Cliente remoto de EJB 3.1 (en GlassFish V3)
Leyendo el FAQ de EJB (https://glassfish.dev.java.net/javaee5/ejb/EJB_FAQ.html) quiero comentar cómo crear un cliente EJB sin necesidad de desplegarlo en el mismo en servidor. Realmente es muy simple:
Aquí la interfaz:
y aquí la implementación:
Notar la línea del
¿Y si el cliente está en otro computador?
No os preocupéis, que para todos hay.
¿Y si configuré mi GlassFish para que usara otro puerto para EJB?
Usar la propiedad
Por omisión es el 3700.
1. Crear el Módulo EJB.
Creo que esta opción es demasiada fácil. En resumen, he creado un módulo llamadoCalculadoraEJBModule
. Este nombre es importante que lo utilizaremos al final en el cliente. Este módulo tiene la interfaz remota del ejb ejb.CalculadoraBeanRemote
y su implementación ejb.CalculadoraBean
Aquí la interfaz:
package ejb;
import javax.ejb.Remote;
@Remote
public interface CalculadoraBeanRemote {
long factorial(long num);
}
y aquí la implementación:
package ejb;
import javax.ejb.Stateless;
@Stateless
public class CalculadoraBean implements CalculadoraBeanRemote {
@Override
public long factorial(long num) {
if (num < 1) {
return 1L;
}
return factorial(num - 1) * num;
}
}
2. Desplegar el módulo
Nada más que hacer "deploy" al módulo desde el NetBeans, y listo, ya está publicado en nuestro servidor (por ahora en el local)3. Hacer una aplicación Java común
Notar que no estoy mencionando hacer una cliente EJB de Java. No. En este caso haremos una aplicación común Java, como si fuera un Swing, o de consola. Nada más. Para nuestro ejemplo lo llamaremosCalculadoraCliente
. Y la clase Main
tendrá el siguiente código:package calculadoracliente;
import ejb.CalculadoraBeanRemote;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class Main {
static final Logger LOGGER = Logger.getLogger(Main.class.getName());
public static void main(String[] args) {
try {
CalculadoraBeanRemote remote = (CalculadoraBeanRemote) new InitialContext()
.lookup("java:global/CalculadoraEJBModule/CalculadoraBean");
long base = 10L;
long num = remote.factorial(base);
LOGGER.log(Level.INFO, "factorial de {0}={1}", new Object[]{base, num});
} catch (NamingException ex) {
LOGGER.log(Level.SEVERE, null, ex);
}
}
}
Notar la línea del
InitialContext().lookup()
, específicamente en su parámetro donde se le indica el nombre del EJB en el servidor. Para resumir la explicación, está compuesta por tres partes:java:global
: Es utilizado a partir de la especificación EJB 3.1, donde ya todos los EJB tendrán un mismo nombre JNDI. Antes cada proveedor de EJB daban por su lado y provocaba confusiones y nada de portabilidad entre proveedoresCalculadoraEJBModule
: Es el nombre del módulo. Como en este caso es un módulo autónomo (no es parte de un Enterprise Application .EAR) se pone su nombre. Pero si fuera parte de un EAR, entonces debería anteponerse el nombre del EAR (sin la extensión .ear)CalculadoraBean
: Esto es fácil. Sí, es el nombre del Bean, descrito con @Stateless/@Stateful/@Singleton
4. Agregar el .jar de GlassFish en el cliente
Este paso es necesario para poder utilizar toda la batería de GlassFish en el cliente. Debería agregarse unicamente el archivogf-client.jar
que se encuentra en el directorio $GLASSFISH_HOME/modules/
. 5. Ejecutar el cliente
Y voilá!... la aplicación funcionando.¿Y si el cliente está en otro computador?
No os preocupéis, que para todos hay.
4a. Configurar un parámetro de ejecución en el cliente indicando la ubicación del servidor
Por omisión el parámetro es "localhost". Pero ¿cuál es el parámetro? Es una propiedad de ejecución llamadoorg.omg.CORBA.ORBInitialHost
Es necesario agregar esto en las propiedades del proyecto cliente.-Dorg.omg.CORBA.ORBInitialHost=SERVIDOR_EJB
¿Y si configuré mi GlassFish para que usara otro puerto para EJB?
Usar la propiedad
org.omg.CORBA.ORBInitialPort
en el cliente.Por omisión es el 3700.
Código fuente
Los proyectos usados para este ejemplo están aquí:- CalculadoraEJBModule.tar.gz El módulo EJB
- CalculadoraCliente.tar.gz: El cliente
Muy burn tutorial, gracias por la info, quisiera saber como podria hacer lo mismo pero en vez del cliente realizarlo en un pagina jsp, o mejor aun conectar el EJBmodule con un proyecto web en JSF, chau.
ResponderBorrarEn el post "¿Para qué los EJB?" (http://www.apuntesdejava.com/2008/08/para-que-los-ejb.html) se explica cómo usar.
ResponderBorrarTambién hay un vídeo de cómo hacer una aplicación con JSF 2.0/EJB3.1 en NetBeans 6.8
http://www.apuntesdejava.com/2009/12/netbeans-68-jsf-20-ejb-31-javaee-6.html
Me pasa algo curioso con el ejemplo, si selecciono el archivo gf-client.jar desde la carpeta donde esta instalado el glassfish funciona bien, pero si lo copio a otra carpeta y lo selecciono desde otra carpeta me sale este error,
ResponderBorrarNeed to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
Inclusive copie todo el contenido de la carpeta modules y lo mismo
Depronto te a pasado y sabes a que se deba esto?
Cuando lo agregas por las propiedades del proyecto, lo que hace es agregarlo al "path" de la aplicación. Cuando haces "Build", copiará el .jar en la subcarpeta "lib" de la carpeta "dist" para que sea utilizado por la aplicación. Cuando distribuyas la aplicación, debes llevar todo el contenido de la carpeta "dist", solo así funcionará.
ResponderBorrar¿Y que pasa si cambia la implementación del EJB en el servidor? Estamos importando todo el proyecto EJB. ¿Hemos de copiar la libreria en todas las carpetas lib de todas nuestras aplicaciones cliente? ¿Hay otra forma más ágil, como los stubs i demás de WebServices que Netbeans crea automáticamente?
ResponderBorrarHola, que buena guia, me funciona todo menos cuando pongo el cliente en otro computador... añadi estas lineas pero sigue sin conectar... que pasara??
ResponderBorrarprops.setProperty("java.naming.factory.initial", "com.sun.enterprise.naming.SerialInitContextFactory"); props.setProperty("java.naming.factory.url.pkgs", "com.sun.enterprise.naming"); props.setProperty("java.naming.factory.state", "com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl"); props.setProperty("org.omg.CORBA.ORBInitialHost", "192.168.1.2"); props.setProperty("org.omg.CORBA.ORBInitialPort", "3700");
InitialContext ic = new InitialContext(props);
CalculadoraBeanRemote remote = (CalculadoraBeanRemote) ic .lookup("java:global/CalculadoraEJBModule/CalculadoraBean");
Hola Javier,
ResponderBorrarque raro !
pero has intentado la parte de agregar las propiedades en la misma aplicación? O sea, en la línea de comandos (o como está en la parte 4.a) colocando -Dorg.omg.CORBA.ORBInitialHost=192.168.1.2
Algo así sería si se llama desde la línea de comandos:
java -Dorg.omg.CORBA.ORBInitialHost=192.168.1.2 -jar ......
le agregue la linea de comando, sin embargo sigue molestando, estuve ojeando la pagina http://www.java.net/forum/topic/glassfish/glassfish/ejb-client-runs-netbeans-not-outside-0
ResponderBorrary no me dieron muchas esperanzas de que funcionara el programa, he desactivado firewalls, actualizado glassfish, monte el proyecto en eclipse y el error es siempre este:
javax.naming.NoInitialContextException: Cannot instantiate class...
Muchisimas gracias... Lo habia estado buscando, publica mas cosas asi. Que si sirvem
ResponderBorrarSe agradece por compartir el conocimiento y la inform y aquí dejo un enlace donde hay un tutorial de un resumen de toda la tecnología java y sus ventajas con ejemplos desarrollados usando el IDE NetBeans ->http://netbeans.org/kb/docs/javaee/ecommerce/netbeans-ecommerce-tutorial.html
ResponderBorrarGracias Anónimo.
ResponderBorrarEn la misma página de NetBeans hay bastante documentación interesante, además de su Wiki http://wiki.netbeans.org/CommunityDocs_Contributions
Exelente ejemplo, me corrio todo, pero un problema cuando trate de correrlo con java web start, saben como hacerlo...sos
ResponderBorrargracias aJuerzg
ResponderBorrarPara que se ejecute en JWS, se deberán agregar las bibliotecas del GlassFish... pero ten cuidado porque cuando el cliente quiera acceder desde la web, tendrá que bajar toda esa biblioteca, y puede tomar varios minutos, dependiendo de la velocidad de la red.
Hola a todos, sigui los pasos y me corrioen forma local con el netbeans y glassfish el problema es q cuando lo compilo a jar y lo ejecuto java -jar xx.jar me sale el siguiente error
ResponderBorrarjavax.naming.NoInitialContextException: Cannot instantiate class: com.sun.enterprise.naming.SerialInitContextFactory [Root exception is java.lang.ClassNotFoundException: com.sun.enterprise.naming.SerialInitContextFactory]
alguien sabe por q no corre con el jar, estoy q me rompo la cabeza y nada
bueno segui los pasos con netbeands 7 y glassfish 3.1 y jdk 1.6 y al ejecutar en el netbeands corria pero cuando lo compilaba me salia error, esto era por agregar las librerias gf-client.jar para solucionar copie los siguientes *.jar de glassfish
ResponderBorrarauto-depends.jar
bean-validator.jar
common-util.jar
config.jar
config-api.jar
config-types.jar
connectors-internal-api.jar
container-common.jar
deployment-common.jar
dol.jar
ejb.security.jar
ejb-container.jar
gf-client.jar
gf-client-module.jar
glassfish-api.jar
glassfish-corba-asm.jar
glassfish-corba-codegen.jar
glassfish-corba-csiv2-idl.jar
glassfish-corba-newtimer.jar
glassfish-corba-omgapi.jar
glassfish-corba-orb.jar
glassfish-corba-orbgeneric.jar
glassfish-naming.jar
gmbal.jar
hk2-core.jar
internal-api.jar
javax.ejb.jar
javax.jms.jar
javax.resource.jar
javax.servlet.jar
javax.transaction.jar
jta.jar
kernel.jar
management-api.jar
orb-connector.jar
orb-enabler.jar
orb-iiop.jar
security.jar
tiger-types-osgi.jar
transaction-internal-api.jar
pero aun no logro correr remotamente, por alguna razon el programa inicia pero al tratar de crear el objeto se keda buscando el servidor o el puerto, ya me fije y el puerto es el correcto, incluso lo cambie para probar y nada, se queda en esta linea
CalculadoraBeanRemote remote = (CalculadoraBeanRemote) ic .lookup("java:global/CalculadoraEJBModule/CalculadoraBean");
si alguien tiene algubna idea por q no puedo onectar remotamente se lo agradeceria mucho
Hola como puede acceder a mi aplicacion JSF desde otra maquina que este en la misma red....la aplicacion la hice en netbeas....mi idea es algo asi http://direcciondemimaquina:8080/miaplicacion
ResponderBorrarHola Cruzetas
Borrarhas revisado que esté habilitado el puerto 8080 en el firewall de la maquina que tienes el JSF?
saludos
Hola,he seguido las instrucciones paso a paso pero en el punto donde "es necesario agregar un .jar que contenga la interfaz del EJB a este proyecto" lo agrego y me sale el siguiente error "no es posible añadir la referencia a si mismo",¿como puedo resolver este problema?"
ResponderBorrarhola amigos alguien me podría ayudar e seguido los pasos del tutorial y todo bien el problema viene que no esta el jar gf-client en la catpeta modules,no se porque no aparece en la instalacion del glassfish 3.1.2 y trabajo con netbaens 6.9 alguna solucion sera bienvenida.
ResponderBorrar