Usando SessionBeans en Grails

Marzo 14th, 2010 por Alejandro Leave a reply »

¿SessionBeans y Grails?

Una de la cualidades de Grails que personalmente más me gusta es su integración con JEE. Desde Grails podemos utilizar tags JSP, Session Beans y EntityBeans como si fueran parte integral del framework.
En este post nos centraremos en como podemos invocar SessionBeans ya sean remotos o locales desde nuestro código Grails. Esta posibilidad junto con el manejo de los EntityBeans le aportan a Grails adaptabilidad y escalabilidad. A que me refiero con esto, a que siendo prolijos podemos desarrollar una aplicación entera en Grails y luego más adelante pasar los modelos y los servicios a Entities y SessionBeans respectivamente. De esta forma podemos comenzar rápidamente a desarrollar nuestra aplicación haciendo uso de las ventajas de estar en un ambiente dinámico y luego cuando la aplicación está más definida y los cambios no son lo común entonces podemos pasar la capa de negocios a JEE. Este cambio no afecta a ningún otro componente de Grails como ser controladores o vistas.
Para lograr esto último todo lo que debemos hacer es sustituir el código de las operaciones de los servicios por delegación a la misma operación en los SessionBeans creados.

A continuación veremos como se configura Grails para utilizar SessionBeans tanto para EJB3.0 como EJB2.1

Inyectando los SessionBeans
Grails permite inyectar tanto en los servicios como en los controladores cualquier SB al igual que lo hace con sus servicios. Al Grails utilizar Spring en el manejo de sus componentes es posible utilizar todas las ventajas de este dentro de Grails. La forma más sencilla de configurar los objetos a ser inyectados dentro de los controladores o servicios, y en especial los SB, es utilizando el archivo resources.groovy. Este archivo es equivalente a el archivo applicationContext.xml de Spring solo que en vez de ser un archivo XML es una clase groovy que utiliza el SpringBuilder como DSL para la configuración. Por defecto el archivo resources que se encuentra en grails-app/conf/spring y tiene el siguiente contenido:

// Place your Spring DSL code here
beans = {

}

Dentro del closure es donde se deben agregar las definiciones de los beans.

Configuración de servidor JNDI
Para poder acceder a cualquier componente que se encuentra en un servidor de aplicaciones debemos hacerlo utilizando JNDI. Para esto Spring provee una clase utilitaria la cual facilita las operaciones sobre un servidor de nombres JNDI como ser lookup y a su vez actúa como un proveedor de contexto JNDI. Para esto hay que agregar la siguiente definición en el resources.groovy

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

Donde:

  • ejbJndi
Es el nombre del bean el cual es de tipo org.springframework.jndi.JndiTemplate. Este nombre puede ser cualquiera. Es a este nombre que se hará referencia para determinar el servidor de nombres que provee el acceso a un objeto.
  • environment
Es la propiedad de JndiTempalte la cual se configura con un Mapa que tiene las propiedades JNDI

En un archivo podrían existir tantas definiciones de JndiTemplate como proveedores JNDI se necesiten acceder.

Configuración de servidor JNDI por ENVIRONMENT
Es muy probable y necesario, que el servidor JNDI requiera diferente configuración de IP y puerto según sea el ambiente desarrollo, producción o testing. Para lograr esto se debe anexar a la configuración anterior lo siguiente:

  • Colocar el valor de la IP y puerto del JBoss en cada environment del Config.groovy.
  • Importar la clase ConfigurationHolder en el archivo resources.groovy
  • Sustituir la ip y puerto de la variable "java.naming.provider.url" por las cargadas en la configuración.

