• Post Reply Bookmark Topic Watch Topic
  • New Topic

Getting a Resource from a JAR file  RSS feed

 
Mike London
Ranch Hand
Posts: 1505
11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello,

I see lots of posts that seem to say they're going to explain how to get a resource (say a '.JPG') out of a JAR file using the code similar to the line of code I have below, but none of the examples actually seem to do it. Upon closer inspection, I find in every example I've looked at that they're just referring to a file in, say, a "resources" folder. I can do that successfully too -- read into an InputStream a lone file in the CLASSPATH.

--------------

But, say you have a JAR file called image.jar and inside this jar file you have a JPG (and possibly other files) called "MyCoolImage.jpg".

I believe that the basic code to read this is something like:



Yet, no matter what I try, even when I put the JAR in the same "src" folder were this code finds the JPG by itself, it's always null.

I've tried adding packages, using different paths (leading "/", non leading "/", directory in JAR to match Java package, no matching directory in JAR to match Java package, etc.).

Always "null".

So my question is, what is the secret?

How do I read a file from inside a JAR file into an InputStream?

Thanks very much for any suggestions!

mike

 
Paul Clapham
Sheriff
Posts: 22828
43
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you want to use that code as is, then you put the jpg file into the same folder (inside the jar) as the file which is trying to use the jpg. It's a relative URL so that means it's relative to the class which is getting the resource. Alternatively put a "/" before the URL to make it absolute, then put the jpg into the root folder of the jar.

But you mentioned a "src" folder... does that mean that your classes are in a package named "src"? Or does it mean that you're talking about how things are arranged in your IDE? If it's the former, then you should start looking at how things are arranged in the jar file after you produce it instead.
 
Mike London
Ranch Hand
Posts: 1505
11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul Clapham wrote:If you want to use that code as is, then you put the jpg file into the same folder (inside the jar) as the file which is trying to use the jpg. It's a relative URL so that means it's relative to the class which is getting the resource. Alternatively put a "/" before the URL to make it absolute, then put the jpg into the root folder of the jar.

But you mentioned a "src" folder... does that mean that your classes are in a package named "src"? Or does it mean that you're talking about how things are arranged in your IDE? If it's the former, then you should start looking at how things are arranged in the jar file after you produce it instead.


Still confused.

Yes, sorry, the "src" folder is just the IDE construct.

This code is in a regular Java Application.

If I put the JPG file by itself in the "src" folder, or even in a path, then code like this works fine:

In Path:


In "src" folder:


---------------------

However, if I then put the MyImage.jpg into a JAR file and put that same JAR file in the root of the src folder (same folder as the code is in, no packages currently for simplicity), then I get the 'null' with or without leading slashes.

So, both of these return null:





-------

The Jar file itself has this format:

META-INF
MyImage.jpg

-------

I am not sure I totally understood your points above so I wanted to elaborate a little on my setup.

This has got to be a simple problem.

Very much appreciate your reply and look forward to hearing back.

Thanks! :)

mike
 
Paul Clapham
Sheriff
Posts: 22828
43
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mike London wrote:However, if I then put the MyImage.jpg into a JAR file and put that same JAR file in the root of the src folder (same folder as the code is in, no packages currently for simplicity), then I get the 'null' with or without leading slashes.


Now I'm confused. Why would you do that? Normally when people ask this question (and it's a very frequent question) it's because they have generated a jar file containing their application, and they want to use resources which they packaged along with the Java classes in that jar.

However if you really want a separate jar containing only your images, you have to make sure that it's in your classpath. Then the rules for the getResource() method apply, because getResource goes through all of the classpath roots.
 
Mike London
Ranch Hand
Posts: 1505
11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul Clapham wrote:
Mike London wrote:However, if I then put the MyImage.jpg into a JAR file and put that same JAR file in the root of the src folder (same folder as the code is in, no packages currently for simplicity), then I get the 'null' with or without leading slashes.


Now I'm confused. Why would you do that? Normally when people ask this question (and it's a very frequent question) it's because they have generated a jar file containing their application, and they want to use resources which they packaged along with the Java classes in that jar.

However if you really want a separate jar containing only your images, you have to make sure that it's in your classpath. Then the rules for the getResource() method apply, because getResource goes through all of the classpath roots.


The actual JAR file that is having problem holds other project resources that would make sense.

I've tried, for trying to figure out what's going on, to use both a text file and an image file.

However, I think I'm good with the classpath as stated above since either of the files by themselves in the 'src' folder work fine. It's ONLY when they're in the JAR file (also in the 'src' folder) that they don't work.

Of course, I'm using getResourseAsStream() not getResource() as you wrote above. Not sure if that makes any difference since it works with the files by themselves but not with the JAR file (all in the src folder).

Thanks for any other thoughts you might have.

mike
 
Tony Docherty
Bartender
Posts: 3271
82
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As Paul has said if the code is running from the src folder and not from the jar then the contents of the jar will not be available unless you have explicitly added the jar file to the classpath used when the program is launched.

