JAR ejecutable ignora su propio atributo Class-Path

Usé las instrucciones que se encuentran en Maven: ¿cómo puedo agregar una entrada de ruta de clase arbitraria a un contenedor? para agregar una entrada arbitraria al Class-Path atributo. Aquí está mi MANIFEST.MF archivo:

Manifest-Version: 1.0
Class-Path: jace-runtime.jar
Main-Class: org.jace.examples.Test

Definí org.jace.examples.Test de la siguiente manera:

public class Test
{
    public static void main(String[] args)
    {
        System.out.println("classpath: " + System.getProperty("java.class.path"));
        System.out.println("PeerExample: " + Class.forName("org.jace.util.ShutdownHook"));
    }
}

dónde org.jace.util.ShutdownHook se define en jace-runtime.jar. Cuando invoco java -jar peer_example1.jar Obtengo el siguiente resultado:

classpath: peer_example1.jar Excepción en el subproceso "principal" java.lang.ClassNotFoundException: org.jace.util.ShutdownHook

En otras palabras, Java está agregando el archivo JAR ejecutable al classpath pero ignorando Class-Path. si invoco java -cp jace-runtime.jar;peer_example1.jar org.jace.examples.Test Obtengo el resultado esperado:

classpath: jace-runtime.jar;peer_example1.jar

¿Alguna idea?

preguntado el 03 de mayo de 12 a las 18:05

Es posible que necesite ../jace-runtime.jar si la raíz jar se considera como el directorio de trabajo actual. -

@MarkoTopolnik: Lo acabo de probar. No funcionó. -

Pero, ¿ha intentado acceder a una clase en ese otro frasco? Parece que java.class.path no refleja el classpath leído desde el manifiesto. -

@MarkoTopolnik: Sí, utilicé Class.forName() para buscar una clase definida en jace-runtime.jar y no se encontró. -

3 Respuestas

Respondiendo a mi propia pregunta:

  1. Adición de entradas arbitrarias a Class-Path está bien por sí solo. El problema surge cuando habilita la indexación JAR usando:

    <configuration>
      <archive>
        <index>true</index>
      </archive>
    </configuration>
    

    Maven omitirá sus entradas de META-INF/INDEX.LIST.

  2. Cuando usa el JAR en tiempo de ejecución, Java buscará en INDEX.LIST para encontrar clases, no en MANIFEST.MF.

  3. Debido a que faltan sus entradas en INDEX.LIST, el cargador de clases no las encontrará, sin importar lo que diga el manifiesto.

Una solución sencilla es deshabilitar la indexación JAR. No estoy seguro de cómo inyectar un arbitrario Class-Path con la indexación habilitada.

contestado el 03 de mayo de 12 a las 19:05

Ojalá pudiera votar esto más de una vez. He tenido el mismo problema durante aproximadamente un año. No pude encontrar la causa hasta que vi esto. En mi caso, no tengo este código en mi archivo .pom pero todavía se está generando un INDEX.LIST. Al menos, ahora sé dónde está el problema. - Wige

Para aquellos que de otro modo no lo sepan, el mecanismo de archivo ejecutable toma el classpath del manifiesto y lo usa para cargar clases. externo al archivo.

Entonces, si espera un WAR con un classpath manifiesto de WEB-INF/classes para encontrar clases en la entrada WEB-INF/classes dentro el archivo entonces te decepcionará.

Respondido el 05 de enero de 14 a las 23:01

Según la página de herramientas para la opción jar: Enlace a documentos

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 clases de usuario.

contestado el 03 de mayo de 12 a las 19:05

-1: La documentación se refiere al hecho de que el -cp/-classpath la opción de línea de comandos se ignora en favor de la Class-Path que estoy usando, así que este no es el problema. - Gili

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.