Java 为什么getResourceAsStream返回null?

Java 为什么getResourceAsStream返回null?,java,getresource,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, Buffere

我在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.");
        }
    }
    [...]
}
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)
mouse.png
资源/一般/
参考资料/generic/mouse.png
线程“AWT-EventQueue-0”java.lang.IllegalArgumentException中出现异常:输入==null!
在javax.imageio.imageio.read(imageio.java:1348)
在com.thesimpzone.watch_-pugs.watch_-pugs.content.content.loadImage(content.java:29)上
在com.thesimpzone.watch_-pugs.watch_-pugs.content.GenericContent.loadContent(GenericContent.java:17)
在com.thesimpzone.watch_-pugs.watch_-pugs.content.GenericContent.(GenericContent.java:12)
在com.thesimpzone.watch_-pugs.watch_-pugs.Canvas.(Canvas.java:45)
在com.thesimpzone.watch_-pugs.watch_-pugs.Framework.(Framework.java:75)
在com.thesimpzone.watch_-pugs.watch_-pugs.Window.(Window.java:50)
在com.thesimpzone.watch_-pugs.watch_-pugs.Window.(Window.java:26)
在com.thesimpzone.watch_-pugs.watch_-pugs.Window$1.run(Window.java:60)
在java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)中
位于java.awt.EventQueue.dispatchEventImpl(EventQueue.java:744)
在java.awt.EventQueue.access$400(EventQueue.java:97)
位于java.awt.EventQueue$3.run(EventQueue.java:697)
位于java.awt.EventQueue$3.run(EventQueue.java:691)
位于java.security.AccessController.doPrivileged(本机方法)
位于java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
位于java.awt.EventQueue.dispatchEvent(EventQueue.java:714)
位于java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
在java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)中
位于java.awt.EventDispatchThread.PumpeEventsforHierarchy(EventDispatchThread.java:105)
位于java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
位于java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
在java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
我不知道为什么类加载器找不到图像。我已经查看了编译过的jar,文件就在那里,并且在paint中打开得很好,所以文件还可以。我尝试了各种类加载器变体,包括getSystemClassLoader()、getClassLoader()和Content.class.getClassLoader();也可以使用getResourceAsStream(path)而不是getResource(path).openStream()。我试过在前缀上加上或不加“/”,所以我已经没有主意了,谷歌也帮不上忙。而且,我定义“前缀”的方法似乎非常笨拙,所以如果有更好的方法,我会很高兴有人告诉我如何定义


谢谢。

当调用
getResourceAsStream()
时,您需要查找与作为根目录的任何包
内容相关的内容

类路径上没有“目录”,特别是在.jar文件中,只有包

最好使用
Thread.currentThread().getContextClassloader().getResourceAsStream()
,它有一个完全限定的包,不带前导的
/

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

就你而言:

Thread.currentThread().getContextClassloader().getResourceAsStream(“resources/generic/mouse.png”)

如果这种方法仍然存在错误,那么您的
.jar
并不像您想象的那样构建,或者如果您是从IDE内部获得的,那么您可能没有将内容
resource/generic/
复制到类路径中

就我个人而言,我总是使用以下表格:


Thread.currentThread().getContextClassLoader().getResourceAsStream(“path/to/resource/file.ext”)因为它总是从您调用它的任何地方以及您所处的任何类加载器工作,并且它是显式的关于它在哪里查找它要查找的内容。

尝试使用Content.class.getClassLoader().getResourceAsStream(路径)

旁注:
前缀
已经是一个
字符串
。对它调用
toString()
是没有意义的。哦,是的,那是我试图使用char[]的时候,所以它可能是最终的。作为下次的建议,不要通过重写原始代码来编辑您的问题。它误导了答案。如果需要,通过添加正在尝试的新代码和结果进行编辑。Hmm仍然会给出完全相同的错误(更新OP以显示当前代码)。我也尝试使用文字而不是变量,但由于InputStream为空,它仍然显示完全相同的IllegalArgumentException。然后,您的.jar并不像您想象的那样构建,如果您是从IDE内部获取此信息,那么您可能没有将
resource/generic
复制到类路径中。这是您的配置问题。我的目录结构是从提取导出的.jar中获取的,因此图像就在那里。嗯,好吧,我在eclipse中得到了错误,但显然,当我现在运行导出的(独立的)jar时,它能完美地加载吗?