“A programmer is a person who passes as an exacting expert on the basis of being able to turn out, after innumerable punching, an infinite series of incomprehensive answers calculated with micrometric precisions from vague assumptions based on debatable figures taken from inconclusive documents and carried out on instruments of problematical accuracy by persons of dubious reliability and questionable mentality for the avowed purpose of annoying and confounding a hopelessly defenseless department that was unfortunate enough to ask for the information in the first place.”
(IEEE Grid newsmagazine)
En esta segunda parte de esta serie (podéis ver la primera parte aquí) comentaré mi experiencia con el famoso nuevo sistema estandarizado o único de nombres JNDI (portable JNDI names).
Tras varias aplicaciones, he llegado a una nomenclatura que me ha parecido adecuada para el nombrado de mis objetos y recursos siguiendo mi propio estándar.:
A continuación muestro ejemplos de cómo cambia la declaración de elementos con EJB 3 (JEE5) a EJB 3.1 (JEE6).
- Declaración de EJB: defino un nombre de aplicación y declaro todos los ejb con la nomenclatura general "global" usando dicho nombre: @EJB(name="java:global/nombre_aplicacion/nombre_ejb", beanInterface=nombre_ejb_interfaz_local.class)
- Acceso a referencias de EJB locales: la declaración la hago usando siempre:
- Acceso a referencias locales de EJB desde otros módulos: usando la nomenclatura
- Acceso a recursos: igual que antes, pero usando "lookup" en lugar de "mappedName" en la notación @Resource
@EJB(name="java:module/nombre_ejb")
java:global/nombre_ejb
A continuación muestro ejemplos de cómo cambia la declaración de elementos con EJB 3 (JEE5) a EJB 3.1 (JEE6).
con EJB 3 (JEE5) | con EJB 3.1 (JEE6) | |
---|---|---|
Declaración | @Stateless(name="BalteusService", mappedName="ejb/BalteusService") public class BalteusService; |
@Stateless() @EJB(name="java:global/BalteusApp/BalteusService", beanInterface=BalteusServiceLocal.class) |
EJB Ref | @EJB private OtherServiceLocal otherService |
@EJB(name="java:module/OtherService") private OtherServiceLocal otherService |
Resource Ref | @Resource(mappedName="jdbc/BalteusDS") private DataSource BalteusDS; |
@Resource(lookup="jdbc/BalteusDS") private DataSource BalteusDS; |
Para la utilización de interfacez locales de EJB desde otros módulos de un EAR (por ejemplo, desde una aplicación web), donde antes usaba el típico patrón ServiceLocator, ahora uso una adaptación del patron BeanLocator (que es una especie de ServiceLocator 2.0), descrito por Adam Bien en su libro (http://www.adam-bien.com/roller/abien/entry/ejb_3_1_beanlocator_when).
La forma de utilizar el patrón
La forma de utilizar el patrón
/** public class BeanLocator { * Para realizar el lookup de interfaces locales * * Asume que los servicios están declarados como "java:global/XXXService" * (p.e. @EJB(name="java:global/UserService",beanInterface=UserServiceLocal.class) ), es decir, * asume que el nombre JNDI declarado es el nombre de la interfaz eliminando el sufijo "Local" * @param clazz * @return */ public static <T> T lookup(Class<T> clazz) { String name = clazz.getSimpleName(); return lookup(clazz,"java:global/cestelJEEApp/" + name.substring(0, name.indexOf("Local"))); } }
Con este BeanLocator, obtener una referencia a la interfaz local, es algo muy sencillo. Por ejemplo:
PaisServiceLocal paisService = BeanLocator.lookup(PaisServiceLocal.class);
Referencias y más información: