Why ClassLoader returns a path with extraneous second exclamation point

走远了吗. 提交于 2020-07-22 21:33:35

问题


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);

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.)

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.


回答1:


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.

If you look at

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

you can split it up in the following parts:

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

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.

This theory build on the documentation of the JarURLConnection which states:

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!/

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.

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.

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.



来源:https://stackoverflow.com/questions/50067888/why-classloader-returns-a-path-with-extraneous-second-exclamation-point

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!