Java Jar-Datei: Verwenden Sie Ressourcenerrors: URI ist nicht hierarchisch

Ich habe meine App als JAR-Datei bereitgestellt. Wenn ich Daten von einer Datei der Ressource nach außerhalb der JAR-Datei kopieren muss, mache ich diesen Code:

URL resourceUrl = getClass().getResource("/resource/data.sav"); File src = new File(resourceUrl.toURI()); //ERROR HERE File dst = new File(CurrentPath()+"data.sav"); //CurrentPath: path of jar file don't include jar file name FileInputStream in = new FileInputStream(src); FileOutputStream out = new FileOutputStream(dst); // some excute code here 

Der Fehler, den ich habe, ist: URI is not hierarchical . Dieser Fehler treffe ich nicht, wenn er in IDE ausgeführt wird.

Wenn ich obigen Code als Hilfe zu einem anderen Post auf StackOverFlow ändere:

 InputStream in = Model.class.getClassLoader().getResourceAsStream("/resource/data.sav"); File dst = new File(CurrentPath() + "data.sav"); FileOutputStream out = new FileOutputStream(dst); //.... byte[] buf = new byte[1024]; int len; while ((len = in.read(buf)) > 0) { //NULL POINTER EXCEPTION //.... } 

Solutions Collecting From Web of "Java Jar-Datei: Verwenden Sie Ressourcenerrors: URI ist nicht hierarchisch"

Du kannst das nicht machen

 File src = new File(resourceUrl.toURI()); //ERROR HERE 

Es ist keine Datei! Wenn Sie von der IDE starten, haben Sie keinen Fehler, da Sie keine JAR-Datei ausführen. In der IDE werden classn und Ressourcen auf dem Dateisystem extrahiert.

Aber Sie können einen InputStream auf diese Weise öffnen:

  InputStream in = Model.class.getClassLoader().getResourceAsStream("/data.sav"); 

Entfernen Sie "/resource" . Im Allgemeinen trennen sich die IDEs von Dateisystemklassen und -ressourcen. Aber wenn das Glas hergestellt wird, werden sie alle zusammen gesetzt. Daher wird die Ordner-Ebene "/resource" nur für die Trennung von classn und Ressourcen verwendet.

Wenn Sie eine Ressource vom Classloader erhalten, müssen Sie den Pfad angeben, über den die Ressource im Jar verfügt, also die echte Pakethierarchie.

Wenn Sie aus irgendeinem Grund wirklich ein java.io.File Objekt erstellen müssen, um auf eine Ressource innerhalb einer Jar-Datei zu verweisen, lautet die Antwort hier: https://stackoverflow.com/a/27149287/155167

 File f = new File(getClass().getResource("/MyResource").toExternalForm()); 

Hier ist eine Lösung für Eclipse RCP / Plugin-Entwickler:

 Bundle bundle = Platform.getBundle("resource_from_some_plugin"); URL fileURL = bundle.getEntry("files/test.txt"); File file = null; try { URL resolvedFileURL = FileLocator.toFileURL(fileURL); // We need to use the 3-arg constructor of URI in order to properly escape file system chars URI resolvedURI = new URI(resolvedFileURL.getProtocol(), resolvedFileURL.getPath(), null); File file = new File(resolvedURI); } catch (URISyntaxException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } 

Es ist sehr wichtig, FileLocator.toFileURL(fileURL) anstelle von resolve(fileURL) zu verwenden. Wenn das Plugin in ein jar gepackt wird, erstellt Eclipse eine entpackte Version an einem temporären Speicherort, sodass auf das Objekt mit File zugegriffen werden kann. Zum Beispiel, ich denke, Lars Vogel hat einen Fehler in seinem Artikel – http://blog.vogella.com/2010/07/06/reading-resources-from-plugin/

Während ich selbst auf dieses Problem gestoßen bin, möchte ich eine weitere Option hinzufügen (zur ansonsten perfekten Erklärung von @ dash1e):

Exportieren Sie das Plugin als Ordner (nicht als jar), indem Sie hinzufügen:

 Eclipse-BundleShape: dir 

zu Ihrer MANIFEST.MF .

Zumindest wenn Sie Ihre RCP-App mit dem Export-Assistenten (basierend auf einer *.product ) -Datei exportieren, wird dies respektiert und erzeugt einen Ordner.

Zusätzlich zu den allgemeinen Antworten können Sie “URI ist nicht hierarchisch” von der Unils- Bibliothek abrufen, die versucht, einen Datensatz aus einer .jar Datei zu laden. Dies kann passieren, wenn Sie Datensätze in einem Maven-Submodul speichern, aber tatsächlich in einem anderen.

Es gibt sogar einen Fehler UNI-197 eingereicht.