Cargar un recurso contenido en un jar

Resuelto JuanDeLosMuertos asked hace 15 años • 3 respuestas

En mi aplicación cargo recursos de esta manera:

WinProcessor.class.getResource("repository").toString();

y esto me da:

file:/root/app/repository   (and I replace "file:" with empty string)

Esto funciona bien cuando ejecuto mi aplicación desde el IDE, pero cuando ejecuto el jar de mi aplicación:

java -jar app.jar

El camino se convierte en:

jar:/root/app.jar!/repository

¿Hay alguna forma de solucionar este problema?

Usaré el nombre del directorio "repositorio" para crear esto:

ConfigurationContext ctx = (ConfigurationContext) ConfigurationContextFactory.createConfigurationContextFromFileSystem(repositoryString, null);

De la misma manera, obtendré un nombre de archivo (en lugar de un directorio) y lo usaré de esta manera:

System.setProperty("javax.net.ssl.trustStore", fileNameString)
JuanDeLosMuertos avatar Feb 22 '09 19:02 JuanDeLosMuertos
Aceptado

Parece que estás intentando cargar el recurso usando FileInputStreamalgo así. No hagas eso: en lugar de llamar getResource, llama getResourceAsStreamy lee los datos de eso.

(En su lugar, podría cargar los recursos desde la URL, pero llamar getResourceAsStreames un poco más conveniente).

EDITAR: Habiendo visto su respuesta actualizada, parece que otros fragmentos de código dependen de que los datos estén en un único archivo físico en el sistema de archivos. Por lo tanto, la respuesta es, en primer lugar, no agruparlo en un archivo jar. Puede verificar si está en un archivo separado y, si no, extraerlo a un archivo temporal, pero en mi opinión, eso es bastante complicado.

Jon Skeet avatar Feb 22 '2009 12:02 Jon Skeet

Cuando ejecuta código usando java -jar app.jar, Java usa SÓLO la ruta de clase definida en el manifiesto del archivo JAR (es decir, Class-Pathatributo). Si la clase está en app.jar, o la clase está en la ruta de clase establecida en el Class-Pathatributo del manifiesto del JAR, puede cargar esa clase usando el siguiente fragmento de código, donde es classNameel nombre de clase completo.

final String classAsPath = className.replace('.', '/') + ".class";
final InputStream input = ClassLoader.getSystemResourceAsStream( path/to/class );

Ahora bien, si la clase no es parte del JAR y no está en el manifiesto Class-Path, entonces el cargador de clases no la encontrará. En su lugar, puede utilizar URLClassLoader, con cierto cuidado para abordar las diferencias entre Windows y Unix/Linux/MacOSX.

// the class to load
final String classAsPath = className.replace('.', '/') + ".class";

// the URL to the `app.jar` file (Windows and Unix/Linux/MacOSX below)
final URL url = new URL( "file", null, "///C:/Users/diffusive/app.jar" );
//final URL url = new URL( "file", null, "/Users/diffusive/app.jar" );

// create the class loader with the JAR file
final URLClassLoader urlClassLoader = new URLClassLoader( new URL[] { url } );

// grab the resource, through, this time from the `URLClassLoader` object
// rather than from the `ClassLoader` class
final InputStream input = urlClassLoader.getResourceAsStream( classAsPath );

En ambos ejemplos, deberá lidiar con las excepciones y el hecho de que el flujo de entrada es nullsi no se puede encontrar el recurso. Además, si necesita ingresar InputStreama byte[], puede usar los commons de Apache IOUtils.toByteArray(...). Y, si luego desea un archivo Class, puede usar el defineClass(...)método del cargador de clases, que acepta el archivo byte[].

Puede encontrar este código en una ClassLoaderUtilsclase en el código fuente de Diffusive, que puede encontrar en SourceForge en github.com/robphilipp/diffusive

Y un método para crear URL para Windows y Unix/Linux/MacOSX a partir de rutas relativas y absolutas enRestfulDiffuserManagerResource.createJarClassPath(...)

Rob Philipp avatar Dec 07 '2012 23:12 Rob Philipp

Construya un URL, luego puede cargar un recurso (incluso en un archivo jar) usando el openStreammétodo.

Konrad Rudolph avatar Feb 22 '2009 12:02 Konrad Rudolph