Java Eclipse与jar中的class.getResource不受约束行为
我正在测试如何表示到资源文件的路径。我在Eclipse和带有jar的命令行之间得到了不同的结果 你能帮我理解为什么会有差异吗? 我有两个资源文件:Java Eclipse与jar中的class.getResource不受约束行为,java,eclipse,jar,resources,Java,Eclipse,Jar,Resources,我正在测试如何表示到资源文件的路径。我在Eclipse和带有jar的命令行之间得到了不同的结果 你能帮我理解为什么会有差异吗? 我有两个资源文件: 一个在类包中,与类文件处于同一级别 一个在类包之外,与包处于同一级别 日蚀。这确实有效: package com.example.mypackage; /* FileIO (project) * | * +---- src (source folder) * | *
- 一个在类包中,与类文件处于同一级别
- 一个在类包之外,与包处于同一级别
package com.example.mypackage;
/* FileIO (project)
* |
* +---- src (source folder)
* |
* +---- com.example.mypackage (package)
* | |
* | +---- TestRes.java (class)
* | |
* | +---- users (resource file 1)
* |
* +---- test.txt (resource file 2)
*/
public class TestRes {
public static void main(String[] args) {
// Some resource names (relative, absolute)
String[][] res = {
{ "users" , "/com/example/mypackage/users" },
{ "../../../test.txt", "/test.txt" },
{ "." , "/com/example/mypackage/" }
};
// Get resource URL
String f = "Relative: %s\nAbsolute: %s\nURL: %s (%s)\n\n";
for (String[] r : res) {
String n0 = r[0];
String n1 = r[1];
try {
String url0 = TestRes.class.getResource(n0).getPath();
String url1 = TestRes.class.getResource(n1).getPath();
System.out.printf(f, n0, n1, url0, (url0.equals(url1)));
}
catch (Exception e) { e.printStackTrace(); }
}
}
}
输出:
Relative: users
Absolute: /com/example/mypackage/users
URL: /C:/Users/User/workspace/FileIO/bin/com/example/mypackage/users (true)
Relative: ../../../test.txt
Absolute: /test.txt
URL: /C:/Users/User/workspace/FileIO/bin/test.txt (true)
Relative: .
Absolute: /com/example/mypackage/
URL: /C:/Users/User/workspace/FileIO/bin/com/example/mypackage/ (true)
但是,当我将项目导出到jar(右键单击FileIO,然后导出
),并在命令行上使用java.exe运行jar时,class.getResource()
在尝试处理第二种情况(“../../../test.txt”
)和第三种情况()时返回null
)
我检查了罐子的结构:
test.txt
位于jar的根目录下
- 根目录下还有3个附加文件(类路径、项目和清单)
TestRes.class
和用户位于com\example\mypackage
文件夹中
从Eclipse运行时,IDE通过映射到src和bin文件夹上的基本文件系统操作来模拟运行时类加载器行为。在所有情况下,模拟的行为可能与真实的运行时行为并不完全匹配。在这种特殊情况下,模拟器似乎没有阻止使用运行时不支持的路径。事实上,我们没有考虑到这一点。深入研究文档,我发现类加载器委托给父类加载器(如果有的话),或者调用getBootstrapResource。如果此步骤找不到资源,则类装入器调用findResource方法,默认情况下该方法不返回任何结果(必须由派生类实现)。由于GetBootstrapSource不是开源的,我不知道资源存储在什么地方。您是否有指向资源位置约束的链接?谢谢。@mins:com/example/mypackage/users
是类路径资源。它不是名为mypackage
目录中名为users
的文件。因此,不要试图将其作为文件系统中的文件读取。正如您在实验中所看到的,它不会一直起作用,特别是当您知道要创建一个归档文件(如jar、war等)时,…javadoc for Class.getResource()列出了仅支持的两种类型的路径。。。从包树的根目录或当前包。没有提供家长导航或其他你正在尝试的东西。这些不是文件系统路径@KonstantinKomissarchik:谢谢。我明白了。@Bhesh Gurung:谢谢。我不确定我是否完全明白你的意思。我的理解是,资源名的结构可以映射到文件系统中的文件夹和文件,或者扩展到jar中,至少在Windows下。如果这在我以外的上下文中无效,请更正我。我已经在Eclipse和jar中使用“TestRes.class.getResourceAsStream(r[1])”阅读了“用户”内容。
C:\Users\User\Desktop>java -jar TestRes.jar
Relative: users
Absolute: /com/example/mypackage/users
URL: file:/C:/Users/User/Desktop/TestRes.jar!/com/example/mypackage/users (true)
java.lang.NullPointerException
at com.example.mypackage.TestRes.main(TestRes.java:31)
java.lang.NullPointerException
at com.example.mypackage.TestRes.main(TestRes.java:31)