Questa è la mia prima domanda in Stack Overflow, quindi mi aspetto che non sia troppo semplice. Ho cercato su Internet una buona soluzione ma ormai non ce l'ho.Un modo semplice per accedere a un ejb remoto situato in un altro server
Sono un grande inizio per EJB, JNDI e Java EE in generale, ma negli ultimi mesi sono stato in grado di fare alcune cose accettabili in questo ambiente. Ora sto concentrando un problema sul lavoro e ormai la soluzione non è buona come vorrei.
Lo scenario è questo: ho un'applicazione EAR in esecuzione in Glassfih 3.1.2. Ho dichiarato EJB all'interno di questa app EAR con bean privi di stato che offrono metodi attraverso un'interfaccia remota.
Questo è il mio Bean remoto in esecuzione in un server denominato server1, ad esempio
package com.booreg;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import com.booreg.IMyRemoteBean;
@Stateless
@LocalBean
public class MyRemoteBean implements IMyRemoteBean
{
@Override
public String helloWorld()
{
return "Hi what's up boy";
}
}
Questa è l'interfaccia per esso
package com.booreg;
import javax.ejb.Remote;
@Remote
public interface IMyRemoteBean
{
public String helloWorld();
}
Poi ho una seconda applicazione EAR che deve eseguire imperativamente su un altro server, chiamato server2. La seconda APP utilizza JSF e Managed Beans. Abbiamo un bean gestito che agisce come un client remoto di MyRemoteBeanRemote, come questo:
package com.nucleus;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import com.booreg.IMyRemoteBean;
@ManagedBean
@ViewScoped
public class MyManagedBean
{
@EJB(name="TheRef") IMyRemoteBean myRemoteBean;
public String getPhrase() { return myRemoteBean.helloWorld(); }
}
Sono arrivato al punto che questo funziona dichiara un file/sun-web.xml ejb-ref all'interno WEB-INF in il mio progetto web.
<ejb-ref>
<ejb-ref-name>TheRef</ejb-ref-name>
<jndi-name>corbaname:iiop:server1:3700#java:global/booreg/booreg.ejb/MyRemoteBean!com.booreg.IMyRemoteBean</jndi-name>
</ejb-ref>
Capisco che con questo file sun-web.xml il jndi nome fa la seconda app per sapere dove trovare l'implementazione EJB situato in un primo momento app. Ma qui ho alcune domande:
- È necessario dichiarare una voce ejb-ref per ciascuna interfaccia EJB che ho nel mio progetto?
- Come evitare di creare un riferimento statico a server/porta (server1: 3700 durante lo sviluppo) all'interno di sun-web.xml? Quando questo andrà in produzione dovrò cambiare manualmente il nome del sever per ognuno ?? Questo suona bizzarro. Posso usare qualche tipo di variabile sul lato server per specificare server/porta?
Mi aspetto che mi sia spiegato abbastanza bene.
Molte grazie
Aggiornamento: finalmente, grazie a questo link vedo che è possibile fare riferimenti al server EJB (server1) creazione di un file jndi.properties all'interno del mio percorso di classe. Questo file dovrebbe contenere righe come questa.
java.naming.factory.initial=com.sun.enterprise.naming.SerialInitContextFactory
java.naming.factory.url.pkgs=com.sun.enterprise.naming
java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl
org.omg.CORBA.ORBInitialHost=server1
org.omg.CORBA.ORBInitialPort=3700
Ma sto ancora affrontando problemi. Quando si distribuisce l'applicazione appare l'eccezione successiva su server1 e non posso distribuire l'applicazione.
ADVERTENCIA: IOP00100006: Class com.sun.jersey.server.impl.cdi.CDIExtension is not Serializable
org.omg.CORBA.BAD_PARAM: ADVERTENCIA: IOP00100006: Class com.sun.jersey.server.impl.cdi.CDIExtension is not Serializable vmcid: SUN minor code: 6 completed: Maybe
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at com.sun.corba.ee.spi.orbutil.logex.corba.CorbaExtension.makeException(CorbaExtension.java:248)
at com.sun.corba.ee.spi.orbutil.logex.corba.CorbaExtension.makeException(CorbaExtension.java:95)
at com.sun.corba.ee.spi.orbutil.logex.WrapperGenerator.handleFullLogging(WrapperGenerator.java:387)
at com.sun.corba.ee.spi.orbutil.logex.WrapperGenerator.access$400(WrapperGenerator.java:107)
at com.sun.corba.ee.spi.orbutil.logex.WrapperGenerator$2.invoke(WrapperGenerator.java:511)
at com.sun.corba.ee.spi.orbutil.proxy.CompositeInvocationHandlerImpl.invoke(CompositeInvocationHandlerImpl.java:99)
at $Proxy117.notSerializable(Unknown Source)
at com.sun.corba.ee.impl.orbutil.ORBUtility.throwNotSerializableForCorba(ORBUtility.java:783)
at com.sun.corba.ee.impl.encoding.CDROutputStream_1_0.write_abstract_interface(CDROutputStream_1_0.java:697)
at com.sun.corba.ee.impl.encoding.CDROutputObject.write_abstract_interface(CDROutputObject.java:545)
at com.sun.corba.ee.impl.javax.rmi.CORBA.Util.writeAbstractObject(Util.java:493)
...
Qualcuno ha qualche idea?
Se si cerca l'ejb remoto tramite jndi in codice, è possibile utilizzare le variabili jvm del server per porta e server. Forse è possibile accedere alle variabili jvm all'interno di sun-web.xml. Non so se è possibile. – djmj
Mi piace mantenere il codice il più semplice e pulito possibile. Per questo motivo non mi piace utilizzare la ricerca all'interno del mio codice in cui @EJB semplifica il lavoro. – dgisbert
Hai considerato di organizzare le due istanze in un cluster? – gcvt