2012-11-06 229 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 ...」 –