eine Ressource in einem Glas enthalten


21

In meiner Anwendung ich Ressourcen auf diese Weise laden:

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

und das gibt mir:

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

Das funktioniert gut, wenn ich meine Anwendung von der IDE ausführen , aber wenn ich das Glas meiner Anwendung ausführen:

java -jar app.jar 

der Weg wird:

jar:/root/app.jar!/repository 

Gibt es eine Möglichkeit, dieses Problem zu lösen?

Ich werde die „Repository“ dir Namen, um diese zu erstellen verwenden:

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

In der gleichen Weise, werde ich einen Dateinamen erhalten (anstelle eines dir) und ich werde verwenden es auf diese Weise:

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

Es klingt wie Sie dann versuchen, die Ressource mit einem FileInputStream oder etwas ähnliches zu laden. Tun Sie das nicht: Rufen Sie statt getResourcegetResourceAsStream und lesen Sie die Daten aus.

(Sie könnten die Ressourcen aus der URL geladen werden stattdessen aber getResourceAsStream Aufruf ist ein bisschen bequemer.)

EDIT: Ihre aktualisierte Antwort gesehen zu haben, so scheint es andere Teile des Codes stützen sich auf die Daten in ein Wesen physische einzelne Datei im Dateisystem. Die Antwort ist daher nicht, sie in einer JAR-Datei zu bündeln. Sie können überprüfen, ob es in einer separaten Datei ist, und wenn es nicht in eine temporäre Datei extrahieren, aber das ist ziemlich hacky IMO.

+1

Zustimmen. Wann immer Sie nicht mit hundertprozentiger Sicherheit sagen können, dass Sie sich mit physischen einzelnen Dateien beschäftigen (Java Web Start für einen), sollten Sie immer mit Streams codieren. 22 feb. 092009-02-22 12:16:38


5

Konstruieren Sie eine URL, können Sie dann eine Ressource geladen werden (auch in einer jAR-Datei), um die openStream Methode.

+1

Das ist, was 'getResourceAsStream' tut. 12 jul. 162016-07-12 14:20:56


9

Beim Ausführen von Code mit java -jar app.jar verwendet Java NUR den Klassenpfad, der im Manifest der JAR-Datei definiert ist (d. H. Class-Path Attribut). Wenn sich die Klasse in app.jar befindet oder wenn die Klasse im Klassenpfad im Class-Path-Attribut des JAR-Manifests festgelegt ist, können Sie diese Klasse mit dem folgenden Code-Snippet laden, wobei className der vollständig qualifizierte Klassenname ist.

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

Nun, wenn die Klasse nicht Teil der JAR ist, und es ist nicht in dem Manifest des Class-Path, dann wird der Klassenlader nicht finden. Stattdessen können Sie die URLClassLoader mit etwas Vorsicht verwenden, um Unterschiede zwischen Windows und Unix/Linux/MacOSX zu behandeln.

// 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); 

In beiden Beispielen Sie mit den Ausnahmen zu behandeln brauchen werden, und die Tatsache, dass der Eingangsstrom ist null, wenn die Ressource nicht gefunden werden kann. Wenn Sie die InputStream in eine byte[] erhalten möchten, können Sie Apaches commons IOUtils.toByteArray(...) verwenden. Und wenn Sie dann eine Class möchten, können Sie die defineClass(...) Methode des Klassenladeprogramms verwenden, die die byte[] akzeptiert.

Sie diesen Code in einer ClassLoaderUtils Klasse in der Diffusions-Quellcode finden können, die Sie auf Source bei github.com/robphilipp/diffusive

und ein Verfahren zu schaffen URL für Windows und Unix/Linux finden/MacOSX von relativen und absoluten Pfaden in RestfulDiffuserManagerResource.createJarClassPath(...)