2

when i build a jar file and run it ,it shows a null pointer exception due to imageicon not found

new ImageIcon(getClass().getClassLoader().getResource("icons/exit.png")));

this is the error what i get when i run the jar file

Exception in thread "main" java.lang.NullPointerException
        at javax.swing.ImageIcon.<init>(Unknown Source)
        at mediaplayer.MediaPlayer.buildtoolbar(MediaPlayer.java:130)
        at mediaplayer.MediaPlayer.<init>(MediaPlayer.java:81)
        at mediaplayer.MediaPlayer.main(MediaPlayer.java:464)

But when i run the project in NetBeans, its working good

This is the output when i list all the files inside my jar

META-INF/
META-INF/MANIFEST.MF
helliker/
helliker/id3/
icons/
mediaplayer/
Thumbs.db
exit.png
ff1.png
helliker/id3/BinaryParser.class
helliker/id3/CorruptHeaderException.class
helliker/id3/ID3Exception.class
helliker/id3/ID3FieldDataException.class
helliker/id3/ID3Tag.class
helliker/id3/ID3v1Tag.class
helliker/id3/ID3v2ExtendedHeader.class
helliker/id3/ID3v2Footer.class
helliker/id3/ID3v2FormatException.class
helliker/id3/ID3v2Frame.class
helliker/id3/ID3v2Frames.class
helliker/id3/ID3v2Header.class
helliker/id3/ID3v2Tag.class
helliker/id3/MP3Comparator.class
helliker/id3/MP3File.class
helliker/id3/MP3FileFilter.class
helliker/id3/MPEGAudioFrameHeader.class
helliker/id3/NoMPEGFramesException.class
helliker/id3/NullsoftID3GenreTable.class
helliker/id3/Playlist.class
helliker/id3/PlaylistException.class
helliker/id3/XingVBRHeader.class
icons/Thumbs.db
icons/exit.png
icons/ff1.png
icons/label.jpg
icons/openpl.gif
icons/pause1.png
icons/play1.png
icons/playlist.png
icons/rr.png
icons/rr1.PNG
icons/stop.png
label.jpg
mediaplayer/MediaPlayer$1.class
mediaplayer/MediaPlayer$PlaylistFilter.class
mediaplayer/MediaPlayer.class
mediaplayer/PlaylistManager$1.class
mediaplayer/PlaylistManager$MP3Filter.class
mediaplayer/PlaylistManager$PlaylistFilter.class
mediaplayer/PlaylistManager.class
mediaplayer/Settings.class
mediaplayer/TagEditor.class
mediaplayer/Thumbs.db
openpl.gif
pause1.png
play1.png
playlist.png
rr.png
rr1.PNG
Haxor
  • 2,306
  • 4
  • 16
  • 18

4 Answers4

6

There is missing some information in the question how the jar file is actually built, but with the following directory layout

├── bin
│   ├── com
│   │   └── example
│   │       └── ImageIconTest.class
│   └── icons
│       └── exit.png
└── src
    ├── MANIFEST.MF
    └── com
        └── example
            └── ImageIconTest.java

and the following code in ImageIconTest.java

package com.example;
import javax.swing.ImageIcon;

public class ImageIconTest {
   public void run() {
      ImageIcon ii = new ImageIcon(getClass().getClassLoader().getResource("icons/exit.png"));
      System.out.println(ii);
   }
   public static void main(String[] args) {
      ImageIconTest app = new ImageIconTest();
      app.run();
   }
}

you can properly run the sample from the file system with

$ java -classpath bin com.example.ImageIconTest

Using a MANIFEST.MF file with the following content:

Manifest-Version: 1.0
Main-Class: com.example.ImageIconTest

you can package it into an executable jar file and run it from the jar file:

$ jar cvfm app.jar src/MANIFEST.MF -C bin .
$ java -jar app.jar

Both approaches are working fine, the important detail is to make sure that the icon directory is included in the jar file at the proper location.

When listing the jar file contents, it should look like this:

  0 Tue Nov 06 12:27:56 CET 2012 META-INF/
107 Tue Nov 06 12:27:56 CET 2012 META-INF/MANIFEST.MF
  0 Tue Nov 06 12:27:56 CET 2012 com/
  0 Tue Nov 06 12:27:56 CET 2012 com/example/
950 Tue Nov 06 12:27:56 CET 2012 com/example/ImageIconTest.class
  0 Tue Nov 06 12:00:36 CET 2012 icons/
873 Tue Nov 06 12:00:36 CET 2012 icons/exit.png

Note the location of the icons directory.

Andreas Fester
  • 36,091
  • 7
  • 95
  • 123
  • i had built the jar file with the help of NetBeans, and the manifest file is included and the classpath is also properly set. still not able to execute the jar file with command line. – Haxor Nov 06 '12 at 11:31
  • 1
    @Haxor That's not really helpful. Is your file structure inside the jar file the same as Andreas specified in his answer, particularly the bin portion of it? Your manifest is likely fine as your code seems to execute. – Vala Nov 06 '12 at 11:37
  • @Thor84no right - but note that the "bin" directory is specifically not part of the jar file. I have updated my answer with the structure of my jar file. – Andreas Fester Nov 06 '12 at 11:38
  • @Haxor Are you using some special kind of classloader, or some other framework which might change classloading behaviour? Or is this "plain Java"? – Andreas Fester Nov 06 '12 at 11:41
  • @Andreas i am using JMF (java media framework) can it change the behaviour? – Haxor Nov 06 '12 at 11:44
  • Unlikely. I also just verified with NetBeans 7.2.1 and it creates the same jar file as my manually created one, and it also runs properly. I suggest to take my sample application and see if it works for you, and then add your code step by step (or vice versa, remove all unnecessary code from your application until you have only your main class and the icon left) – Andreas Fester Nov 06 '12 at 12:09
  • @Andreas i have edited the question, you can see the list of all the files in the jar file.Is there anything wrong with the code? – Haxor Nov 06 '12 at 19:57
