Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Class getResourceAsStream() resource in a different package

I have something like the following project structure

-project 
    -src/main/java // source folder
        -com.mypackage
            -Utility.java
            -some.properties
    -src/main/resources // source folder
        -configuration_files
            -configuration_report.txt

I'm generating the jar with Eclipse's Export function. The above translates to a jar with the structure:

-myjar.jar
    -com
        -mypackage
            -Utility.class
            -some.properties
    -configuration_files
        -configuration_report.txt

Within the Utility class, I'm trying to get the InputStream from configuration_report.txt.

I was doing this (it's within a static method):

Utility.class.getResourceAsStream("/configuration_files/configuration_report.txt"); 

which seems to be validated by the answer to this question, since the file is not in the same package as the class requesting it.

When I run it, however, it returns null. Why?

Note that for the some.properties file, I could do both

Utility.class.getResourceAsStream("/com/package/some.properties");
Utility.class.getResourceAsStream("some.properties");

and I would get the stream.

I'm running this from the command line if it makes any difference.

java [-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=1044] -cp myjar.jar MyMain

If I try to run it within Eclipse, it works...

Edit:

This code is relevant. With or without the preceding /, it return null

    String sourceFilePath = "/configuration_files" + File.separator + "configuration_report.txt";
    InputStream in = Utility.class.getResourceAsStream(sourceFilePath);
like image 282
Sotirios Delimanolis Avatar asked May 01 '13 14:05

Sotirios Delimanolis


People also ask

When using class getResourceAsStream Where will the resource be searched?

The java. lang. Class. getResourceAsStream() finds a resource with a given name.It returns a InputStream object or null if no resource with this name is found.

How do you get path from getResourceAsStream?

getResourceAsStream , send the absolute path from package root, but omitting the first / . If you use Class. getResourceAsStream , send either a path relative the the current Class object (and the method will take the package into account), or send the absolute path from package root, starting with a / .

What is the use of getResourceAsStream in Java?

The getResourceAsStream method returns an InputStream for the specified resource or null if it does not find the resource. The getResource method finds a resource with the specified name. It returns a URL to the resource or null if it does not find the resource. Calling java.


1 Answers

After many tries, the solution comes down to this little javadoc entry for ClassLoader#getResource(String):

The name of a resource is a '/'-separated path name that identifies the resource.

The snippet I had originally posted would've worked

Utility.class.getResourceAsStream("/configuration_files/configuration_report.txt"); 

but I wasn't using /, I was using File.separator like in my edit:

String sourceFilePath = "/configuration_files" + File.separator + "configuration_report.txt";

thinking the class loader worked like OS specific File operations. The first / was matched, but the File.separator evaluated to \\ since I'm on Windows.

The javadoc for Class#getResource(String) says more of the same.

Where the modified_package_name is the package name of this object with '/' substituted for '.' ('\u002e').

As to why this worked on Eclipse, but not from the command line, I'm still unsure, but look at @andy's comment below.

This article gives is a good explanation of this situation.

like image 79
Sotirios Delimanolis Avatar answered Sep 19 '22 19:09

Sotirios Delimanolis