简体   繁体   English

getResourceAsStream()仅在jar文件中返回null

[英]getResourceAsStream() returns null only when in jar file

I know the same question has been asked many many times, but going through all the answers already posted I couldn't find a solution. 我知道同样的问题被问过很多次,但是经历了已经发布的所有答案,我找不到解决方案。

First of all here's the code I'm using to test the issue after i encountered it in my project : 首先,这是我在我的项目中遇到它后用来测试问题的代码:

InputStream test;

System.out.println(this.getClass());
System.out.println(("classpath is: " + System.getProperty("java.class.path")));

test = getClass().getResourceAsStream("/pairs/images/100/back/back1.png");

if (test == null)
{
    System.out.println("getClass().getResourceAsStream(\"/pairs/images/100/back/back1.png\") is null");
    test = GridPanel.class.getClassLoader().getResourceAsStream("pairs/images/100/back/back1.png");
}

if (test == null)
{
    System.out.println("GridPanel.class.getClassLoader().getResourceAsStream(\"pairs/images/100/back/back1.png\") is null");
    test = ClassLoader.getSystemClassLoader().getResourceAsStream("pairs/images/100/back/back1.png");
}

if (test == null)
{
    System.out.println("ClassLoader.getSystemClassLoader().getResourceAsStream(\"pairs/images/100/back/back1.png\") is null");
    Thread.currentThread().getContextClassLoader().getResourceAsStream("pairs/images/100/back/back1.png");
}

if (test == null)
    System.out.println("Thread.currentThread().getContextClassLoader().getResourceAsStream(\"pairs/images/100/back/back1.png\") is null");

So as per title everyone of these calls to getResourceAsStream() returns null, but only when executin the jar file, when launching inside the IDE (Netbeans 8.0.2) they all return the correct stream (tested individually not with this piece of code) and I can work with it. 因此,根据标题,这些对getResourceAsStream()的调用都会返回null,但只有在执行jar文件时,当在IDE(Netbeans 8.0.2)中启动时,它们都返回正确的流(单独测试不使用这段代码)我可以用它。

The jar file contents are as follow: jar文件内容如下: http://i.stack.imgur.com/1y8i8.png

While the src folder in the netbeans project folder is the following: netbeans项目文件夹中的src文件夹如下: http://i.stack.imgur.com/AXj7s.png

So I'm really baffled at the moment, I've tried using the default settings when building with netbeans but I'm losing my head around this issue. 所以我现在真的很困惑,我在使用netbeans构建时尝试使用默认设置,但我对这个问题感到很失望。

Any hints or ideas would be much appreciated! 任何提示或想法将不胜感激!

I think the getResourceAsStream is not reading from filesystem, the leading slash will try to read from the root of the classpath (if you add a directory will read from the root). 我认为getResourceAsStream不是从文件系统读取的,前导斜杠将尝试从类路径的根读取(如果添加目录将从根读取)。 If you don't put the leading slash, you will read from the package the class is from. 如果你没有放置前导斜杠,你将从类来自的包中读取。

Did you add the directory/subdirectories you want to read the file from in the classpath? 您是否在类路径中添加了要读取文件的目录/子目录?

TL;DR It was due some stupid issue with NTFS permission, moving the jar made it work TL; DR这是由于NTFS权限的一些愚蠢问题,移动jar使其工作

So I feel very stupid right now... 所以我现在觉得很蠢......

I tried running it in a Linux environment and everything worked as supposed. 我尝试在Linux环境中运行它,一切都按照假设运行。 Each one of those calls was returning a non-null InputStream pointing to the resource. 这些调用中的每一个都返回一个指向资源的非null InputStream。

So I did something very simple: just moved around the compiled jar in Windows to check if it had something to do with NTFS permissions (keep in mind that I'm using an administrator account and I can freely write, read and execute in those folders). 所以我做了一件非常简单的事情:只是在Windows中编译的jar中移动以检查它是否与NTFS权限有关(请记住我使用的是管理员帐户,我可以在这些文件夹中自由编写,读取和执行)。 Moving it to the root of the project didn't work, but moving it on the desktop WORKED. 将它移动到项目的根目录不起作用,但在桌面上移动它。

What amazes me more is that in some other parts of the projects I'm doing 令我感到惊讶的是,在我正在做的项目的其他部分

URL jarUrl = PairsDeck.class.getProtectionDomain().getCodeSource().getLocation();

to read the whole content of the jar file and that works every time even in the old directory, so that's why I hadn't thought of screwed permissions since the beginning (and I was launching it from a command prompt with admin privileges). 读取jar文件的整个内容,即使在旧目录中也是如此,所以这就是为什么我从一开始就没有想过搞过权限(我从具有管理员权限的命令提示符启动它)。

So I guess somehow the program can read its jar with that call but not load resources from it inside my netbeans project folder due to some issues with NTFS permissions. 所以我想不管怎样,程序可以通过该调用读取它的jar,但是由于NTFS权限的一些问题,不能从我的netbeans项目文件夹中加载它。

To add some confusion 增加一些困惑

File file = new File(jarUrl.toURI());
file.canWrite();
file.canRead();
file.canExecute(); 

all of the above return true. 以上所有都返回true。

I'm just curious to know if there was a way to understand better the issue and maybe have a way to signal some permissions error from the java code. 我只是想知道是否有办法更好地理解这个问题,并且可能有办法从java代码中发出一些权限错误信号。

Thanks wholeheartedly to everybody involved for the help! 衷心感谢所有参与帮助的人!

There are two problems here. 这里有两个问题。

  1. Windows is case-insensitive. Windows不区分大小写。 Other platforms and inside a jar names are case-sensitive. 其他平台和jar名称内部区分大小写。

  2. The getClass() class determines in which jar/class path the resource is souught. getClass()类确定资源在哪个jar / class路径中。 Especially a unit test will not be put in a jar, or a child class might be located outside the jar. 特别是单元测试不会放在罐子里,或者子类可能位于罐子外面。 Either use a SomeClassInJar.class or use a ClassLoader which searches over all jars/class paths. 使用SomeClassInJar.class或使用ClassLoader搜索所有jar / class路径。 A class loader uses only absolute paths, and you must not start the path with a / . 类加载器仅使用绝对路径,并且不能使用/启动路径。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM