example - java jar classpath command line
NoClassDefFoundError al intentar ejecutar mi jar con java.exe-jar... ¿qué pasa? (6)
Tengo una aplicación que intento envolver en un contenedor para una implementación más sencilla. La aplicación se compila y se ejecuta correctamente (en una ventana cmd de Windows) cuando se ejecuta como un conjunto de clases accesibles desde CLASSPATH. Pero cuando meto mis clases y trato de ejecutarlo con java 1.6 en la misma ventana de cmd, empiezo a recibir excepciones:
C:/dev/myapp/src/common/datagen>C:/apps/jdk1.6.0_07/bin/java.exe -classpath C:/myapp/libs/commons -logging-1.1.jar -server -jar DataGen.jar
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
at com.example.myapp.fomc.common.datagen.DataGenerationTest.<clinit>(Unknown Source)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
... 1 more
Lo curioso es que el LogFactory ofensivo parece estar en commons-logging-1.1.jar, que está en la ruta de clase especificada. El archivo jar (sí, está realmente allí):
C:/dev/myapp/src/common/datagen>dir C:/myapp/libs/commons-logging-1.1.jar
Volume in drive C is Local Disk
Volume Serial Number is ECCD-A6A7
Directory of C:/myapp/libs
12/11/2007 11:46 AM 52,915 commons-logging-1.1.jar
1 File(s) 52,915 bytes
0 Dir(s) 10,956,947,456 bytes free
El contenido del archivo commons-logging-1.1.jar:
C:/dev/myapp/src/common/datagen>jar -tf C:/myapp/libs/commons-logging-1.1.jar
META-INF/
META-INF/MANIFEST.MF
org/
org/apache/
org/apache/commons/
org/apache/commons/logging/
org/apache/commons/logging/impl/
META-INF/LICENSE.txt
META-INF/NOTICE.txt
org/apache/commons/logging/Log.class
org/apache/commons/logging/LogConfigurationException.class
org/apache/commons/logging/LogFactory$1.class
org/apache/commons/logging/LogFactory$2.class
org/apache/commons/logging/LogFactory$3.class
org/apache/commons/logging/LogFactory$4.class
org/apache/commons/logging/LogFactory$5.class
org/apache/commons/logging/LogFactory.class
... (more classes in commons-logging-1.1 ...)
Sí, Common-Logging tiene la clase LogFactory. Y finalmente, el contenido del manifiesto de mi jar:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.6.5
Created-By: 10.0-b23 (Sun Microsystems Inc.)
Main-Class: com.example.myapp.fomc.common.datagen.DataGenerationTest
Class-Path: commons-logging-1.1.jar commons-lang.jar antlr.jar toplink
.jar GroboTestingJUnit-1.2.1-core.jar junit.jar
Esto me ha dejado perplejo, y a todos los compañeros de trabajo a los que he escuchado durante más de un día. Solo para descartar las respuestas, al menos por el momento, las soluciones de terceros probablemente se hayan eliminado debido a las restricciones de licencia y las políticas de la empresa (por ejemplo, herramientas para crear archivos exe o empaques). El objetivo final es crear un jar que se pueda copiar desde mi caja de desarrollo de Windows a un servidor Linux (con cualquier jars dependiente) y llenar una base de datos (para que classpaths pueda ser diferente entre entornos de desarrollo y despliegue). ¡Cualquier pista sobre este misterio sería muy apreciada!
Cuando utilizo un manifiesto, he encontrado que la lista de jar para classpath necesita tener un espacio después del listado de cada jar, por ejemplo, "required_lib / sun / pop3.jar required_lib / sun / smtp.jar". Incluso si es el último en la lista.
Este es el problema que está ocurriendo,
si el archivo JAR se cargó desde "C: / java / apps / appli.jar", y su archivo de manifiesto tiene el Class-Path: referencia "lib / other.jar", el cargador de clases se verá en "C: / java" / apps / lib / "para" other.jar ". No mirará la entrada del archivo JAR "lib / other.jar".
Solución:-
- Haga clic derecho en el proyecto, seleccione Exportar.
- Seleccione la carpeta Java y en ella seleccione el archivo JAR ejecutable en lugar del archivo JAR.
- Seleccione las opciones adecuadas y en la sección Manejo de la Biblioteca, seleccione la tercera opción, es decir (Copie las bibliotecas necesarias en una subcarpeta al lado del JAR generado).
[ EDITAR = la tercera opción genera una carpeta además del jar, la segunda opción ("Bibliotecas requeridas del paquete en el JAR generado") también se puede usar, ya que tiene el jar. ]
- Haga clic en finalizar y su JAR se creará en la posición especificada junto con una carpeta que contiene los JARS mencionados en el archivo de manifiesto.
abre la terminal, dale la ruta adecuada a tu jar y ejecútalo usando este comando java -jar abc.jar
Ahora lo que sucederá es que el cargador de clases buscará en la carpeta correcta para los JARS referenciados, ya que ahora están presentes en la misma carpeta que contiene el JAR de su aplicación. No hay una excepción "java.lang.NoClassDefFoundError" lanzada ahora.
Esto funcionó para mí ... ¡Espero que también te sirva!
La opción -jar es mutuamente excluyente de -classpath. Vea una descripción anterior here
-tarro
Ejecute un programa encapsulado en un archivo JAR. El primer argumento es el nombre de un archivo JAR en lugar de un nombre de clase de inicio. Para que esta opción funcione, el manifiesto del archivo JAR debe contener una línea del formulario Main-Class: classname. Aquí, nombre de clase identifica la clase que tiene el método public void main void (String [] args) que sirve como punto de partida de la aplicación.
Consulte la página de referencia de la herramienta Jar y la pista Jar del Tutorial de Java para obtener información sobre cómo trabajar con archivos Jar y manifiestos Jar-file.
Cuando utiliza esta opción, el archivo JAR es el origen de todas las clases de usuario y se ignoran otras configuraciones de ruta de clase de usuario.
Un truco rápido y sucio es agregar tu classpath a la ruta de acceso de clases de arranque:
-Xbootclasspath / a: ruta
Especifique una ruta de directivas, archivos JAR y archivos ZIP separados por dos puntos para agregar a la ruta predeterminada de la clase de arranque.
Sin embargo, como dice @Dan correctamente, la solución correcta es garantizar que su Manifiesto de JAR contenga el classpath para todos los JAR que necesitará.
Puede omitir la opción -jar
e iniciar el archivo jar de esta manera:
java -cp MyJar.jar;C:/externalJars/* mainpackage.MyMainClass
si usa librerías externas en su programa e intenta empacar todas juntas en un archivo jar, no es tan simple, debido a problemas de classpath, etc.
Prefiero usar OneJar para este problema.
tuve el mismo problema con mi jar la solución
- Crea el archivo MANIFEST.MF:
Manifest-Version: 1.0
Sellado: verdadero
Class-Path:. lib / jarX1.jar lib / jarX2.jar lib / jarX3.jar
Clase principal: com.MainClass
- Haga clic derecho en el proyecto, seleccione Exportar.
seleccione exportar todas las carpetas de outpout para el proyecto comprobado
- seleccione usando el manifiesto existente del espacio de trabajo y seleccione el archivo MANIFEST.MF
Esto funcionó para mí :)