【问题标题】:Cannot read an image in jar file无法读取 jar 文件中的图像
【发布时间】:2012-10-26 07:43:54
【问题描述】:

当我构建一个 jar 文件并运行它时,由于找不到 imageicon,它显示一个空指针异常

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 中运行该项目时,它运行良好

这是我列出 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

【问题讨论】:

  • 试试 ClassLoader.class.getResource()。
  • 图片是否打包进JAR?
  • 您应该将 jar 文件作为 zip 文件打开,以确保图标在那里。
  • 是的,图像包含在jar文件中,我用winrar检查过
  • -1 “研究不足”,几乎可以肯定很多stackoverflow.com/…

标签: java jar nullpointerexception embedded-resource


【解决方案1】:

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

注意图标目录的位置。

【讨论】:

  • 我在 NetBeans 的帮助下构建了 jar 文件,并包含了清单文件,并且类路径也已正确设置。仍然无法使用命令行执行 jar 文件。
  • @Haxor 这没什么用。您在 jar 文件中的文件结构是否与 Andreas 在他的答案中指定的相同,尤其是其中的 bin 部分?您的清单可能很好,因为您的代码似乎可以执行。
  • @Thor84no 正确 - 但请注意“bin”目录不是 jar 文件的一部分。我已经用我的 jar 文件的结构更新了我的答案。
  • @Haxor 您是否在使用某种特殊的类加载器,或者其他可能会改变类加载行为的框架?还是这是“普通 Java”?
  • @Andreas 我正在使用 JMF(java 媒体框架)它可以改变行为吗?
【解决方案2】:

当包mediaplayer 中的MediaPlayer 调用"icons/exit.png" 的嵌入式资源时,会发生异常。这将解析为以下路径:

mediaplayer/icons/exit.png

我猜那不是路径,实际上是

icons/exit.png

这就是为什么 String 必须是 "/icons/exit.png" - 请注意 / 前缀。

String 之前的 / 通知类加载器我们的意思是搜索 来自类路径根目录的资源,而不是调用它的类的包。

【讨论】:

  • 当我使用 /icons/exit.png 时,在 netbeans 和执行 jar 文件时也会出现同样的错误。
  • 嗯.. 这是一个棘手的问题。它会缓存旧的罐子吗?如果它是小程序或使用 Java Web Start 部署,则可能是这种情况。顺便说一句 - 为什么 Thumbs.db 在 Jar 中,为什么它和两个图像位于 Jar 中的两个地方?我倾向于删除 Jar 根目录下的 .db 文件和两个图像。它们似乎是多余的,并且(尽管这应该不是问题)可能会使类加载器感到困惑。
  • @AndrewThompson 注意小difference between Class.getResource() and ClassLoader.getResource()。我想您的示例可以与Class.getResource() 一起使用,但与ClassLoader.getResource() 一起使用应该不会有什么不同。 @Haxor你可以试试`getClass().getResource("/icons/exit.png")吗?这应该与您正在尝试的相同。
  • 我刚刚尝试使用前导斜杠 - 但失败了。我找到了解释它的帖子:ClassLoader.getResource() always returns null when a leading slash is present.
  • @Andreas 我不确定是否要删除我的答案。我认为最好将其保留一段时间,以便 OP 有机会查看并关注您的链接。感谢您的提醒! :)
【解决方案3】:

非常感谢大家。 我想出了答案

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

我删除了 ClassLoader() 并且它起作用了,但我只是不知道为什么。 有人可以解释一下这背后的理论吗?

【讨论】:

  • 我认为该理论都在下面 cmets 的各个链接中进行了解释;)问题更像是为什么您的应用程序的行为与理论不同?我认为我们需要更多信息:您使用哪个 JDK/JRE 以及哪个版本来运行 jar 文件,运行 jar 文件时您的命令行是什么样的。
  • @Andreas jdk 1.6.0 jre 7 这是命令行输出Exception in thread "main" java.lang.NullPointerException at javax.swing.ImageIcon.&lt;init&gt;(Unknown Source) at mediaplayer.MediaPlayer.buildtoolbar(MediaPlayer.java:130) at mediaplayer.MediaPlayer.&lt;init&gt;(MediaPlayer.java:81) at mediaplayer.MediaPlayer.main(MediaPlayer.java:464)
  • 您用于启动应用程序的命令行是什么?比如“java -classpath...”
  • java -jar "C:\Documents and Settings\koi hath ni lagaega\My Documents\NetBeansProjects\MediaPlayer\dist\mediaplayer.jar"
  • “这应该可行”......我正在运行一些想法。需要对类加载器细节进行更多研究,并且可能需要一个关于 SO 的新的、更集中的问题。
【解决方案4】:

这段代码运行良好:

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

【讨论】:

    猜你喜欢
    • 2023-04-06
    • 1970-01-01
    • 2011-08-28
    • 2017-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-30
    相关资源
    最近更新 更多