2

The Exception is occurring when MediaPlayer in package mediaplayer calls for an embedded resource at "icons/exit.png". This would resolve to a path of:

mediaplayer/icons/exit.png

I am guessing that is not the path, which is actually.

icons/exit.png

That is why the String needs to be "/icons/exit.png" - note the / prefix.

The / that precedes the String informs the class-loader that we mean it to search for the resource from the root of the class path, as opposed to the package of the class from which it is called.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • when i use /icons/exit.png , it gives me the same error in netbeans and while executing the jar file also. – Haxor Nov 06 '12 at 19:42
  • 1
    hmmm.. This is a tricky one. Could it be caching older Jars? This might be the case if it is an applet or deployed using Java Web Start. BTW - Why is the `Thumbs.db` in the Jar at all, and why are it and the two images located in two places in the Jar? I would tend to remove the `.db` files and both images at the root of the Jar. They seem redundant, and (although it should not be a problem) might be confusing the class-loader. – Andrew Thompson Nov 07 '12 at 03:52
  • 2
    @AndrewThompson Note the little [difference between Class.getResource() and ClassLoader.getResource()](http://stackoverflow.com/questions/6608795/what-is-the-difference-between-class-getresource-and-classloader-getresource). I suppose that your sample would work with `Class.getResource()`, but with `ClassLoader.getResource()` it should not make a difference. @Haxor Can you try with `getClass().getResource("/icons/exit.png")? This should be identical to what you are trying. – Andreas Fester Nov 07 '12 at 08:10
  • 1
    I just tried with a leading slash - and failed. I found this posting which explains it: [ClassLoader.getResource() always returns null when a leading slash is present.](http://weaklyreachable.blogspot.co.uk/2010/06/leading-slash-vs-classloadergetresource.html) – Andreas Fester Nov 07 '12 at 08:24
  • @Andreas I am not sure whether to delete my answer. I think it is better to leave it for a while so the OP has an opportunity to see & follow your links. Thanks for the heads-up! :) – Andrew Thompson Nov 07 '12 at 08:29
  • @AndrewThompson I would leave it at least for a while - agree that this is a tricky issue, I am running out of ideas how to help the OP ;) – Andreas Fester Nov 07 '12 at 08:37
  • @Andreas It worked with getClass().getResource()("/icons/image.png") i removed the classloader – Haxor Nov 07 '12 at 08:41
  • @Andreas Please explain me how it worked. whats the difference between `(getClass().getClassLoader().getResource("icons/exit.png")));` and `(getClass().getResource("/icons/playlist.png")));` – Haxor Nov 07 '12 at 08:46
  • @Haxor It is probably better to take that up on Andreas' answer, because this one will soon be deleted. – Andrew Thompson Nov 07 '12 at 08:51
1

Thanx a lot everyone. I figured out the answer

button = new JButton(new ImageIcon(getClass().getResource("/icons/playlist.png")));

i removed the ClassLoader() and it worked,but i just dont know why. Can somebody please explain me the theory behind this.?

Haxor
  • 2,306
  • 4
  • 16
  • 18
  • I think the theory is all explained in the various links in the comments below ;) The question is more like why does your application behave differently than the theory? I think we need more information: Which JDK/JRE and which version are you using to run the jar file, how does your command line look like when running the jar file. – Andreas Fester Nov 07 '12 at 08:49
  • @Andreas jdk 1.6.0 jre 7 this is the command line output `Exception in thread "main" java.lang.NullPointerException at javax.swing.ImageIcon.(Unknown Source) at mediaplayer.MediaPlayer.buildtoolbar(MediaPlayer.java:130) at mediaplayer.MediaPlayer.(MediaPlayer.java:81) at mediaplayer.MediaPlayer.main(MediaPlayer.java:464)` – Haxor Nov 07 '12 at 08:55
  • What is the command line you are using to launch the application? Like "java -classpath..." – Andreas Fester Nov 07 '12 at 08:57
  • java -jar "C:\Documents and Settings\koi hath ni lagaega\My Documents\NetBeansProjects\MediaPlayer\dist\mediaplayer.jar" – Haxor Nov 07 '12 at 09:02
  • "This should work" ... I am running ouf ideas. Needs some more research on classloader details, and probably a new, more focused question on SO. – Andreas Fester Nov 07 '12 at 09:13
  • I have posted a followup question at http://stackoverflow.com/questions/13269556/strange-behavior-of-class-getresource-and-classloader-getresource-in-executa – Andreas Fester Nov 07 '12 at 12:25
  • @Haxor Hi, I have a different scenario with regards to output. Both ClassLoader.getResource(subdir/readme.txt) and Class.getResource(/subdir/readme.txt) giving me SUCCESS when run in Eclipse. But both of them returning NULL when run from a executable jar on windows machine. Have you any time faced this kind of issue?, if yes, how did you resolve it? – Suresh Feb 08 '18 at 14:04
0

This code works well:

ClassLoader cl = getClass().getClassLoader();
InputStream stream = cl.getResourceAsStream( "hpms/study/Starbucks.jpg" );
if( stream == null ) System.err.println( "resource not found" );
BufferedImage image = ImageIO.read( stream );
ImageIcon icon = new ImageIcon( image );
Aubin
  • 14,617
  • 9
  • 61
  • 84