2009-11-17 9 views
14

Estamos proporcionando una jar cliente para que otras aplicaciones internas se conecten a la API REST de nuestra aplicación. Nuestra API depende de algunas bibliotecas estándar de Yakarta. ¿Es una mejor práctica incluir esos archivos JAR dentro de nuestro archivo jar de cliente? ¿O solo documenta las dependencias y depende de los clientes asegurarse de que tengan esas jarras en su classpath?¿Debería proporcionar bibliotecas dependientes en el contenedor de cliente?

Respuesta

12

no agrupe las jarras de terceros en su propio jar como un jarro de uber, pero sería bueno incluir una copia de todos los jar que se requieren en su distribución decir en un directorio lib o qué nunca.

La razón principal de esto es que sus clientes pueden estar utilizando algún tipo de sistema de administración de dependencias (maven/ivy, etc.) y proporcionar paquetes y clases que en realidad no pertenecen a su proyecto invalidará estos esquemas.

Hay una alternativa y es usar algo como maven shade plugin para reubicar sus dependencias en su propio espacio de nombres de paquete. Esto, por supuesto, tiene el inconveniente de que aumentará el tamaño del código de su biblioteca, pero desde el punto de vista lógico casi puede garantizar las versiones de sus dependencias sin afectar a otras bibliotecas que sus clientes puedan estar utilizando.

EDIT: en respuesta a Marcus Leon comentario:

soluciones posible sin la agrupación/reubicación:

  • Documentación, asegúrese de documentar sus dependencias y conflictos conocidos con versiones anteriores - nadie de hecho lo lee
  • Distribuya su biblioteca a través de un sistema gestionado de dependencia ... como un repositorio maven o ivy, estos le permiten documentar en un conjunto muy específico de límites (incluido el superior) cuáles son sus dependencias, aún pueden ser anulado sólo sus clientes sabrán que lo están haciendo
  • Añadir información OSGi en el MANIFIEST.MF - sólo es útil si sus clientes utilizan realmente OSGi
  • Si sus dependencias se han construido utilizando experto o tener información de versión en los archivos no se manifiestan podría escribir algún tipo de rutina de verificación que explore el classpath y compruebe sus versiones: un poco extremo

Al final es extremadamente difícil asegurarse de tener las dependencias que desea, ya que java es un límite tardío idioma es posible hacer que sus dependencias (incluso si están incluidas) sean reemplazadas por alguien que incluya una versión diferente a la suya en el classpath.

Nota: Recientemente he pasado un muy mal día tratando de averiguar por qué una de nuestras aplicaciones no pudo encontrar una nueva versión de log4j. la causa: alguien que trataba de ser útil lo había agrupado en un recipiente aleatorio sin ninguna relación.

+0

Si no agrupa, y su cliente usa una versión diferente de dependiente.jar, ¿cómo se asegura de que client.jar haga referencia a la versión correcta de dependiente.jar? –

+1

ver edición ...la respuesta corta es que no se puede de ninguna manera ... incluso si incluye –

+0

Usted dice que incluso si las dependencias están agrupadas en un jar con class-path establecido en el manifiesto, el compilador no cargará los archivos jar explícitamente mencionados en la entrada del manifiesto de la ruta de clase? –

2

Debe incluir esos archivos jar si está implementando la aplicación como una aplicación independiente. Si está implementando la fuente para que alguien la construya y proporciona un archivo maven pom, entonces no necesariamente lo necesita.

5

Debe incluir todos los frascos de los que dependa. Si permite que un cliente proporcione frascos estándar, confíe en ellos para que le proporcione la versión correcta. Es mucho más sencillo para ambos si incluye las versiones que sabe que su aplicación funciona.

+0

Si incluye la versión n. ° 2 de su jar y el cliente ya tiene la versión n. ° 1 en classpath, ¿cómo hace para que su biblioteca use la versión n. ° 2 (y no v n. ° 1)? –

+2

Puede especificar el classpath para su aplicación en el archivo de manifiesto de su jar de aplicación. (http://java.sun.com/docs/books/tutorial/deployment/jar/downman.html) La definición de CLASSPATH (definida por la variable de entorno) se ve anulada por la "class-path" definida por el manifiesto del jar . –

+0

He leído (http://one-jar.sourceforge.net/) que el "Cargador de clases Java no sabe cómo cargar clases desde un Frasco dentro de un Frasco. Las entradas en el Fase de Clase deben ser referencias a archivos fuera del archivo Jar, derrotando el objetivo de entregar una aplicación en un solo archivo Jar ". –

4

Las ventajas de la agrupación en un solo frasco son obviamente:

  • simplicidad para el cliente

Las desventajas de la agrupación son:

  • incapacidad para actualizar las versiones de la bibliotecas dependientes
  • ocultar bibliotecas necesarias puede conducir a conflictos potenciales en el cliente h esas librerías adicionales
  • complejidad para usted en el proceso de compilación (pero formas de hacerlo bastante fácilmente en Ant/Maven)
  • algunas bibliotecas con manifiestos no pueden ser unjared simplemente y rejared - usted necesita realmente fusionar la información del manifiesto. Sin embargo, Ant y Maven admiten esto.

Otra opción es utilizar un único jar principal (su código) con el atributo del manifiesto de camino de clase establecido para aspirar los otros jar. Personalmente, esto no me gusta, ya que es muy fácil pasar por alto estas dependencias semi ocultas.

Al final, si habla solo de una o dos jarras, las dejaría divididas. Si está hablando de 10 o 15, es posible que desee considerar la agrupación.

0

Expresa su nerviosismo sobre dependencias de versiones de bibliotecas muy específicas (y puedo entender que, dado cuán estrechamente acoplado, por ejemplo, Hibernate se encuentra entre sus diferentes módulos, solo ciertas versiones de Hibernate-anotaciones funcionan con un hibernate-core , que a su vez debe usarse con un hibernate-validador específico).

Si sabe que un paquete necesita funcionar como parte de una plataforma mucho más grande (por ejemplo, como un complemento para un framework que puede estar cargando sus propios jar), realmente necesita la poderosa carga de clases de múltiples versiones de OSGi (también conocido como JSR-291): OSGI Technology

Con una infraestructura de OSGi habilitado, al igual que la primavera, Eclipse, Jonas, o Glassfish, se puede especificar en un archivo XML sus dependencias de la versión específicas, y si dependerá del paquete libfoo-1.1.4, mientras que otro complemento depende de libfoo-2.0a, el administrador de dependencias OSGI se asegurará de que cada uno cargue la versión correcta.

Cuestiones relacionadas