I must say I've never tried to use getResource() or getResourceAsStream() when my classes haven't been in a package but I assume it works the same as if they are in a package.
 
Mike London
Ranch Hand
Posts: 1505
11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Tony Docherty wrote:As Paul has said if the code is running from the src folder and not from the jar then the contents of the jar will not be available unless you have explicitly added the jar file to the classpath used when the program is launched.

I must say I've never tried to use getResource() or getResourceAsStream() when my classes haven't been in a package but I assume it works the same as if they are in a package.


Sorry for my apparent confusion. Since the standalone image file works fine with getReseourcAsStream (in the src) folder (or using an explicit path) when the program is running, doesn't that mean it's in the CLASSPATH?

Using Intellij IDEA, all the files, the JAR, the .class files, are in the same "out" folder when the program runs.

Are you saying I should put the Java code that accesses the text file or image resource into the JAR as well?

Thanks,

mike
 
Tony Docherty
Bartender
Posts: 3271
82
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sorry for my apparent confusion. Since the standalone image file works fine with getReseourcAsStream (in the src) folder (or using an explicit path) when the program is running, doesn't that mean it's in the CLASSPATH?

The way it works is the class delegates the search to its classloader so it's up to the classloader that loaded the class to decide where to look. I believe the default classloader will look on the file system and in any locations/jars that are on the classpath. The resource to be loaded doesn't need to be on the classpath as long it is reachable ie if the path is relative then there is a relative path from somewhere on the classpath that locates a resource with the given name.

The problem you have is you have packaged the files in a jar and this jar is not on the classpath so the resources are no longer directly visible to the file system and the jar is not explicitly searched as it's is not on the classpath.

Are you saying I should put the Java code that accesses the text file or image resource into the JAR as well?

No I'm saying you need to add the jar to the classpath. You can do this by adding it to the classpath specified when running java.exe.
If you do put the code into the jar then when you run the code in the jar the jar is on the classpath so that will also work.
 
Mike London
Ranch Hand
Posts: 1505
11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Tony Docherty wrote:
Sorry for my apparent confusion. Since the standalone image file works fine with getReseourcAsStream (in the src) folder (or using an explicit path) when the program is running, doesn't that mean it's in the CLASSPATH?

The way it works is the class delegates the search to its classloader so it's up to the classloader that loaded the class to decide where to look. I believe the default classloader will look on the file system and in any locations/jars that are on the classpath. The resource to be loaded doesn't need to be on the classpath as long it is reachable ie if the path is relative then there is a relative path from somewhere on the classpath that locates a resource with the given name.

The problem you have is you have packaged the files in a jar and this jar is not on the classpath so the resources are no longer directly visible to the file system and the jar is not explicitly searched as it's is not on the classpath.

Are you saying I should put the Java code that accesses the text file or image resource into the JAR as well?

No I'm saying you need to add the jar to the classpath. You can do this by adding it to the classpath specified when running java.exe.
If you do put the code into the jar then when you run the code in the jar the jar is on the classpath so that will also work.


I was assuming that the IDE would take care of the classpath as it always seems to do with a java application.

I'll try this with the -classpath option next week from the command line and report back.

For a web application, I'm assuming that putting the file in WEB-INF/classes would suffice.

Appreciate all the great replies.

mike
 
Mike London
Ranch Hand
Posts: 1505
11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Follow up:

Success, but only at the command line.

My mistake was I had forgotten that to find a resource in a jar file you had to specifically mention the jar file, by name, in the classpath. Doing this, the code works fine - but only at the command line.

However, to get this JAR file to be understood as a dependency in the IDE seems to be another matter. I've listed the JAR file in the libraries folder and also in the dependencies tab, but neither of these is sufficient (NullPointerException still). Still trying to figure that one out.

Thanks to all who have been so helpful!

mike
 
Stephan van Hulst
Saloon Keeper
Posts: 7987
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What IDE are you using?

In NetBeans, right-click the Libraries node of your project, and click "Add Jar/Folder...". In Eclipse, right-click your project, go to "Build Path" and click "Add External Archives...". Find the jar that contains your resources and your code should now work.
 
Mike London
Ranch Hand
Posts: 1505
11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:What IDE are you using?

In NetBeans, right-click the Libraries node of your project, and click "Add Jar/Folder...". In Eclipse, right-click your project, go to "Build Path" and click "Add External Archives...". Find the jar that contains your resources and your code should now work.


WHOOPS!!

I had loaded the JAR file incorrectly. In Eclipse, it's simple. You just add the library and viola, it woks. In Intellij, however, when you load the library, you get a dialog box with about 6 choices. If you select the wrong choice (I did), then you'll (still, in my case) get the NullPointerException. I selected "Jar Directory" since my JAR file did not have "classes" (the default and correct choice I later found out). Once I selected "classes" instead, Intellij worked fine. A very confusing dialog.

Thanks again to all.

mike
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!