可执行jar中Class.getResource()和ClassLoader.getResource()的奇怪行为

我理解Class.getResource()和ClassLoader.getResource()之间的区别是什么? 并从自己的代码,那

getClass().getResource("/path/image.png") 

是相同的

 getClass().getClassLoader().getResource("path/image.png") 

张贴无法读取jar文件中的图像显示使用的问题

 getClass().getClassLoader().getResource("path/image.png") 

在一个可执行的jar文件中返回null,而

 getClass().getResource("/path/image.png") 

返回正确的URL。

Since Class.getResource()在删除前导斜杠后委托给ClassLoader.getResource() ,所以我期望这些调用是相同的,但显然它们不是这种情况。 即使当一个特殊的类加载器被附加到特定的类时,对于每个调用仍然应该是一样的,这同样会导致相同的行为。

所以,问题是: 是否有任何明显的情况下,下面的代码为第一个调用返回null,但第二个调用的正确的URL?

 package com.example; import java.net.URL; public class ResourceTest { public void run() { URL iconUrl1 = getClass().getClassLoader().getResource("path/image.png"); System.out.println("ClassLoader.getResource(\"path/image.png\"): " + iconUrl1); URL iconUrl2 = getClass().getResource("/path/image.png"); System.out.println("Class.getResource(\"/path/image.png\"): " + iconUrl2); } public static void main(String[] args) { ResourceTest app = new ResourceTest(); app.run(); } } 

我以为这个问题已经被问及回答了!

  • Class.getResource()和ClassLoader.getResource()之间有什么区别?

getClass().getResource()getClass().getClassLoader().getResource()search相对于类path根的相对于.class文件。

如果这里有一个SSCCE,我不明白为什么没有

1)在.jar中显示目录结构,并…

2)考虑包装

问:什么(如果有的话)还没有被回答Class.getResource()和ClassLoader.getResource()有什么区别? (和它引用的链接)?

================================================== =======================

我仍然不确定什么是不明确的,但是这个例子可能有帮助:

 /* SAMPLE OUTPUT: ClassLoader.getResource(/subdir/readme.txt): NULL Class.getResource(/subdir/readme.txt): SUCCESS ClassLoader.getResource(subdir/readme.txt): SUCCESS Class.getResource(subdir/readme.txt): NULL */ package com.so.resourcetest; import java.net.URL; public class ResourceTest { public static void main(String[] args) { ResourceTest app = new ResourceTest (); } public ResourceTest () { doClassLoaderGetResource ("/subdir/readme.txt"); doClassGetResource ("/subdir/readme.txt"); doClassLoaderGetResource ("subdir/readme.txt"); doClassGetResource ("subdir/readme.txt"); } private void doClassLoaderGetResource (String sPath) { URL url = getClass().getClassLoader().getResource(sPath); if (url == null) System.out.println("ClassLoader.getResource(" + sPath + "): NULL"); else System.out.println("ClassLoader.getResource(" + sPath + "): SUCCESS"); } private void doClassGetResource (String sPath) { URL url = getClass().getResource(sPath); if (url == null) System.out.println("Class.getResource(" + sPath + "): NULL"); else System.out.println("Class.getResource(" + sPath + "): SUCCESS"); } } 

这是相应的目录树。 它恰好是一个Eclipse项目,但是不pipe它是Eclipse,Netbeans …还是.jar文件,目录都是相同的:

 C:. ├───.settings ├───bin │ ├───com │ │ └───so │ │ └───resourcetest │ └───subdir └───src ├───com │ └───so │ └───resourcetest └───subdir 

正在打开的文件是“subdir / readme.txt”


附录11/9/12:

Hi –

我从github逐字复制你的代码,重新编译并重新运行:

 ClassLoader.getResource(/subdir/readme.txt): NULL Class.getResource(/subdir/readme.txt): SUCCESS ClassLoader.getResource(subdir/readme.txt): SUCCESS Class.getResource(subdir/readme.txt): NULL 

如果这不是你得到的输出…我很困惑。

无论什么价值,我正在运行:

  • Eclipse Indigo(应该没关系)

  • 在IDE中运行(在IDE内部或外部不应该是文件系统或.jar)

  • 我的JRE是1.6(如果有的话,这可能是biggie)

对不起,我们还没有能够解决我认为是一个简单的问题:(


附录11/21/12(Andreas):

由于在这个问题上没有最近的活动,我想总结一下我们发现的:

  • 根据我们的共同理解,上述问题的答案是: “不, Class.getResource("/path/image.png")返回一个有效的URL,而ClassLoader.getResource("path/image.png")返回null”
    • 我们完全清楚ClassLoader.getResource()和Class.getResource()之间的区别。
    • 我们的示例输出匹配“SUCCESS”和“null”
    • 示例输出与我们所期望的相符
    • 结论:我们要么监督某些事情,要么导致相关问题中描述的“解决scheme”发挥作用。 我认为我们目前不能certificate这一个或另一个。