2009-02-22 8 views
21

En mi solicitud me carga los recursos de esta manera:cargar un recurso contenida en un frasco

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

y esto me da:

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

Esto funciona bien cuando corro mi aplicación desde el IDE , pero cuando corro el frasco de mi solicitud:

java -jar app.jar 

el camino se convierte en:

jar:/root/app.jar!/repository 

¿hay alguna manera de resolver este problema?

Voy a usar el "depósito" nombre de directorio con el fin de crear esto:

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

De la misma manera, voy a conseguir un nombre de archivo (en lugar de un dir) y voy a utilizar de esta manera:

System.setProperty("javax.net.ssl.trustStore", fileNameString) 

Respuesta

35

Parece que estás intentando cargar el recurso usando FileInputStream o algo así. No haga eso: en lugar de llamar al getResource, llame al getResourceAsStream y lea los datos de eso.

(Se puede cargar los recursos de la URL en su lugar, pero llamar getResourceAsStream es un poco más conveniente.)

EDIT: Después de haber visto su respuesta actualizada, parece otros fragmentos de código se basan en ser los datos de una archivo único físico en el sistema de archivos. Por lo tanto, la respuesta no es agruparlo en un archivo jar en primer lugar. Usted podría comprobar si está en un archivo separado, y si no lo extrae en un archivo temporal, pero eso es bastante raro.

+1

De acuerdo. Siempre que no pueda decir con certeza al 100% que tratará con archivos individuales físicos (java web start para uno) siempre debe codificar con streams. –

5

construir un URL, a continuación, puede cargar un recurso (incluso en un archivo jar) usando el método openStream.

+1

Eso es lo que hace 'getResourceAsStream'. –

9

Cuando se ejecuta el código usando java -jar app.jar, java usa SÓLO la ruta de clase definida en el manifiesto del archivo JAR (es decir, el atributo Class-Path). Si la clase está en app.jar, o la clase está en la ruta de clase establecida en el atributo Class-Path del manifiesto de JAR, puede cargar esa clase utilizando el siguiente fragmento de código, donde className es el 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 de la jarra, y no es en el manifiesto de Class-Path, entonces el cargador de clases no lo encontrará. En su lugar, puede usar el URLClassLoader, con cierto cuidado para tratar 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 que tendrá que hacer frente a las excepciones, y el hecho de que el flujo de entrada es null si el recurso no puede ser encontrado. Además, si necesita obtener el InputStream en un byte[], puede usar los recursos comunes de Apache IOUtils.toByteArray(...). Y, si luego quiere un Class, puede usar el método defineClass(...) del cargador de clases, que acepta el byte[].

Puede encontrar este código en una clase ClassLoaderUtils en el código fuente difusivo, que se puede encontrar en SourceForge en github.com/robphilipp/diffusive

y un método para crear URL para Windows y Unix/Linux/MacOSX de rutas relativas y absolutas en RestfulDiffuserManagerResource.createJarClassPath(...)

Cuestiones relacionadas