w128
w128

Reputation: 4928

How to load resources from /src/main/resources in a way that will work both directly from Eclipse and in a runnable JAR?

I have a Maven project in Eclipse with a main() method. The project has a dependency that uses embedded resources, i.e. it contains files in /src/main/resources. I would like to create a runnable JAR file from the project. The problem is that - depending on how I load the embedded resources - I can either run the project as a runnable JAR using java -jar my.jar, or I can run it directly from Eclipse, but not both - the reason being that the path to these resources obviously differs between the two cases.

For example, I can load the resources as follows:

// Loads /src/main/resources/script.rb;
// Works when run directly from Eclipse; throws an exception when run as a runnable JAR
InputStream resource = this.getClass().getResourceAsStream("/script.rb");

This way, I can successfully run the project directly from Eclipse. Creating a runnable JAR using Eclipse's Export → Runnable JAR file puts the script.rb resource inside the resources folder in the JAR's root, which makes the above code fail when I try to run it as java -jar my.jar. I can fix this by changing the code to point to the /resources folder:

// Works when run as 'java -jar my.jar', fails when run from Eclipse.
InputStream resource = this.getClass().getResourceAsStream("/resources/script.rb");

Now, the exported JAR file works fine, but I can no longer successfully run my project as a Java application directly from Eclipse.

I read several other posts on loading resources, but nothing helped so far.

Is there a way to fix this and load the resource in a way that works correctly in both cases? What would probably work is convincing Eclipse to put resources inside the JAR's root instead of inside the resources folder, but I'm not sure if this is possible.

Upvotes: 1

Views: 2983

Answers (1)

lance-java
lance-java

Reputation: 27986

Using Class.getResourceAsStream(...) will load relative to the package. You should use Classloader.getResourceAsStream(...) to load from root.

Eg

InputStream resource = this.getClass().getClassloader().getResourceAsStream("script.rb");

(Assuming that src/main/resources is on the ecliplse classpath)

Note: the / has been removed!

Upvotes: 1

Related Questions