简体   繁体   中英

Exception when trying to access Resources in jar file

I'm developing a java application and I'm using gradle as my default build system. I only have one problem: I read an config file like this in my java code:

URL url = Main.class.getResource("/configuration/Config.xml");
File file = new File(url.getFile());

And here's my project structure:

|-- src
|    |-- main
|         |-- java
|         |    \-- ch.example.bla
|         |         |-- Main.java
|         |-- resources
|              \-- Config.xml
\-- build.gradle

And here's my Gradle build file:

apply plugin: 'java'
repositories {
    mavenCentral()
}
dependencies {
    compile group: 'commons-collections', name: 'commons-collections', version: '3.2'
    testCompile 'junit:junit:4.11'
}
sourceCompatibility=System.properties['java.specification.version']
version = '1.0'
compileJava {
    options.compilerArgs.add '-XDignore.symbol.file'
    options.fork = true
    options.forkOptions.executable = "javac" // assumes that javac is on PATH
    options.compilerArgs << "-XDignore.symbol.file"
}
jar {
    manifest {
        attributes    'Implementation-Title': 'ResourceTest',
                      'Implementation-Version': version,
                      'Main-Class': 'ch.example.bla.Main'
    }
}

When I run the program via eclipse, then it works without a problem. But when I generate the jar-file with the command "gradle build" then i get an exception. Here's my error message, when I try to execute the jar-file via console (with the command: "java -jar ResourceTest.jar"):

java.io.FileNotFoundException: D:\Tutorial\Spring\eclipse\workspace\ResourceTest\build\libs\file:\D:\Tutorial\Spring\eclipse\workspace\ResourceTest\build\libs\ResourceTest-1.0.jar!\configuration\Config.xml (Die Syntax für den Dateinamen, Verzeichnisnamen oder die Datenträgerbezeichnung ist falsch)
        at java.io.FileInputStream.open(Native Method)
        at java.io.FileInputStream.<init>(Unknown Source)
        at java.io.FileInputStream.<init>(Unknown Source)
        at sun.net.www.protocol.file.FileURLConnection.connect(Unknown Source)
        at sun.net.www.protocol.file.FileURLConnection.getInputStream(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(Unknown Source)
        at com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(Unknown Source)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
        at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
        at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source)
        at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source)
        at javax.xml.parsers.DocumentBuilder.parse(Unknown Source)
        at ch.example.bla.Main.main(Main.java:38)

What am I doing wrong? How should I access resources in java, so that I can use them in an jar file?

Kind regards Marc

URL url = Main.class.getResource("/configuration/Config.xml");

I don't see configuration folder in your structure. This should be :-

URL url = Main.class.getResource("Config.xml");

I think that the URL you specified doesn't match the file structure you illustrated.

URL url = Main.class.getResource("/configuration/Config.xml");

This says to start with the folder where the Main class resides, and look in a subfolder named "configuration" and find "Config.xml" within that subfolder.

But to get to the actual folder, named "resources" not "configuration", you need to make quite a trek. Main() seems to be in a subfolder of "ch.example.bla". With the folder structure listed, if I am reading it right, you would need something more like "../../resources/Config.xml" but I'm not sure I'm reading your diagram right.

Are there any classes in the "main" FOLDER (not the Main() class) that you can use as your root? Then, you wouldn't need the ".." stuff.

I'm trying to remember where the best explanation of the naming conventions was that I read. It was maybe half a year ago...You know, it might have been the API for Class.getResource()

Hmmm. Maybe not. That explanation is pretty terse, though perfectly accurate of course.

How to Use Icons has a section 2/5ths of the way down called "Loading Images using getResource" that might be more friendly.

Sorry the configuration folder is there, I just forgot to write it in the tree... Here's the actual tree:

|-- src
|    |-- main
|         |-- java
|         |    \-- ch.example.bla
|         |         |-- Main.java
|         |-- resources
|         |   \-- configuration
|         |         |-- Config.xml
\-- build.gradle

It was like this:

InputStream initialStream = null;
        OutputStream outStream = null;
        try {
            initialStream = this.getClass().getClassLoader()
                    .getResourceAsStream("config/Config.xml");
            byte[] buffer = new byte[initialStream.available()];
            initialStream.read(buffer);

            File file = File.createTempFile("ConfigTemp", ".xml");
            file.deleteOnExit();

            outStream = new FileOutputStream(file);
            outStream.write(buffer);

            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(file);
            doc.getDocumentElement().normalize();
            System.out.println("Root element :"
                    + doc.getDocumentElement().getNodeName());
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e1) {
            e1.printStackTrace();
        } finally {
            try {
                initialStream.close();
                outStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM