Accede a tus EJB3 de Sesión

Quiero explicar cómo acceder de distintas maneras a un sEJB ejecutándose en un servidor de aplicaciones.

Además quiero hablar sobre las interfaces de los sEJB y cierta ventaja de salirse un poco del camino establecido por los tutoriales que se encuentran en la web dada las grandes posibilidades de implementación y configuración de los sEJB y sus interfaces.

¿Interfaces remotas o locales o las dos?

Depende, pero es mejor preguntarse ¿quién debe poder acceder a mi sEJB?

Como regla general, prefiero que cada EJB sea sólo utilizado como remoto o como local, no ambos. y así limitarlos según sea necesario.

La principal diferencia entre una interfaz local y una remota, es la manera en que el servidor de aplicaciones sirve el sEJB. Con las interfaces remotas, los objetos son enviados como valores y con las locales, se envían los objetos como referencias. Para conocer esto, el contenedor depende de la llamada que utilicemos: local o remote

Ahora, podemos definir las dos interfaces que implementen métodos distintos según nuestras necesidades, como evitar que los clientes remotos accedan a ciertos métodos que deseamos utilizar en local.

Un pequeña práctica que me gusta implementar es la de no utilizar la notación @remote o @local en las interfaces. En su lugar, prefiero utilizarlas directamente en el EJB que las implementa. Así podremos tener implementaciones de estas interfaces independientes del EJB. Dado que no podemos tener la certeza de que cualquier servicio proporcionado por estas interfaces vaya a ser un EJB prefiero mantener las interfaces por separado.

Seguimos necesitando indicar en alguna parte que estas interfaces son la local y remota de nuestro sEJB. Para lograr esto utilizamos la misma notación, pero ésta vez en el sEJB directamente:



@Stateless
@Local(MyTest.class)
@Remote(MyTestRemote.class)
public class MyTestBean implements MyTest, MyTestRemote{
//...
}

Ya habiendo definido el sEJB y sus interfaces, vamos a utilizarlas desde un cliente remoto y desde otro EJB incluido dentro del mismo EAR.

Lo más importante, es conocer la URI donde vamos a encontrar al EJB. Dado que lo hemos incluido dentro del EAR MyEA podremos acceder a las dos interfaces con los siguientes nombres:

  • /MyEA/MyTestBean/remote

  • /MyEA/MyTestBean/local



El cliente remoto tendrá que hacer algo como lo siguiente, para poder obtener una instancia del EJB desplegado en un servidor JBoss:



Properties properties = new Properties();
properties.put("java.naming.factory.initial","org.jnp.interfaces.NamingContextFactory");
properties.put("java.naming.factory.url.pkgs","org.jboss.naming:org.jnp.interfaces");
properties.put("java.naming.provider.url","localhost:1099");

Context context = new InitialContext(properties);
MyTestRemote remote = (MyTestRemote)context.lookup("MyEA/MyTestBean/remote");
//...


Para un EJB o POJO que está desplegado junto a MyTestBean en el EAR, debemos hacer algo parecido:



Context context = new InitialContext();
MyTest bean = (MyTest)context.lookup("MyEA/MyTestBean/local");
//...


Como veréis, no hace falta indicar las propiedades del contexto inicial ya que el servidor lo inicializará por nosotros.

Es importante no caer en el error de instanciar directamente un sEJB desde alguna de nuestras clases, ya que las inyección realizadas por el contenedor no se van a realizar. Por ejemplo, las unidades de persistencia no funcionarán y obtendremos un NPE poco explicativo.