2

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:

enter image description here

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?

user3150201
  • 1,901
  • 5
  • 26
  • 29
  • 3
    can you post the stack trace? – Manuel Manhart Jan 24 '14 at 08:45
  • 1
    see http://stackoverflow.com/questions/9853522/exporting-an-jar-file-in-eclipse-and-referencing-a-file – jacquard Jan 24 '14 at 08:48
  • @theCoder: but why would he get a NPE? – Manuel Manhart Jan 24 '14 at 08:51
  • put jar next to a file named sprites which has ball.PNG. If it works then image is not exported – shyos Jan 24 '14 at 08:54
  • Put the image into the folder next to the jar file that will solve your problem. – Mayur Jan 24 '14 at 08:54
  • 1
    1. Is the class referenced by this in the same Package as the image? 2. Have you checked the jar? Maybe there is no /sprites/ball.png . – FuryFart Jan 24 '14 at 08:55
  • @RAM I don't think they're in the same package. As you can see in my project structure I illustarated above, the `sprites` folder and the `(default package)` folder are both in the `src` folder. The sprites folder is not inside the `(default package)` folder. But is this a problem? I thought that using `(this.getClass().getResource("sprites/ball.PNG"));` uses the `src` folder as a starting point. – user3150201 Jan 24 '14 at 09:03
  • I meant jar not package in the first question. sorry – FuryFart Jan 24 '14 at 09:05
  • If you run `jar -tvf ` is there a `sprites` folder and can you see `ball.png` – First Zero Jan 24 '14 at 09:11

5 Answers5

3

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.

enter image description here

FuryFart
  • 2,304
  • 4
  • 27
  • 43
2

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);
codejitsu
  • 3,162
  • 2
  • 24
  • 38
  • Please see my edit. I did try to add '/', and tried both lowercase png and uppercase PNG. – user3150201 Jan 24 '14 at 08:51
  • I will, but this means I'll have to change a lot of places in my code. And what I did, should work, I think. Also, in previous games I made, it worked. I'm curious as to why what I did doesn't work. – user3150201 Jan 24 '14 at 08:58
1

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.

Manuel Manhart
  • 4,819
  • 3
  • 24
  • 28
  • Not sure I understand everything you wrote. But basically, you're saying that the program couldn't find the image resource. How can it be? The image resource is inside the sprites folder, which is inside the exported JAR. I checked. – user3150201 Jan 24 '14 at 09:05
  • try to move the image to your java package in a sub-package named sprites. i had the same problem once and just looked in my old code ;-) the problem is, that getResource starts looking in the actual packag of the class, if you want to have / as context there would be another way (which i don't remember atm) – Manuel Manhart Jan 24 '14 at 09:11
  • Do you mean, create a new folder inside `(default package)`, name it `sprites`, and move all my image resources in there? If so, I tried it. It doesn't work :\ – user3150201 Jan 24 '14 at 09:24
  • i updated my answer for finding the error. this is what i did to fix it. i just played around with my code and i have my image in a /resources/ folder. if nothing helps, i can give you my code as as a working example (it is a simple java weather app example from a basic java swing training i held) – Manuel Manhart Jan 24 '14 at 09:33
  • i can: http://www.file-upload.net/download-8547927/weather.zip.html there are 2 projects, weatherserver (downloads the actual weather) and 06SwingWeather (builds into an executable jar file and has the image loading in it, in AboutDialog.java). you have to build weatherserver first, then you can build the swingweather. if you got further questions just ask. – Manuel Manhart Jan 24 '14 at 12:23
  • Code removed from file-upload again since the question is solved. – Manuel Manhart Jan 27 '14 at 09:55
1

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
jacquard
  • 1,307
  • 1
  • 11
  • 16
0

Thanks all. On a Windows 7 machine apparently running under the Netbeans IDE path names are not case sensitive - but running the JAR file under Java Se 8.2 on the same machine file names suddenly are case sensitive.