为什么getResourceAsStream返回null?

时间:2014-10-12 16:37:48

标签: java getresource

我的jar中有一个我想加载的图像,但是getResourceAsStream()总是返回null。

目录结构:

com/thesimpzone/watch_pugs/watch_pugs/{all my class files}
META-INF/MANIFEST.MF
resources/generic/mouse.png

Content.java:

public abstract class Content {

    protected Map<String, BufferedImage> images = new HashMap<String, BufferedImage>();

    protected String prefix;

    public Content(String prefix){
        this.prefix = prefix;
    }

    protected void loadImage(String name){
        System.out.println(name);
        System.out.println(prefix);
        String path = (prefix + name);
        System.out.println(path);
        String identifier = name.substring(0, name.lastIndexOf("."));
        try{
            InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(path);
            images.put(identifier, ImageIO.read(in));
        }catch(IOException | ClassCastException e){
            throw new RuntimeException("Image " + identifier + " at " + path + " could not be loaded.");
        }
    }
    [...]
}

GenericContent.java:

public class GenericContent extends Content {

    public GenericContent(){
        super("resources/generic/");
        this.loadContent();
    }

    @Override
    public void loadContent() {
        loadImage("mouse.png");
    }

}

堆栈跟踪:

mouse.png
resources/generic/
resources/generic/mouse.png
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: input == null!
    at javax.imageio.ImageIO.read(ImageIO.java:1348)
    at com.thesimpzone.watch_pugs.watch_pugs.content.Content.loadImage(Content.java:29)
    at com.thesimpzone.watch_pugs.watch_pugs.content.GenericContent.loadContent(GenericContent.java:17)
    at com.thesimpzone.watch_pugs.watch_pugs.content.GenericContent.<init>(GenericContent.java:12)
    at com.thesimpzone.watch_pugs.watch_pugs.Canvas.<init>(Canvas.java:45)
    at com.thesimpzone.watch_pugs.watch_pugs.Framework.<init>(Framework.java:75)
    at com.thesimpzone.watch_pugs.watch_pugs.Window.<init>(Window.java:50)
    at com.thesimpzone.watch_pugs.watch_pugs.Window.<init>(Window.java:26)
    at com.thesimpzone.watch_pugs.watch_pugs.Window$1.run(Window.java:60)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:744)
    at java.awt.EventQueue.access$400(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:697)
    at java.awt.EventQueue$3.run(EventQueue.java:691)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:714)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

我不知道为什么类加载器无法找到图像。我已经查看了编译后的jar文件,并且文件在那里,并且在paint中打开很好,所以文件没问题。我尝试了各种ClassLoader变体,包括getSystemClassLoader(),getClassLoader()和Content.class.getClassLoader();还有getResourceAsStream(path)而不是getResource(path).openStream()。我曾尝试过无论领先的&#39; /&#39;关于前缀,所以我想出了所有的想法,谷歌并没有帮助。此外,似乎我正在做的是定义&#39;前缀&#39;非常尴尬,所以如果有更好的方法,如果有人告诉我如何,我会很高兴。

感谢。

2 个答案:

答案 0 :(得分:1)

在调用getResourceAsStream()时,所有关于相对vs绝对包的内容都是关于任何包Content作为根目录的东西。

没有&#34;目录&#34;在类路径上,特别是在.jar文件中,只有包

最好的选择是Thread.currentThread().getContextClassloader().getResourceAsStream()使用完全合格的包,不含的前导/

这是最好的原因是因为在应用程序容器内部,它们通常有多个类加载器,这样您就不必关心从哪个加载资源。

在你的情况下:

Thread.currentThread().getContextClassloader().getResourceAsStream("resources/generic/mouse.png");

如果您仍然使用此方法出错,则.jar不会像您认为的那样构建,或者您是否从IDE内部获取此内容,您可能无法复制内容{ {1}}进入类路径。

我个人总是使用以下表格:

resource/generic/因为它始终适用于您所在的地方和您所在的任何类加载器,并且显式关于它在哪里寻找它正在寻找的内容。< / p>

答案 1 :(得分:0)

尝试使用 Content.class.getClassLoader().getResourceAsStream(path);