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

时间:2018-04-27 17:59:03

标签: 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行为进行深奥的自定义,那么它可能已经完成了这个案例。如果它 可能,那么我就不知道如何检查,并希望有任何见解。

1 个答案:

答案 0 :(得分:1)

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

如果你看一下

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

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

  1. file:/Users/myName/warPath/warName.war
  2. /WEB-INF/classes
  3. /rewrite/common/RenameFunctor.groovy
  4. 类路径上的实际资源是最后一个/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