58 votos

NoClassDefFoundError al intentar ejecutar mi tarro con java.exe -jar...¿qué pasa?

Tengo una aplicación que estoy tratando de terminar en un frasco para facilitar la implementación. La aplicación se compila y se ejecuta correctamente (en una ventana de cmd de Windows) cuando se ejecuta como un conjunto de clases que se puede acceder desde la ruta de clases. Pero cuando me tarro de mis clases y tratar de ejecutarlo con java 1.6 en la misma ventana de cmd, puedo comenzar 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.harris.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 gracioso es que el infractor LogFactory parece estar en commons-logging-1.1.jar, que se encuentra en la ruta especificada. El archivo jar (sí, existen):

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 de la commons-logging-1.1.jar archivo:

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í, commons-logging tiene la LogFactory clase. Y por último, el contenido de mi tarro de manifiesto:

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.6.5
Created-By: 10.0-b23 (Sun Microsystems Inc.)
Main-Class: com.harris.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 ha dejado perplejos a mí, y a cualquiera de los compañeros de trabajo me he pinchado para más de un día de ahora. Solo para descartar las respuestas, por ahora, al menos, la tercera parte de las soluciones a esto son probablemente debido a restricciones de licencia y las políticas de la compañía (por ejemplo: herramientas para la creación de exe o embalaje hasta los frascos). El objetivo final es crear un tarro que puede ser copiado de mi desarrollo de la caja de Windows a un servidor Linux (con cualquier dependiente de frascos) y se utiliza para rellenar una base de datos (para las rutas de clases puede terminar siendo diferentes entre el desarrollo y la implementación de entornos). Alguna pista a este misterio sería muy apreciada!

59voto

toolkit Puntos 27248

El-jar opción es mutuamente excluyente de-classpath. Ver a un viejo descripción aquí

-jar

Ejecutar un programa encapsulado en un archivo JAR. El primer argumento es el nombre de un archivo JAR en lugar de una startup nombre de la clase. Para que esta opción funcione, el manifiesto del archivo JAR debe contener una línea de la forma Main-Class: nombre de la clase. Aquí, classname identifica la clase con el public static void main(String[] args) método que sirve como la aplicación del punto de partida.

Ver el Frasco de referencia de la herramienta de la página y el Frasco camino de Java Tutorial para obtener información acerca de cómo trabajar con los archivos Jar y Jar-file se manifiesta.

Cuando se utiliza esta opción, el archivo JAR es la fuente de todas las clases de usuario, y otra clase de usuario configuración de la ruta son ignorados.

Rápido y sucio hack es para anexar su classpath para el bootstrap classpath:

-Xbootclasspath/a:ruta de acceso

Especificar dos puntos separados camino de directires, JAR archivos, y los archivos ZIP para anexar a la predeterminada bootstrap ruta de clase.

Sin embargo, como @Dan con razón, dice, la solución correcta es asegurar que su Frascos de Manifiesto contiene la ruta de clases para todos los Frascos que se necesita.

31voto

g_tom Puntos 111

Se puede omitir la -jar opción e iniciar el archivo jar como este:

java -cp MyJar.jar;C:\externalJars\* mainpackage.MyMainClass

18voto

Gautam M. Puntos 736

Este es el problema que se está produciendo,

si el archivo JAR se cargó de "C:\java\apps\appli.jar" y el archivo de manifiesto tiene la Clase de la Ruta: de referencia "lib/other.jar", el cargador de clases se verá en "C:\java\apps\lib\" para "other.jar". No se verá en el archivo JAR de la entrada "lib/other.jar".

Solución:-

  1. Haga clic derecho en el proyecto, Seleccione Exportar.
  2. Seleccione la Carpeta de Java y en ella seleccionar Archivo JAR Ejecutable en lugar de que el archivo JAR.
  3. Seleccione las opciones apropiadas y en la Biblioteca de la sección de Manejo de seleccionar la 3ª opción de decir (se requiere la Copia de las bibliotecas en una sub-carpeta siguiente para generar el JAR).
  4. Haga clic en finalizar y el FRASCO se crea en la posición especificada junto con una carpeta que contiene los FRASCOS se menciona en el archivo de manifiesto.
  5. abra el terminal,dar la ruta adecuada para su jarra y ejecutar el comando java-jar abc.jar

    Ahora lo que va a suceder es que el cargador de clases buscará en la carpeta correcta para la referencia de los FRASCOS ya que ahora están presentes en la misma carpeta que contiene la aplicación JAR..no Hay ninguna "de java.lang.NoClassDefFoundError" excepción ahora.

Esto funcionó para mí... Espero que funcione para ti también!!!

3voto

flash Puntos 3169

si el uso de librerías externas en su programa y tratar de llevar a todos juntos en un archivo jar no es sencilla, debido a la ruta de clases de problemas, etc.

Prefiero utilizar sierras ondear para este problema.

0voto

Mary C Puntos 46

He encontrado que cuando la estoy usando una de manifiesto que la inclusión de las jarras para el classpath necesidad de tener un espacio después de la lista de cada frasco por ejemplo, "required_lib/sun/pop3.jar required_lib/sun/smtp.jar ". Incluso si es la última en la lista.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X