2011-07-10 9 views

Respuesta

37

Se especifica según el orden en que se especifican los recursos (es decir, generalmente archivos jar) mediante la opción -classpath. Los recursos 'anteriores' en el classpath tienen prioridad sobre los recursos que se especifican después de ellos. Esto también se puede configurar en el archivo de manifiesto de su aplicación y luego no necesita proporcionar la opción -classpath. Es posible que desee comprobar these articles sobre cómo trabajar con archivos de manifiesto.

La descripción exhaustiva de "cómo se encuentran las clases" se puede encontrar here, donde la sección de Clases JAR-Class-Path describe la lógica de los archivos JAR-búsqueda.

+0

Si utilizo Maven, ¿eso significa que es aleatorio de facto? Establecer classpath en MANIFEST.MF no funcionaría cuando se realiza la prueba (se toman los jar del repositorio local) –

+0

Desde Maven 2.0.9, esto se puede manejar, como se describe [aquí] (http://stackoverflow.com/questions/793054/ maven-classpath-order-issues). – mouser

+1

Cualquier documentación oficial que confirme que los 'Recursos' anteriores 'en el classpath tienen prioridad sobre los recursos que se especifican después de ellos. –

7

El cargador de clases determina dónde se encuentra un recurso (tomado de ClassLoader JavaDoc):

La clase ClassLoader utiliza un modelo de delegación para buscar clases y recursos. Cada instancia de ClassLoader tiene un cargador de clases principal asociado. Cuando se le solicite que encuentre una clase o recurso, una instancia de ClassLoader delegará la búsqueda de la clase o recurso en su cargador de clases principal antes de intentar encontrar la clase o el recurso en sí. El cargador de clases incorporado de la máquina virtual, denominado "cargador de clases de arranque", no tiene un elemento primario, pero puede servir como elemento primario de una instancia de ClassLoader.

Así que donde quiera en el código de la clase nº getResource o Clase # getResourceAsStream se llama, esto sucede (tomado de Class.java)

public java.net.URL getResource(String name) { 
    name = resolveName(name); 
    ClassLoader cl = getClassLoader0(); 
    if (cl==null) { 
     // A system class. 
     return ClassLoader.getSystemResource(name); 
    } 
    return cl.getResource(name); 
} 

ClassLoader.java:

public URL getResource(String name) { 
    URL url; 
    if (parent != null) { 
     url = parent.getResource(name); 
    } else { 
     url = getBootstrapResource(name); 
    } 
    if (url == null) { 
     url = findResource(name); 
    } 
    return url; 
} 

donde ClassLoader #findResource debe ser sobreescrito por la implementación de ClassLoader. Esto implica que el comportamiento es diferente en un servidor de aplicaciones, un TomCat o si está ejecutando desde un archivo jar, depende de las implementaciones de ClassLoader del entorno en el que se encuentra actualmente.

Here es un ejemplo que puede usar para rastrear lo que está pasando bajo el capó en su caso particular.

+0

Es cierto que depende del cargador de clases, pero como uso Java SE con clasificadores de clases estándar, la otra respuesta es válida. –

+1

Esto debería agregar lo que sucede cuando se utiliza el URLClassLoader habitual, con múltiples jarras/directorios. –

Cuestiones relacionadas