ßeta perpetua

El blog personal de Juan Manuel Barroso

Conectando Grails y EJB3

No Comments »

Me he encontrado con la necesidad de construir una aplicación web sobre un servicio EJB3 que implementa el acceso a datos y gran parte de la lógica de negocio, y como era de esperar, Grails me ha facilitado enormemente el mecanismo para la integración.

La idea es que la aplicación Grails (1.3.6) pueda desplegarse en un servidor diferente a donde se encuentra el EJB3, para esto usaremos  JNDI y la interfaz remota del servicio.

Lo primero que debemos hacer es añadir los beans correspondientes al fichero conf/spring/resources.groovy:

ejbJndi(org.springframework.jndi.JndiTemplate) {
   environment = [
      "java.naming.factory.initial" : "org.jnp.interfaces.NamingContextFactory",
      "java.naming.provider.url" : "jnp://servidorEJb3.net:1099"
   ]
}

Lo que hemos hecho es construir un bean, con nombre ejbJndi, a partir  de la clase org.springframework.jndi.JndiTemplate. Le damos valor a la variable environment especificando las propiedades que Spring usará para encontrar nuestro EJB3.

Luego procedemos a declarar nuestro bean remoto añadiendo al fichero anterior una nueva entrada:

beanServicioRemoto(org.springframework.jndi.JndiObjectFactoryBean) {
    jndiName = "aplicacion/ejbName/remote"
    jndiTemplate = ref("ejbJndi")
}

Hemos llamado a nuestro bean beanServicioRemoto, y lo hemos inicializado con el nombre del EJB (especificando la interfaz remota)  y la referencia a nuestro template  ejbJndi.

El beanServicioRemoto puede ser usado desde los controladores o servicios como un servicio más:

def beanServicioRemoto

Pero antes de poder usarlo debemos añadir algunas librerías al directorio lib de nuestra aplicación:

La primera a añadir deberá ser la que contenga la interfaz del EJB3 remoto y todos las clases que se usen en dicha interfaz. Dicha librería puede obtenerse empaquetando en un JAR las clases del EJB3

Adicionalmente, es muy probable que se necesiten añadir librerías clientes del servidor donde se encuentre desplegado el EJB3. Para JBOSS 4.2.3 se han añadido las siguientes librerías:

jbossall-client.jar
jboss-aop-jdk50-client.jar
jboss-aspect-jdk50-client.jar
jboss-common-client.jar
jboss-ejb3-client.jar
jboss-j2ee.jar
jnp-client.jar

Si la aplicación levanta, enhorabuena, en caso contrario es muy probable que aparezca el demonio de los conflictos de librerías y tengas que pelearte con él. En mi caso me apareció el siguiente error:

Server failed to start: java.lang.LinkageError:
   Class javax/management/MBeanServer violates loader constraints

Problema que solucione cambiando el servidor de aplicaciones embebido a jetty. Este cambio me lo pude permitir porque el contenedor destino de la aplicación  era JBOSS, y en tiempo de desarrollo me daba igual tomcat que jetty.

Para desinstalar tomcat e instalar jetty:

grails uninstall-plugin tomcat
grails install-plugin jetty

Si en lugar de EJB3 tenemos EJB2 se deberán cambiar las clases de Spring que se usan en el resources.groovy. Puede consultarse aquí dicho escenario.