2012-11-06 232 views
2

当我建立一个jar文件并运行它的图像,它显示了由于ImageIcon的一个空指针异常找不到无法读取jar文件

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

这是错误当我运行jar是我所得到文件

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) 

但是当我运行在NetBeans中的项目,它的工作好

这是输出时,我列出我的罐子里面的所有文件

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 
+0

尝试ClassLoader.class.getResource()。 – user1516873

+1

将图像打包到JAR中吗? – 2012-11-06 11:13:06

+0

您应该将jar文件作为zip文件打开以确保图标在那里。 – HericDenis

回答

4

有缺失的问题jar文件实际上是如何建造了一些信息,但与下面的目录布局

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

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(); 
    } 
} 

下面的代码就可以正常从文件系统中运行样本

$ java -classpath bin com.example.ImageIconTest 

使用MANIFEST.MF文件,内容如下:

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

,你可以将其打包为一个可执行的JAR文件,并从jar文件运行它:

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

这两种方法都工作正常时,重要的细节是确保图标目录包含在jar文件中的适当位置

当列出的jar文件的内容,它应该是这样的:

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 

注意的图标目录的位置。

+0

我在NetBeans的帮助下构建了jar文件,并且包含了清单文件,并且也正确设置了类路径。 仍然无法使用命令行执行jar文件。 – Haxor

+1

@Haxor这不是很有帮助。 jar文件中的文件结构是否与Andreas在其答案中指定的相同,尤其是它的bin部分?您的代码似乎可以执行,您的清单可能没有问题。 – Thor84no

+0

@ Thor84no right - 但请注意,“bin”目录并不是jar文件的一部分。我用我的jar文件的结构更新了我的答案。 –

0

此代码工作良好:

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); 
2

异常正在发生时MediaPlayer在包在"icons/exit.png"嵌入资源mediaplayer呼叫。这样就解决到的路径:

mediaplayer/icons/exit.png 

我猜测是不是路径,这是实际

icons/exit.png 

这就是为什么String需求是"/icons/exit.png" - 注意/前缀。

先于String/通知类加载器,我们的意思是寻找从类路径的根 资源,而不是包从它被称为类的。

+0

当我使用/icons/exit.png时,它给了我netbeans中同样的错误,同时也执行了jar文件。 – Haxor

+1

嗯..这是一个棘手的问题。它可以缓存较旧的瓶子吗?如果它是一个applet或使用Java Web Start进行部署,则可能是这种情况。顺便说一句 - 为什么瓶子里的Thumbs.db是这样的,为什么它和两个图像位于罐子里的两个地方?我倾向于删除jar文件的根目录下的'.db'文件和两个图像。它们似乎是多余的,并且(尽管它不应该是一个问题)可能会混淆类加载器。 –

+2

@AndrewThompson注意一点[Class.getResource()和ClassLoader.getResource()之间的区别](http://stackoverflow.com/questions/6608795/what-is-the-difference-between-class-getresource-and-类加载器-的getResource)。我想你的示例可以使用'Class.getResource()',但使用'ClassLoader.getResource()'它应该没有什么区别。 @Haxor你可以用'getClass()。getResource(“/ icons/exit.png”)来尝试吗?这应该与你正在尝试的相同。 –

1

感谢各位。 我想出答案

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

我删除了的ClassLoader()和它的工作,但我只是不知道为什么。 有人可以解释我背后的理论。

+0

我认为这个理论在下面的评论的各种链接中都有解释;)问题更多的是为什么你的应用程序的行为与理论不同?我认为我们需要更多的信息:你使用哪个JDK/JRE和哪个版本来运行jar文件,当运行jar文件时,命令行看起来如何。 –

+0

@Andreas JDK 1.6.0 JRE 7 这是命令行输出 '异常在线程 “主” 显示java.lang.NullPointerException 在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

+0

您用来启动应用程序的命令行是什么?像“java -classpath ...” –