2012-07-15 8 views
7

Zunächst habe ich viele S.O. Fragen zu diesem Thema und ich habe die darin vorgeschlagenen Dinge ausprobiert.Wie sollte auf Ressourcen in einem kompilierten Jar zugegriffen werden?

Hier ist meine Situation. Ich schreibe eine Java-App mit dem Processing-Framework und bin in den letzten Phasen, in denen ich über die Verpackung der App nachdenken muss. Eine JAR-Datei, die über die Befehlszeile ausführbar ist, versuche ich mithilfe der Exportfunktion in Eclipse zu erstellen.

Die Struktur meines Projekts sieht wie folgt aus:

src/ 
    multiple packages/ 
libs/ 
    jar files and natives 
data/ 
    fonts and images 
config/ 
    json files 

Wenn ich exportieren Sie die JAR-Datei und uzip das Glas seinen Inhalt zu untersuchen, finde ich, dass der Inhalt dieser Verzeichnisse auf der obersten Ebene abgeladen wurden des .jar.

die wie folgt aussieht:

.jar 
    packages 
    jar files 
    fonts 
    json files 

Also, wenn ich versuche, wie eine Konfigurationsdatei mit etwas zu laden:

BufferedReader reader = new BufferedReader(new FileReader(path)); 

alles funktioniert file, wenn ich die app in Eclipse ausgeführt werden. Aber die JAR-Datei wirft eine FileNotFoundException.

Viele der Fragen, die ich auf S.O. In Bezug auf solche Probleme empfehlen wir die Verwendung von class.getClass().getResource() oder class.getResourceAsStream(). Ich habe diese beiden mit relativen Pfaden versucht und nur den Dateinamen wie in:

class.getResource('config.json'); 
class.getResources('cfg/config.json'); 
class.getResourceAsStream('../../config.json'); 

Alle diese Methoden null zurück, wenn entweder von Eclipse oder das Glas laufen mit:

java -jar myjarfile.jar 

Ich bin auch offen für die Verwendung einer Ant-Datei. Tatsächlich benutze ich jetzt die Ant-Datei, die von der Exportfunktion generiert wurde, um das Jar zu erstellen. Wenn es etwas gibt, das ich hinzufügen kann, um die Verzeichnisse in das Glas hinzuzufügen, das auch großartig wäre.

Antwort

5

Um Ressourcen im Stammverzeichnis zu erreichen, fügen Sie dem Pfad einen Pfad / hinzu. Wenn nicht, tun Sie das relativ zum aktuellen Paket, was normalerweise nur nützlich ist, wenn die Ressource auch in Ihren Quellen physisch neben der Klasse ist.

Verwenden Sie also class.getResourceAsStream("/config.json");, um config.json im Stammverzeichnis des JAR zu erreichen.

Beachten Sie auch, dass jars-inside-jars nicht direkt unterstützt werden.

+0

Vielen Dank für Ihre Antwort. Schlägst du vor, dass ich den Schrägstrich in einem Zusatz zu getResource() verwende? – JeremyFromEarth

+0

Dies scheint viel näher zu kommen. Dies ist der Pfad, den dieser zurückgibt: jar: file:/C: /path_to_project/myjarfile.jar! /config.json Wenn ich das jar ausführe, erhalte ich trotzdem eine Ausnahmedatei, obwohl der Pfad korrekt ist. Ich sollte auch erwähnen, dass es innerhalb von Eclipse funktioniert. – JeremyFromEarth

+1

Sie können FileReader nicht mit Ressourcen innerhalb von jars verwenden. Sie müssen den von getResourceAsSTream zurückgegebenen InputStream verwenden. –

1

Ihre .jar-Datei sollte nur die Verzeichnisse enthalten, die sich auf das "Paket" für den kompilierten Code beziehen. Möglicherweise verweisen Sie auf eine .war-Struktur mit/lib/WEB-INF usw., und das ist anders.

Wenn Ihr Paket Struktur ist:

com.yourco.authentication 

Und Ihre Klasse in Anmelden

Dann wird Ihr Glas

/com/ 
    /yourco/ 
    /authentication/ 
     Login.class 

sollten Sie dann die .jar in Ihrem Classpath für die env brauchen über die Befehlszeile ausführen.

Ich sehe Sie beachten, es funktioniert in Eclipse, die wahrscheinlich Umgebung Einstellungen und importierten erforderlichen Bibliotheken usw. hat so schwer genau zu sagen. Wenn Ihr Paket/Ordner den kompilierten Java-Code enthält, bin ich mir nicht sicher, ob das funktionieren wird, wenn Sie extern referenziert werden, was darauf hindeutet, dass Sie Ihre Pakete im Stammordner starten.

+0

Ich sehe einen anderen Vorschlag mit der Bearbeitung Ihres Codes, um auf/zu verweisen. ohne zu testen könnte es funktionieren, aber es sieht so aus, als ob du versuchst, eine App und keine lib mit deiner Verzeichnisstruktur zu paketieren. –