notacion - java lang annotation
Java: ¿Cuál de los múltiples recursos en classpath JVM toma? (3)
El ClassLoader determina dónde se ubicará un recurso (tomado de ClassLoader JavaDoc):
La clase ClassLoader usa 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.
Entonces, donde sea que se llame en su código Clase # getResource o Class # getResourceAsStream, 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 se está ejecutando desde un archivo jar, depende de las implementaciones de ClassLoader del entorno en el que se encuentra actualmente.
Here hay un ejemplo que puede usar para rastrear lo que está pasando bajo el capó en su caso particular.
Si tengo varios archivos del mismo nombre en classpath (por ejemplo, tengo múltiples .jar
con log4j.properties
), ¿cuáles son las reglas que sigue JVM para elegir uno?
Estoy contribuyendo con un caso comprobado de que si classpath es, por ejemplo, todos los jar en una carpeta, y desea priorizar uno (o algunos) de ellos, esto no funciona:
Windows:
bin/prioritized.jar;bin/*
Linux:
bin/prioritized.jar:bin/*
Parece que la primera ruta bin / priorit.jar se ignora solo porque la segunda con un comodín la incluye en su propio ámbito. Esto es lo que efectivamente rompe el orden especificado de los classpaths.
Por lo tanto, para tener múltiples recursos priorizados (probados en Java 10.0.1), debe colocarlos en ámbitos no superpuestos y luego funcionarán.
Se especifica según el orden en que los recursos (es decir, generalmente archivos jar) se especifican utilizando 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 establecer en el archivo de manifiesto de su aplicación y luego no es necesario que proporcione la opción -classpath
. Es posible que desee consultar estos artículos 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 sobre Clase JAR-class-Class describe la lógica de la búsqueda de archivos JAR.