Ejemplo
Config.groovy

  ...
  environments {
    development {
        ...
        jboss.ip = "10.200.8.173"
        jboss.port = "1099"
        ...
    }
    production {
        ...
        jboss.ip = "172.16.2.105"
        jboss.port = "1099"
        ...
    }

Resources.groovy

     import org.codehaus.groovy.grails.commons.*
     ...
	ejbJndi(org.springframework.jndi.JndiTemplate){
		environment = [
			"java.naming.factory.initial" : "org.jnp.interfaces.NamingContextFactory",
			"java.naming.provider.url" : "jnp://"+ConfigurationHolder.config.jboss.ip+":"+ConfigurationHolder.config.jboss.port]
	}

Configuración de componentes EJB 3.0
Para poder inyectar componentes EJB 3.0 tenemos que agregar la siguiente configuración:

	xXXServices(org.springframework.jndi.JndiObjectFactoryBean){
		jndiName = "XXXServices/remote"
		jndiTemplate = ref("ejbJndi")
	}

Donde:

  • xXXServices
Es el nombre que se le dará a la referencia remota al SB y que será utilizado para inyectar esta en los controladores y servicios. Cualquier controlador o servicio que tenga una propiedad con nombre xXXServices se le inyectara la referencia al SB remoto definido por ese nombre en el archivo resources.groovy. La primer x es en minúscula para indicar que por convención el nombre debe comenzar en minúscula.
  • jndiName
Nombre por el cual se va a buscar la referencia al SB en el servidor JNDI
  • jndiTemplate
Nombre del bean que se va a utilizar como provider para acceder al objeto JNDI. Es el definido en el punto anterior.

Para utilizar el SB en un servicio sería:

public class EjemploServices {
	def xXXServices

	void unMetodo(param1, param2) {
		xXXServices.invocoMetodoEnEJB(param1, param 2)
	}
}

Configuración de componentes EJB 2.1
Para poder inyectar componentes EJB 2.1 tenemos que agregar la siguiente configuración que es similar a la vista para EJB 3.0.

 xXXServices(org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean) {
		jndiName = "EJBXXXServices"
		businessInterface = "biz.aquait.yyy.ejb.EJBXXXServices"
		jndiTemplate = ref("ejbJndi")
		refreshHomeOnConnectFailure = true
                lookupHomeOnStartup=false

	}

Donde:

  • xXXServices
Es el nombre que se le dará a la referencia remota al SB y que será utilizado para inyectar esta en los controladores y servicios. Cualquier controlador o servicio que tenga una propiedad con nombre xXXServices a esta se le inyectara la referencia al SB remoto definido por ese nombre en el archivo resources.groovy. La primer x es en minúscula para indicar que por convención el nombre debe comenzar en minúscula.
  • jndiName
Nombre por el cual se va a buscar la referencia al SB en el servidor JNDI
  • refreshHomeOnConnectFailure
Refresca la home cuando detecta un fallo en la conexión, por ejemplo cuando se reinicia el servidor
  • lookupHomeOnStartup
Hace que la aplicación no haga el lookup a levantar sino al utilizar servicios del SB.
  • jndiTemplate
Nombre del bean que se va a utilizar como provider para acceder al objeto JNDI. Es el definido en el primer punto.
  • businessInterface
La interfaz remota del SB, es decir la que extiende EJBObject.

La forma de utilizar el SB dentro de un servicio u otro componente es la misma forma que las referencias a SB implementados  con EJB 3.0.

Conclusión

Siguiendo los pasos presentados arriba podemos decir que configurar Grails para utilizar  SB no es engorroso y que el uso de estos dentro del framework es transparente ya que se usan de la misma forma que un servicio de Grails.

  • Blogger Post
  • Digg
  • Reddit
  • Google Reader
  • Share/Bookmark
Advertisement

2 comments

  1. josem dice:

    Un proyecto con SessionBeans podría ser desplegado en un contenedor web como tomcat? o sería necesario usar un servidor de aplicaciones como GlassFish? :)

    Buen post

  2. Alejandro dice:

    Los SB ya sean statefull o stateless necesitan de un contenedor de EJB y por eso necesitan ejecutarse dentro de un servidor de aplicaciones como ser GlassFish o Jboss. Por su lado Tomcat es solo un servidor web y como tal tiene un contenedor web en el cual podes deployar componentes web como ser páginas JSP, JSF y Servlets.
    Si por algún motivo no quieres tener ejecutando tu aplicación Grails en un Servidor de Aplicaciones podrías tener una arquitectura distribuida. En esta tendrías un Tomcat con la Aplicación Web la cual utiliza en forma remota los SB que están en un Servidor de Aplicaciones instalado en otra máquina.

Deja un comentario

Spam protection by WP Captcha-Free