16

I have this test app:

import java.applet.*;
import java.awt.*;
import java.net.URL;
public class Test extends Applet
{

    public void init()
    {
        URL some=Test.class.getClass().getClassLoader().getResource("/assets/pacman.png");
        System.out.println(some.toString());
        System.out.println(some.getFile());
        System.out.println(some.getPath());

    }
}

When I run it from Eclipse, I get the error:

java.lang.NullPointerException
    at Test.init(Test.java:9)
    at sun.applet.AppletPanel.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

Classpath (from .CLASSPATH file)

<classpathentry kind="src" path="src"/>

In my c:\project\src folder, I have only the Test.java file and the 'assets' directory which contains pacman.png.

What am I doing wrong and how to resolve it?

user1803551
  • 12,965
  • 5
  • 47
  • 74
Ali
  • 261,656
  • 265
  • 575
  • 769

4 Answers4

23

You don't need the slash at the start when getting a resource from a ClassLoader, because there's no idea of a "relative" part to start with. You only need it when you're getting a resource from a Class where relative paths go from the class's package level.

In addition, you don't want Test.class.getClass() as that gets the class of Test.class, which will be Class<Class>.

In other words, try either of these lines:

URL viaClass=Test.class.getResource("/assets/pacman.png");
URL viaLoader=Test.class.getClassLoader().getResource("assets/pacman.png");
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Thanks. I tried both but it doesn't work, however now it gives an exception on line 10 (which is the first system.out.println line) instead of line 9. I've made sure and the image is in project/src/assets... – Ali Mar 09 '09 at 10:32
  • that measn that "some" is null... which means you are not getting the resource properly. – TofuBeer Mar 09 '09 at 10:34
  • yes, so how can i resolve it? is the classpath incorrect or something else i need to change? – Ali Mar 09 '09 at 10:37
  • Try getting the applet side of things out of the equation - run the same code in a console app. – Jon Skeet Mar 09 '09 at 10:39
  • But i'm building an applet so I could run this in a web browser, it would be pointless to make it a console :(. There must be some way to make it work in the applet? How do applets use images? – Ali Mar 09 '09 at 10:41
  • No, it wouldn't be pointless to make it a console app - it would solve one problem at a time. Make sure you can get a resource in a simple setting, then move on to a more complicated one. For instance, your original code would have failed even in a console app. – Jon Skeet Mar 09 '09 at 10:42
  • Ok, i removed all references to applet and changed init method to public static void main(String args[]). Got the error : "Exception in thread "main" java.lang.NullPointerException at Test.main(Test.java:10)" – Ali Mar 09 '09 at 10:47
  • Same output for both of your examples – Ali Mar 09 '09 at 10:49
  • Glad you've got this fixed now. The technique of "use a simpler context to check something" is an important one though. – Jon Skeet Mar 09 '09 at 11:00
  • @JonSkeet Given that someone uses an absolute path to the resource - then it should not matter whether it is loaded via class.getResource or class.getClassLoader().getResource. Or am I assuming wrongly? – Queeg Feb 16 '23 at 13:39
  • @Queeg: It's been many years since I looked at this, but I seem to recall that if you *do* specify an "absolute" path in ClassLoader.getResource, the lookup would fail. Of course, I may be misremembering - or things may well have changed in the last 13 years. – Jon Skeet Feb 16 '23 at 14:08
8

I would do it this way:

final InputStream stream;

stream = Test.class.getResourceAsStream("assets/pacman.png");
System.out.println("Stream = " + stream);

"/assets/pacman.png" is an absolute location whle "assets/pacman.png" is a relative location.

Carl Manaster
  • 39,912
  • 17
  • 102
  • 155
TofuBeer
  • 60,850
  • 18
  • 118
  • 163
  • as expected, given that you other attempts didn't work. What is the package that the classes are in, where is the .class file located? – TofuBeer Mar 09 '09 at 10:39
  • The .class is put in c:\java\test\bin when i hit run in eclipse. The .java is in c:\java\test\src and the assets/ folder is also in this dir. No package being used right now because im just trying to make it work for my other project. Thanks – Ali Mar 09 '09 at 10:43
  • 1
    the assests dir needs to be where the .class file is – TofuBeer Mar 09 '09 at 10:51
8
  • When you use .getClass().getResource(fileName) it considers the location of the fileName is the same location of the of the calling class.
  • When you use .getClass().getClassLoader().getResource(fileName) it considers the location of the fileName is the root - in other words bin folder

It hits NullPointerException if the file is actually not exist there.

Source:

package Sound;
public class ResourceTest {
    public static void main(String[] args) {
        String fileName = "Kalimba.mp3";
        System.out.println(fileName);
        System.out.println(new ResourceTest().getClass().getResource(fileName));
        System.out.println(new ResourceTest().getClass().getClassLoader().getResource(fileName));

Output:

Kalimba.mp3
file:/C:/Users/User/Workspaces/MyEclipse%208.5/JMplayer/bin/Sound/Kalimba.mp3
file:/C:/Users/User/Workspaces/MyEclipse%208.5/JMplayer/bin/Kalimba.mp3
    }
}
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
ironwood
  • 8,936
  • 15
  • 65
  • 114
1

This works for me:

URL viaClass=Test.class.getResource("assets/test.html");

which assets in the same folder with Test.class output file (after a miserable checking and debugging)

Thinhbk
  • 2,194
  • 1
  • 23
  • 34