getClassLoader().getResource() returns null
Asked Answered
S

5

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?

Stormy answered 9/3, 2009 at 10:20 Comment(0)
J
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.

Jonathonjonati answered 9/3, 2009 at 10:34 Comment(3)
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?Jonathonjonati
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. ThanksStormy
the assests dir needs to be where the .class file isJonathonjonati
D
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");
Derwon answered 9/3, 2009 at 10:26 Comment(11)
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...Stormy
that measn that "some" is null... which means you are not getting the resource properly.Jonathonjonati
yes, so how can i resolve it? is the classpath incorrect or something else i need to change?Stormy
Try getting the applet side of things out of the equation - run the same code in a console app.Derwon
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?Stormy
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.Derwon
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)"Stormy
Same output for both of your examplesStormy
Glad you've got this fixed now. The technique of "use a simpler context to check something" is an important one though.Derwon
@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?Fateful
@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.Derwon
J
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.

Jonathonjonati answered 9/3, 2009 at 10:34 Comment(3)
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?Jonathonjonati
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. ThanksStormy
the assests dir needs to be where the .class file isJonathonjonati
C
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
    }
}
Coinstantaneous answered 29/11, 2011 at 0:51 Comment(0)
R
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)

Rattlesnake answered 26/4, 2012 at 3:4 Comment(0)
B
0

I found that the 'resouces' file is a normal file type

enter image description here

Then my code worked

URL url = FileUtility.class.getClassLoader().getResource("test.json");

Betatron answered 2/12, 2023 at 10:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.