Extraño comportamiento de Class.getResource () y ClassLoader.getResource () en el archivo ejecutable

Entiendo de ¿Cuál es la diferencia entre Class.getResource () y ClassLoader.getResource ()? y desde el propio código, eso

getClass().getResource("/path/image.png") 

es idéntico a

 getClass().getClassLoader().getResource("path/image.png") 

La publicación No se puede leer una imagen en el archivo jar muestra un problema al usar

 getClass().getClassLoader().getResource("path/image.png") 

en un archivo jar ejecutable devuelve nulo, mientras

 getClass().getResource("/path/image.png") 

devuelve la URL correcta.

Since Class.getResource() delega en ClassLoader.getResource() después de eliminar la barra diagonal inicial, espero que estas llamadas sean idénticas, pero obviamente no lo son en este caso. Incluso cuando un cargador de clases especial se adjunta a la clase particular, todavía debe ser el mismo para cada llamada, lo que también da como resultado el mismo comportamiento.

Entonces, la pregunta es: ¿hay alguna circunstancia obvia bajo la cual el siguiente código devuelva nulo para la primera llamada pero la URL adecuada para la segunda llamada?

 package com.example; import java.net.URL; public class ResourceTest { public void run() { URL iconUrl1 = getClass().getClassLoader().getResource("path/image.png"); System.out.println("ClassLoader.getResource(\"path/image.png\"): " + iconUrl1); URL iconUrl2 = getClass().getResource("/path/image.png"); System.out.println("Class.getResource(\"/path/image.png\"): " + iconUrl2); } public static void main(String[] args) { ResourceTest app = new ResourceTest(); app.run(); } } 

¡Pensé que esta pregunta ya estaba hecha y respondida!

  • ¿Cuál es la diferencia entre Class.getResource () y ClassLoader.getResource ()?

getClass().getResource() busca en relación con el archivo .class mientras getClass().getClassLoader().getResource() busca en relación con la raíz de la ruta de getClass().getClassLoader().getResource() .

Si hay un SSCCE aquí, no entiendo por qué no lo hace

1) Muestra la organización del directorio en .jar, y …

2) Tomar el paquete en consideración

P: ¿Qué (si hay algo) aún no ha recibido respuesta? ¿Cuál es la diferencia entre Class.getResource () y ClassLoader.getResource ()? (y los enlaces que cita)?

=============================================== =======================

Todavía no estoy seguro de lo que no está claro, pero este ejemplo podría ayudar:

 /* SAMPLE OUTPUT: ClassLoader.getResource(/subdir/readme.txt): NULL Class.getResource(/subdir/readme.txt): SUCCESS ClassLoader.getResource(subdir/readme.txt): SUCCESS Class.getResource(subdir/readme.txt): NULL */ package com.so.resourcetest; import java.net.URL; public class ResourceTest { public static void main(String[] args) { ResourceTest app = new ResourceTest (); } public ResourceTest () { doClassLoaderGetResource ("/subdir/readme.txt"); doClassGetResource ("/subdir/readme.txt"); doClassLoaderGetResource ("subdir/readme.txt"); doClassGetResource ("subdir/readme.txt"); } private void doClassLoaderGetResource (String sPath) { URL url = getClass().getClassLoader().getResource(sPath); if (url == null) System.out.println("ClassLoader.getResource(" + sPath + "): NULL"); else System.out.println("ClassLoader.getResource(" + sPath + "): SUCCESS"); } private void doClassGetResource (String sPath) { URL url = getClass().getResource(sPath); if (url == null) System.out.println("Class.getResource(" + sPath + "): NULL"); else System.out.println("Class.getResource(" + sPath + "): SUCCESS"); } } 

Aquí está el árbol de directorios correspondiente. Resulta ser un proyecto de Eclipse, pero los directorios son los mismos independientemente de si se trata de Eclipse, Netbeans … o un archivo .jar:

 C:. ├───.settings ├───bin │ ├───com │ │ └───so │ │ └───resourcetest │ └───subdir └───src ├───com │ └───so │ └───resourcetest └───subdir 

El archivo que se abre es “subdir / readme.txt”


ADDENDUM 11/9/12:

Hola –

Copié tu código textualmente de github, volví a comstackr y volví a ejecutar:

 ClassLoader.getResource(/subdir/readme.txt): NULL Class.getResource(/subdir/readme.txt): SUCCESS ClassLoader.getResource(subdir/readme.txt): SUCCESS Class.getResource(subdir/readme.txt): NULL 

Si ese no es el resultado que estás obteniendo … Estoy desconcertado.

Por lo que sea que valga, estoy corriendo:

  • Eclipse Indigo (no debería importar)

  • Correr dentro del IDE (no debería importar si es un sistema de archivos o .jar, dentro o fuera de un IDE)

  • Mi JRE es 1.6 (en todo caso, esta es probablemente la gran cosa)

Lo siento, no hemos podido resolver lo que pensé que era un problema simple 🙁


ADDENDUM 11/21/12 (Andreas):

Como no hubo actividad reciente sobre esta cuestión, me gustaría resumir lo que encontramos:

  • Según nuestro entendimiento común, la respuesta a la pregunta anterior es: “No, no es posible que Class.getResource("/path/image.png") devuelva una URL válida, mientras que ClassLoader.getResource("path/image.png") devuelve nulo” :
    • Estamos completamente claros sobre la diferencia entre ClassLoader.getResource () y Class.getResource ()
    • Nuestras salidas de muestra coinciden, tanto para “SUCCESS” como para “null”
    • Las salidas de muestra coinciden con lo que esperaríamos
    • Conclusión: o supervisamos algo, o algo diferente causó que la “solución” descrita en la pregunta vinculada funcionara. Creo que actualmente no podemos probar uno u otro.