2010-03-13 12 views
7

que tienen un programa que necesita varias bibliotecas de terceros, y en el momento en que se envasa este modo:¿Cuál es la mejor práctica para incluir archivos jar de terceros en un programa Java?

 
zerobot.jar (my file) 
libs/pircbot.jar 
libs/mysql-connector-java-5.1.10-bin.jar 
libs/c3p0-0.9.1.2.jar 

Por lo que yo sé la "mejor" manera de manejar librerías de terceros es poner ellos en el classpath en el manifiesto de mi archivo jar, que funcionará multiplataforma, no ralentizará el lanzamiento (lo que puede combinarlos) y no se topa con problemas legales (lo que podría hacer el reempaquetado).

El problema es para los usuarios que suministran las bibliotecas de terceros ellos mismos (por ejemplo, caso de uso, actualizándolos para corregir un error). Dos de las bibliotecas tienen el número de versión en el archivo, lo que agrega problemas.

Mi solución actual es que mi programa tiene un proceso de arranque que crea un nuevo cargador de clases y ejemplifica el programa adecuado al usarlo. Este cargador de clases personalizado agrega todos los archivos .jar en lib/a su classpath.

Mi forma actual funciona bien, pero ahora tengo dos cargadores de clases personalizados en mi aplicación y un cambio reciente en el código ha causado problemas que son difíciles de depurar, por lo que si hay una manera mejor me gustaría eliminar esto complejidad. También parece una sobreingeniería para lo que estoy seguro es una situación muy común.

Entonces mi pregunta es, ¿cómo debería estar haciendo esto?

+0

@ZoFrex: ¿por qué usar un nuevo cargador de clases? ¿Por qué no simplemente usar el cargador de clases predeterminado que siempre es un URLClassLoader (AFAIK)? De esa forma solo tendrías un cargador de clases. Así es como lo estoy haciendo y estoy enviando cientos de máquinas con sistema operativo X y Windows (si no toca el ventilador, cambiaría la forma en que lo estoy haciendo;) – SyntaxT3rr0r

+0

Uso realmente un URLClassLoader . Creé uno nuevo para inyectar el classpath dinámico, no puedes alterar el classpath predeterminado. El segundo cargador de clases que escribí anteriormente, para el sistema de complementos. – ZoFreX

Respuesta

5

Proporcionamos archivos de script con el contenedor. P.ej. some.bat, some.sh etc.

Y a partir de Java6, puede usar comodines para especificar classpaths.

Aquí es un buen artículo que explica este enfoque: https://blogs.oracle.com/mr/entry/class_path_wildcards_in_mustang

+1

@Zwei steinen: quiere ser una plataforma cruzada. Java 6 significa que te cortarías de una gran parte de la base de usuarios de OS X que tienen Mac que nunca tendrán oficialmente Java 6 (32 bits CPU Macs). – SyntaxT3rr0r

+0

Ehhhh para este proyecto La compatibilidad con OS X no es realmente una gran cosa, y de todos modos he estado compilando contra 1.6. Gracias por la sugerencia, ¡tendré que comprobar que mis otros proyectos funcionen en 1.5! – ZoFreX

+0

Voy a especificar el classpath en el manifiesto jar y requeriré que el usuario final nombre correctamente las bibliotecas de terceros cuando las actualice. Sin embargo, estoy marcando este como aceptado ya que tenía la información más genial. – ZoFreX

0

Puede probar la solución Fat-Jar, funciona perfectamente con el 'Fat Jar Eclipse Plug-In'. He usado algunos proyectos sin ningún problema. El principio de esto parece ser el mismo de tu solución actual.

+0

Si estoy leyendo bien, solo maneja el paquete para mi distribución, y no para los usuarios que actualizan sus bibliotecas externas. – ZoFreX

+0

@bpfurtado: +1, o usa "izpack" ... O haz lo mismo, no es difícil. – SyntaxT3rr0r

+0

fat-jar es solo un paquete y no proporciona un mecanismo de actualización para las bibliotecas incluidas. En cuanto a tus dificultades para copiar utilizando un Classloader personalizado, solo hago todo el desarrollo/depuración dentro de mi IDE y luego uso fat-jar para realizar la implementación, todas las pruebas pendientes con la solución 'empaquetada' estarían relacionadas con 'ClassNotFoundException's , lo que nunca sucede, ya que 'frasco de grasa' funciona bastante bien. – sysoutnull

0

Creo que voy a ir a la ruta manifiesto. Declarar la ruta de clase en el manifiesto de la jarra de la entrada, y tener entradas para:

 
libs/pircbot.jar 
libs/mysql-connector-java-5-bin.jar 
libs/c3p0.jar 

Entonces, si los usuarios quieren actualizar a las últimas versiones de las bibliotecas, van a tener que cambiar su nombre para que coincida con lo que se declara en el manifiesto. No creo que sea una molestia demasiado grande, y hace las cosas mucho más simples internamente.

En general, tampoco me gusta la idea de cargar todo en ./lib/ automáticamente, parece potencialmente peligroso.

1

Si su público es técnico (y suena como si estuvieran dispuestos a incluir nuevos archivos jar), ¿entonces quizás podría suministrar archivos .sh y .bat que puedan editar para modificar el classpath? Eso será más transparente para ellos que un cargador de clases personalizado.

+0

Este no es un mal enfoque, pero complica las cosas cuando actualizan el archivo principal del programa, ya que sus cambios deberían volver a realizarse. Creo que, en general, requerirles que cambien el nombre de los archivos es el mejor enfoque, pero si hay quejas, probablemente siga esta ruta. – ZoFreX

Cuestiones relacionadas