[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Gestión de dependencias



-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hola,

Desarrollando uno de los proyectos (en adelante, "herramienta" [1]) que he 
comentado anteriormente en Mindfood, me ha surgido un problema sobre el cual 
agradecería sugerencias.

El problema reside principalmente en la gestión de las dependencias.
Básicamente, el propósito del proyecto podría describirse como "envolver" una 
aplicación web dada, con el fin de proporcionar funcionalidades adicionales 
sin afectar a la aplicación original.

En el momento del empaquetado, las librerías proporcionadas por la aplicación 
original se "mezclan" con las requeridas por la herramienta, utilizando un 
mecanismo básico de nomenclatura de ficheros, para evitar la duplicidad en el 
caso de que alguna de las dependencias fuera requerida por ambas partes.
Para cada dependencia en concreto esta solución podría ser suficiente, aun en 
el caso de necesitar un mayor grado de sofisticación en lo referente al 
mecanismo de resolución de versiones (podría mejorarse tratando de inferir 
versiones a partir de metadatos, bien inspeccionando el manifest, o en último 
caso utilizando un catálogo tipo repositorio Maven [2]).
Sin embargo, existe un momento en el que no se puede obviar que el conjunto de 
las dependencias tiene estructura, y que dicha estructura lleva asociada unas 
condiciones de contorno en forma de contratos entre dependencias. Es un 
problema común presente en sistemas operativos con enlazado dinámico, y que 
puede llevar a incompatibilidades no resolubles (librería A depende de B, 
versión 0.54, y no es compatible con versiones posteriores, mientras que al 
mismo tiempo otra librería C necesita una versión de B superior a la 0.55).
En este sentido, pretendo que la solución a esa problemática quede excluída 
del alcance proyecto, y que, en caso de que se incurra en algún conflicto, el 
propio desarrollador, al tener acceso al código fuente, pueda aplicar una 
solución específica. La solución, similar a lo que proponía Delphi hace unos 
años, de unir en una única entidad la propia aplicación y sus dependencias, 
no es viable en este caso (ni la especificación de JVM ofrece demasiadas 
capacidades en este sentido), ya que no es posible incluir ficheros war 
dentro de otros ficheros war. La única solución aparentemente sería incluir 
todas las dependencias, evitando colisiones a nivel de nombre de fichero, y 
personalizar el classloader para conseguir evitar las incompatibilidades.

En tiempo de ejecución se da asimismo un problema en este sentido, relacionado 
con los recursos que las aplicaciones comparten por el hecho de ser 
ejecutadas en la misma máquina virtual, por un lado, y en el mismo "contexto" 
del contenedor de servlets, por otro.
Los singletons [3] en cualquiera de sus variantes son explícitamente únicos 
por instancia de máquina virtual. Es decir, no existe un mecanismo simple 
para que una dependencia acceda a la instancia de un singleton, la cual a su 
vez sea distinta a la que es accesible desde otra dependencia. En otras 
palabras, no veo posible (o al menos fácil) el modificar el ámbito de 
unicidad de las constantes (static final) en función de qué las use.

Los problemas en este sentido ocurren incluso dejando a un lado las relaciones 
entre dependencias. En concreto, la herramienta utiliza Struts [4]. Struts 
utiliza recursos ofrecidos por el contenedor de servlets como las instancias 
de "request", "session" y "context", referenciando desde ellas información 
como el idoma preferido por el usuario, variables necesarias para el correcto 
funcionamiento de Struts, etc. En el caso de que la aplicación también 
utilizara Struts hace que se den conflictos entre ambas. Struts, en este 
sentido, ofrece un mecanismo de modularización por url, de forma que la 
propia librería permite independizar unos módulos de otros.

Supongo que ese mecanismo es el que mejor parece adaptarse a este caso, 
teniendo en cuenta su aparente simplicidad. La "resolución" de este tipo de 
conflictos, en el caso de esta herramienta, se centra en evitar la 
confluencia de nombres. Así, los estilos, los jsp, las imágenes, y ahora las 
urls (lo cual es un inconveniente a priori por la no compatibilidad de los 
bookmarks), se nombran utilizando un criterio subjetivo de "improbabilidad de 
colisión", hasta que un análisis posterior ofrezca una solución mejor.

Este tema sirve para introducir la idea de la necesidad de una herramienta de 
gestión de aplicaciones en ejecución. Una especie de Maven en runtime, que 
garantice un entorno de equilibrio estable para las aplicaciones (es decir, 
que sea capaz de volver a una versión anterior en el caso de que se detecte 
un error).

Como suele pasar, el mero hecho de escribir y plasmar en palabras el problema 
sirve para entenderlo mejor y deducir posibles alternativas.

Un saludo,
Jose.

[1] <http://www.orange-soft.com/mindfood/archive/msg00205.html>
[2] <http://maven.apache.org/>
[3] <http://c2.com/cgi/wiki?SingletonPattern>
[4] <http://jakarta.apache.org/struts/>
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)

iD8DBQFAqzdsCAvt6RF8M0cRAt6JAJ9+DceOK/bMC2700Ajw3mS0grS8IQCdGSqd
n5Y4hTJAIGtaV2P8KUgrtwo=
=2L1t
-----END PGP SIGNATURE-----