java - 为什么 ClassLoader 返回带有第二个无关感叹号的路径

标签 java classloader war

我正在尝试获取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 行为进行深奥的定制,那么在这种情况下可能已经完成了。如果它可能,那么我不知道如何检查,并且希望有任何见解。

最佳答案

警告:这个答案是对机制的部分假设和猜测,它可能不是 100% 正确,但我认为它已经足够接近了。据我所知,实际的 WAR 类加载会因 servlet 容器或应用程序服务器而异,因此这个答案可能并不适用于所有这些。

如果你看

jar:file:/Users/myName/warPath/warName.war!/WEB-INF/classes!/rewrite/common/RenameFunctor.groovy

您可以将其分为以下部分:

  1. 文件:/Users/myName/warPath/warName.war
  2. /WEB-INF/classes
  3. /rewrite/common/RenameFunctor.groovy

类路径上的实际资源是最后一个,/rewrite/common/RenameFunctor.groovy,其他部分是war类加载器用来查找的部分的坐标包含该资源的类路径:首先是 war 文件本身的位置,file:/Users/myName/warPath/warName.war,然后是 war 内的路径,/WEB -INF/类

该理论建立在 JarURLConnection 的文档之上,其中指出:

A URL Connection to a Java ARchive (JAR) file or an entry in a JAR file.

The syntax of a JAR URL is:

jar:<url>!/{entry}  

for example:

jar:http://www.foo.com/bar/baz.jar!/COM/foo/Quux.class

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 内的资源。

从技术上讲,war 文件是 jar 文件,但与 jar 文件相反,war 文件本身不是类路径的一部分。相反,它包含添加到类路径中的元素,例如 WEB-INF/lib 中的 jar 文件以及 WEB-INF/classes 中的类和其他文件。

! 分隔的部分定义了 war 类加载器定位特定资源所采取的步骤,在本例中是 /rewrite/common/RenameFunctor.groovy

关于java - 为什么 ClassLoader 返回带有第二个无关感叹号的路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50067888/

相关文章:

java - ClassCastException 因为类加载器?

grails - Grails war命令未设置环境

java - 使用嵌入式 jetty 服务器运行 Web 应用程序 (WAR)

java - EAR 中的差异 部署在 Websphere 应用程序服务器中。 ( war 到耳边)

java - 正则表达式 VS 包含。最棒的表演?

java - BigInteger 类中的无用变量,为什么?

java - 使用类加载器加载数组

Java 对 Activity 的引用

Java - 使用 IO - 说明

java - 如何实现java.lang.Classloader getResources()?