3

My class IntroState.java has the following path:

Project/src/GameState/IntroState.java

My image is located at:

Project/Resources/Images/logo.png

The folder Resources is a Source Folder. I use Eclipse oxygen.

i try to load it with:

new BufferedImage image = ImageIO.read(getClass().getResource("/Images/logo.png");

I get a NullPointerException when i run it. This Code worked fine in an older project, but my Laptop died and i had to reinstall Eclipse and redo my Code, since then it stopped working. Anyone see the problem? i tried lots of different paths, i have the feeling that some of my Eclipse settings are wrong maybe.

Nafta
  • 71
  • 1
  • 7
  • It is hard to tell what is wrong with your project without actually seeing its structure or settings. Maybe you need to use some clear/rebuild options? If that doesn't help take a look at this question about loading resources: [Loading image resource](https://stackoverflow.com/q/9864267), which for Eclipse points us out to [Runnable JARs missing Images/Files (Resources)](https://stackoverflow.com/q/8960381) – Pshemo May 23 '18 at 12:26
  • Is the Resources directory included in the Java Build Path in your Eclipse project settings? – david a. May 23 '18 at 12:35
  • Look in the jar (zip format) to find `/Images/logo.png`. Case-sensitive. Marking the folder as source folder should have done it, and `IntroState.class.getResource("/Images/logo.png")`. – Joop Eggen May 23 '18 at 12:35
  • as already stated in the question, the folder "Resources" is included in the build path as Source Folder. I also rebuilt the Project multiple times. – Nafta May 23 '18 at 12:38

3 Answers3

1

It will search for the image based on the location of the class. Since class GamesState.Introstate is found at Project/src (in actual fact in eclipse it is probably found at Project/bin) it will look for the image at Project/src/Images/logo.png when you use the path /Images/logo.png

Sean F
  • 4,344
  • 16
  • 30
  • I already had something like this working with the same folder structure and images in "Resources" were found with getClass().getResource("/images/logo.png"); – Nafta May 23 '18 at 12:32
  • https://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getResource(java.lang.String) : Before delegation, an absolute resource name is constructed from the given resource name using this algorithm: If the name begins with a '/' ('\u002f'), then the absolute name of the resource is the portion of the name following the '/'. Otherwise, the absolute name is of the following form: modified_package_name/name Where the modified_package_name is the package name of this object with '/' substituted for '.' ('\u002e'). – Sean F May 23 '18 at 14:51
  • In order to find it, it must be on the class path. If you don't know what the class path is, you need a basic java tutorial. So, it simply cannot be in Project/Resources since no part of that is part of the classpath. So move it to somewhere under src, and then use either the absolute or relative path from the class path entry of the class for which you call getResource() – Sean F May 23 '18 at 14:54
  • If you put it in GameState, and you use IntroState as the class for getResource(), then either "/GameState/logo.png" or just "logo.png" will work – Sean F May 23 '18 at 14:55
0

You should read the file as stream

Try using:

getClass().getClassLoader().getResourceAsStream("Images/logo.png")

Or

getClass().getClassLoader().getResource("Images/logo.png")
Deb
  • 2,922
  • 1
  • 16
  • 32
  • I still get a NullPointerException – Nafta May 23 '18 at 12:43
  • @Nafta I am sorry.There was a mistake previously. Did you try the updated version of answer? You should not append the '/' in front of the path – Deb May 23 '18 at 12:44
  • I tried both ways with and without the '/' and with and without "getClassLoader()". it always throws an error. – Nafta May 23 '18 at 12:48
0

Say, you have a resource file in your project Project/src/com/example/icon.PNG. But this is not where the program is going to look for it. The program is going to look for your file in classpath, which is either under /out, or /target folder, the one which contains your compiled classes.

Get to know you classpath precise by running System.getProperty("java.class.path"). It has same structure as your OS $PATH variable.

In context of location of resource files, absolute means relative to the classpath, as if the classpath was / of your filesystem.

In context of location of resource files, relative means relative to the compiled class file.

When accessing resource files in Java, there are three pairs of options to consider:

  1. You may access a resource either by using ClassLoader (i.e. this.getClass().getClassLoader(), or MyClass.class.getClassLoader()), or using Class (i.e. MyClass.class, or this.getClass());
  2. You may access a resource either by providing an absolute or a relative path;
  3. You may either obtain resource's URL (i.e. this.getClass().getClassLoader().getResource("com/example/icon.PNG"), or com.example.MyClass.class.getResource("icon.PNG")), or you may obtain InputStream instead (i.e. MyClass.class.getClassLoader().getResourceAsStream("com/example/icon.PNG")), or this.getClass().getResourceAsStream("/com/example/icon.PNG"))

YOU CANNOT USE RELATIVE PATHS WITH CLASSLOADER

Absolute paths (relative to your classpath) start with / when you access it via Class, but never start with / when you access it via ClassLoader. For example:

  • this.getClass().getResourceAsStream("/com/example/icon.PNG") finds the file;
  • this.getClass().getClassLoader().getResourceAsStream("/com/example/icon.PNG") returns null
  • this.getClass().getResourceAsStream("com/example/icon.PNG") returns null
  • this.getClass().getClassLoader().getResourceAsStream("com/example/icon.PNG") finds the file
  • com.example.package1.MyObj1.class.getResource("../icon.PNG") finds the file
  • com.example.MyClass.class.getResource("icon.PNG") finds the file
  • com.example.MyClass.class.getResource("com/example/icon.PNG") returns null

Last but not least - it would be enough to have read access rights for the resource file in order to copy it to classpath (to out/production/, or target/, etc.) so even if it is root owned, read-only access rights (chmod 444 icon.PNG) then it still would be enough to build your app. If the resource file is unreadable in build time, your classpath simply won't built at all, so no worries here. If you do make a trick and take away read access rights on the resource which is already on the classpath (i.e. you do chmod 000 /target/Project/com/example/icon.PNG), then the obtained URL still won't be null, but you're going to simply read 0 bytes from it, with no error.

Václav
  • 430
  • 1
  • 7
  • 22