I made a game in Java. It works completly fine in Eclipse.
I exported it as a Runnable JAR. When double-clicking on it's icon, it doesn't open. So I tried running the JAR from the command line.
I get a NullPointerException
error, in a line of code that's trying to retrieve an image resource (as I said, it works fine inside Eclipse). This is the line of code where the error happens:
ball = new ImageIcon(this.getClass().getResource("sprites/ball.PNG"));
I have no idea what's wrong. Here is the structure of my project:
Any ideas? I'm starting to get desperate.
Thanks a lot for your help.
EDIT: I tried adding a /
to the beginning of sprites/ball.PNG
. Didn't help. Also tried to change PNG
to png
. Didn't work either.
Checked inside the JAR, the image is inside. I'm on Windows.
Here is the stacktrace:
Exception in thread "main" java.lang.NullPointerException
at javax.swing.ImageIcon.<init><Unknown Source>
at instPanel.<init><instPanel.java:17>
at Main.<init><Main.java:23>
at Main.main<Main.java:38>
EDIT: Could the fact that I'm using (default package) be a problem?
If you look inside the jar with an archive tool it should be like this.
JARROOT/*.class
JARROOT/sprites/ball.png
You can try following.
In Eclipse right click the sprites folder. Click Build Path -> Use as Source Folder
and package the project again.
And your call to the resource should be
this.getClass().getResource("/sprites/ball.png");
or
this.getClass().getResource("/ball.png");
depending on how Eclipse packaged the jar.
EDIT: Please read the documentation.
If the string you pass to getResource("")
begins with '/' it will be treated as an absolute path within the jar. If the string starts without '/' it will be treated as the relative path to the class.
Here is an image of a simple project with comments.
The folder "icons" is a resource folder. Its content will be packaged inside the jar. In this case JARROOT/other/zoom-out-icon.JPG
and JARROOT/zoom-in-icon.jpg
.
Have you tried to call the getResource
with /sprites/ball.PNG?
Other question: are you on linux system? If so, you should pay attention on uppercase (ball.PNG vs. ball.png).
EDIT:
BufferedImage image = ImageIO.read(getClass().getResource("/sprites/ball.PNG"));
ImageIcon icon = new ImageIcon(image);
You load the URL with this.getClass().getResource("sprites/ball.PNG")
but it returns:
"A java.net.URL object or null if no resource with this name is found".
So the constructor from ImageIcon(URL location)
gets null as value and if you look into the constructor you will see following line: this(location, location.toExternalForm());
.
The problem lies in that exact line as location is null and therefor location.toExternalForm()
throws your NPE.
You could fix it with
image = this.getClass().getResource("sprites/ball.PNG");
if (image != null) {
ball = new ImageIcon(image);
}
but the underlying problem is that the image is not found.
What you can to to find (and fix) the error:
1 print somewhere the path in which it will be looking:
URL resource = this.getClass().getResource("/");
resource.getFile(); // print me somehwere
URL resource = this.getClass().getResource("img/");
resource.getFile(); // print me as well
URL resource = this.getClass().getResource("img/ball.PNG");
resource.getFile(); // print me as well
2 Ensure, that the image name / path matches the case exactly since it may be case sensitive.
I tried the code you gave and ran into the same problem with the uppercase PNG file. Later, when using 'ball.png', and using the below command:
java -classpath test.jar MainClass
I am able to access the image. What is the command you are using?
Output of jar -tf Test.jar:
META-INF/MANIFEST.MF
.classpath
Test.class
sprites/ball.png
.project