我试图抓住ClassLoader
中的资源。代码的简化版本如下所示:
String ePath = "rewrite/common/RenameFunctor.groovy"
String fPath = ThClType.class.getClassLoader().getResource(ePath);
我得到的回复因为fPath是jar:file:/Users/myName/warPath/warName.war!/WEB-INF/classes!/rewrite/common/RenameFunctor.groovy
。我们想要它的资源的实际路径,除了没有第二个感叹号。 (与warName.war
不同,classes
只是一个普通目录。)
有谁知道可能导致额外感叹号的原因和/或可能做些什么来修复它?这是更新一些我没有编写的相当旧的代码的过程的一部分,因此如果可以对ClassLoader
行为进行深奥的自定义,那么它可能已经完成了这个案例。如果它 可能,那么我就不知道如何检查,并希望有任何见解。
答案 0 :(得分:1)
警告:这个答案是关于机制的部分假设和猜测,它可能不是100%正确,但我认为它足够接近。据我所知,每个servlet容器或应用程序服务器的实际WAR类加载会有所不同,因此这个答案可能并不适用于所有这些。
如果你看一下
jar:file:/Users/myName/warPath/warName.war!/WEB-INF/classes!/rewrite/common/RenameFunctor.groovy
您可以将其拆分为以下部分:
file:/Users/myName/warPath/warName.war
/WEB-INF/classes
/rewrite/common/RenameFunctor.groovy
类路径上的实际资源是最后一个/rewrite/common/RenameFunctor.groovy
,其他部分是war类加载器用于查找包含该资源的类路径部分的坐标:战争文件本身的位置file:/Users/myName/warPath/warName.war
,然后是战争中的路径/WEB-INF/classes
。
这个理论建立在JarURLConnection
的文件上,其中陈述了:
与Java ARchive(JAR)文件或JAR中的条目的URL连接 文件。
JAR URL的语法是:
jar:<url>!/{entry}
例如:
jar:http://www.foo.com/bar/baz.jar!/COM/foo/Quux.class
Jar URL应该用于引用JAR文件或JAR中的条目 文件。上面的示例是一个引用JAR条目的JAR URL。如果 条目名称被省略,URL指的是整个JAR文件:
jar:http://www.foo.com/bar/baz.jar!/
因此对于普通jar,URL的第一部分标识jar文件本身,第二部分标识jar中的资源。
技术上war文件是jar文件,但与jar文件相反,war文件本身不是类路径的一部分。相反,它包含添加到类路径中的元素。例如WEB-INF/lib
中的jar文件以及WEB-INF/classes
中的类和其他文件。
!
分隔部分然后定义war类加载器为定位特定资源所采取的步骤,在本例中为/rewrite/common/RenameFunctor.groovy
。