为什么ClassLoader返回带有多余第二个感叹号的路径 [英] Why ClassLoader returns a path with extraneous second exclamation point
问题描述
我正在尝试在 ClassLoader
中获取资源。代码的简化版本如下所示:
I'm trying to grab a resource in ClassLoader
. A simplified version of the code looks something like this:
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
不同,类
只是一个普通目录。)
the response I get back as fPath is jar:file:/Users/myName/warPath/warName.war!/WEB-INF/classes!/rewrite/common/RenameFunctor.groovy
. The actual path to the resource we want it exactly that, except without the second exclamation point. (Unlike warName.war
, classes
is just a normal directory.)
有人知道是什么引起了额外的感叹号和/或如何解决该问题?这是更新一些我未编写的非常旧的代码的过程的一部分,因此,如果可以对 ClassLoader
行为进行深奥的自定义,则很可能已经在此完成了案件。如果可能,那么我不知道如何检查,并且不胜感激。
Does anyone know what might have caused the extra exclamation point and/or what might be done to fix it? This is as part of a process of updating some pretty old code that I didn't write, so if esoteric customization of ClassLoader
behavior is possible, it's possible it's been done in this case. if it is possible, then I don't know how to check, and would appreciate any insight.
推荐答案
警告:这个答案只是部分假设和对力学的猜测,可能不是100%正确,但是我认为它已经足够接近了。据我所知,实际的WAR类加载将随servlet容器或应用程序服务器的不同而变化,因此此答案可能并不适用于所有它们。
Warning: this answer is part supposition and guess-work on the mechanics, it may not be 100% correct, but I think it comes close enough. As far as I know actual WAR class loading will vary per servlet container or application server, so this answer may not hold for all of them.
如果您查看
jar:file:/Users/myName/warPath/warName.war!/WEB-INF/classes!/rewrite/common/RenameFunctor.groovy
您可以将其拆分为以下部分:
you can split it up in the following parts:
-
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类加载器用来查找包含该资源的类路径部分的坐标:首先是war文件本身的位置, file :/Users/myName/warPath/warName.war
,然后是战争中的路径 / WEB-INF / classes
。
The actual resource that is on the class path is the last one, /rewrite/common/RenameFunctor.groovy
, the other parts are the coordinates used by the war class loader to find the part of the class path that contains that resource: first the location of the war file itself, file:/Users/myName/warPath/warName.war
, and then the path within the war, /WEB-INF/classes
.
此理论基于 JarURLConnection
的文档建立,该文档指出:
This theory build on the documentation of the JarURLConnection
which states:
与Java ARchive(JAR)文件或JAR
文件中的条目的URL连接。
A URL Connection to a Java ARchive (JAR) file or an entry in a JAR file.
JAR URL的语法为:
The syntax of a JAR URL is:
jar:<url>!/{entry}
例如:
jar:http://www.foo.com/bar/baz.jar!/COM/foo/Quux.class
Jar URL应用于引用JAR文件或JAR
文件中的条目。上面的示例是一个JAR URL,它引用一个JAR条目。如果省略
条目名称,则URL指向整个JAR文件:
jar:http://www.foo.com/bar/baz.jar!/
Jar URLs should be used to refer to a JAR file or entries in a JAR
file. The example above is a JAR URL which refers to a JAR entry. If
the entry name is omitted, the URL refers to the whole JAR file:
jar:http://www.foo.com/bar/baz.jar!/
因此,对于普通的jar,URL的第一部分标识jar文件本身,第二部分标识jar文件本身部分标识了jar中的资源。
So for a plain jar, the first part of the URL identifies the jar file itself, and the second part identifies the resource within the jar.
从技术上讲,war文件是jar文件,但与jar文件相反,war文件本身不是类路径的一部分。相反,它包含添加到类路径中的元素,例如 WEB-INF / lib
中的jar文件以及 WEB中的类和其他文件-INF / classes
。
Technically war files are jar files, but contrary to jar files, the war file itself is not part of the class path. Instead it contains elements that are added to the class path., for example jar files in WEB-INF/lib
and the classes and other files in WEB-INF/classes
.
然后将!
分开的部分定义为战争类加载器来定位特定资源,在本例中为 /rewrite/common/RenameFunctor.groovy
。
The !
separated parts then define the steps taken by the war class loader to locate a specific resource, in this case /rewrite/common/RenameFunctor.groovy
.
这篇关于为什么ClassLoader返回带有多余第二个感叹号的路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!