0

I made an application that uses several images. I have 2 ways to run my app:
- press run in idea
- make a fat jar file and run it from console java -jar app.jar

If I want to run it from Idea I have to use:

BufferedImage backgroundImage = ImageIO.read(new File("res/field.png"));

instead of

BufferedImage backgroundImage = ImageIO.read(getClass().getClassLoader().getResource("res/field.png"));
<- that's what I have to use in jar file case

Why? I thought that they're about the same. Is there any universal way for my case?

Pavel
  • 4,912
  • 7
  • 49
  • 69

2 Answers2

2

I always use:

BufferedImage backgroundImage = ImageIO.read(getClass().getResource("res/field.png"));

which works from both the IDE and from inside a jar. .getResource(...) returns an URL, either jar:// or file://

Just be aware, the path either starts with a / (in which case it is relative to the package root) or it is relative to the class package - if your class is com.example.Test, /res/ refers to the folder com/example/Test/res/.

You can even use the static version - YourClassName.class.getResource(...) which allow you to easily reach other "branches" of your package tree (you can use reference is from classes located in different branches)

thedayofcondor
  • 3,860
  • 1
  • 19
  • 28
  • it works, but I have to store my images inside class folder... Is there any other way to use project root? – Pavel Nov 07 '12 at 07:41
  • If your path starts with a slash the path is relative to the root of the source folder.Ie, if your package is com.something you can access files and folders at the same level as com/ – thedayofcondor Nov 07 '12 at 07:53
  • I need to access root of the project which contains src, res and etc... I didn't get what you mean. – Pavel Nov 07 '12 at 08:09
  • When you pack a jar, the Res folder is either not included or included at the same level as it was put directly under src/. if you want it to be accessible in a uniform way the standard is to keep it SRC/ so in both the jar and IDE the folder is in the same place – thedayofcondor Nov 07 '12 at 08:16
  • So.. I have to keep my `res` folder in `src` folder if I want it to be accessible in a uniform way? And there isn't any other way? – Pavel Nov 07 '12 at 08:23
  • Basically yes - you should create the jar, unzip it with WinZip and see where the IDE puts the Res folder... and make sure your project has the same folder structure – thedayofcondor Nov 07 '12 at 08:33
  • can you please post a screenshot of the folder structure? maybe there is another way – thedayofcondor Nov 07 '12 at 08:35
  • look at http://stackoverflow.com/questions/11143878/java-image-loading-doesnt-show-up-in-jar – thedayofcondor Nov 07 '12 at 09:12
  • I posted a screenshot, but it didn't appear... As to project structure I don't want to change it, because I don't want to see `res` in my `src` ;) So... There is no uniform way... Anyway thank you all for help! – Pavel Nov 07 '12 at 12:02
  • Well, in this case, there is a trick you can use - put a placeholder file somewhere in your src. Try to get that with getClass().getResource(). You get back a "file://..." or a "jar:file..." uri, which allows you to programmatically detect if you are running from inside a jar or from the IDE - then you can use a conditional statement to use one the two methods you are already using to load your resource in the appropriate way – thedayofcondor Nov 07 '12 at 13:06
1

With java.io, the relative path is dependent on the current working directory. With getResource you must have that resource in the classpath.

panagdu
  • 2,133
  • 1
  • 21
  • 36