OSGi y los TransactionManager malditos
Puede ser que estes comenzando tu andadura en el uso de módulos OSGi, y tal vez puede ser que trabajes en un proyecto muy grande, o no tanto :-), en el que se utilice un ESB, como por ejemplo FuseESB. Si estas en esta situación es muy normal que tengas que conectarte a múltiples bases de datos y diferentes sistemas. Algo de lo que tal vez no te has percatado todavía es que el look-up por defecto de los servicios OSGi puede jugarte una mala pasada.
Nota: Este artículo presupone que tienes conocimientos previos de OSGi y Spring Dynamic Modules.
Imaginemos que existen dos bundles que corresponden a repositorios, que pueden no ser más que conectores con diferentes bases de datos. En este ejemplo FooRepository y BarRepository. Imaginemos también que tenemos otro bundle FooServices que tiene como dependencia FooRepository, pero los servicios OSGi exportados usando SpringDM se definen de la siguiente manera.
¿Le ves algún problema?, ¿no?. Tranquilo según el manual esta es la manera de declarar los servicios y referenciarlos, pero sí que existe un problema, hay que leer el manual un poco más en detalle. En este caso en concreto no sabes si el TransactionManager que se va a utilizar en FooServices es fooTransactionManager o barTransactionManager, pero lo correcto sería que siempre fuese fooTransactionManager, con su correspondiente DataSource. Esto se debe a que si solo incluyes las propiedades id e interface en la referencia a un servicio (osgi:reference) el look-up se hace tan solo a nivel de la interfaz, por lo que cualquiera de los dos TransactionManager lo cumplen. Lo peor de este caso es que es un error muy difícil de encontrar, porque la aplicación puede funcionar perfectamente, sobretodo cuando se trata de un conjunto de servicios de lectura, y empezar a fallar pasados unos días con unos errores muy poco coherentes.
¿Y entonces que hago?, pues muy sencillo, especificar la propiedad bean-name cuando se crea una referencia a un servicio OSGi. Ver línea 21 del siguiente gist.
Espero que esto te sirva de algo y te ayude si te encuentras con un problema similar :-)
Nota: Este artículo presupone que tienes conocimientos previos de OSGi y Spring Dynamic Modules.
Imaginemos que existen dos bundles que corresponden a repositorios, que pueden no ser más que conectores con diferentes bases de datos. En este ejemplo FooRepository y BarRepository. Imaginemos también que tenemos otro bundle FooServices que tiene como dependencia FooRepository, pero los servicios OSGi exportados usando SpringDM se definen de la siguiente manera.
¿Le ves algún problema?, ¿no?. Tranquilo según el manual esta es la manera de declarar los servicios y referenciarlos, pero sí que existe un problema, hay que leer el manual un poco más en detalle. En este caso en concreto no sabes si el TransactionManager que se va a utilizar en FooServices es fooTransactionManager o barTransactionManager, pero lo correcto sería que siempre fuese fooTransactionManager, con su correspondiente DataSource. Esto se debe a que si solo incluyes las propiedades id e interface en la referencia a un servicio (osgi:reference) el look-up se hace tan solo a nivel de la interfaz, por lo que cualquiera de los dos TransactionManager lo cumplen. Lo peor de este caso es que es un error muy difícil de encontrar, porque la aplicación puede funcionar perfectamente, sobretodo cuando se trata de un conjunto de servicios de lectura, y empezar a fallar pasados unos días con unos errores muy poco coherentes.
¿Y entonces que hago?, pues muy sencillo, especificar la propiedad bean-name cuando se crea una referencia a un servicio OSGi. Ver línea 21 del siguiente gist.
Espero que esto te sirva de algo y te ayude si te encuentras con un problema similar :-)
Comentarios