问题描述
我目前正在通过 Java 9 将应用程序从 Java 8 迁移到 Java 11。该应用程序使用自定义的可执行 war 框架,并利用此处的嵌套类解析代码:http://pavel.savara.sweb.cz/files/JarJarURLConnection.java。此代码允许可执行 war 中的引导程序代码使用以下形式的 url 从其自己的存档中的 jar 加载类:
jar:jarjar:file:<path_to_war>^/WEB-INF/<path_to_jar>!/<path_to_class>
意图是初始 jar
协议使 JRE 将 jarjar:file:<path_to_war>^/WEB-INF/<path_to_jar>
视为要加载的资源,然后 !/
之后的任何内容都是要加载的类的路径。
自定义 jarjar
协议处理程序解析请求的 url jarjar:file:<path_to_war>^/WEB-INF/<path_to_jar>
并将其替换为另一个 jar
协议 url:jar:file:<path_to_war>!/WEB-INF/<path_to_jar>
(注意从 ^
到!
).
这在 Java 8 之前都可以正常工作,但从 Java 9 开始就失败了,我不知道为什么。 JRE 似乎忽略了由 parseURL
创建的转换后的 url,并尝试使用没有来自 WEB-INF 的嵌套 jar 的普通战争位置。
非常感谢任何帮助。此代码是其他一些更复杂代码的一部分,因此我们希望不必重新编写整个代码。
编辑: Github 存储库,包含基本代码和描述 Java 8 和 Java 11 之间行为差异的自述文件...
https://github.com/jugglingcats/execwar-test
编辑2:
在调试器中运行两者我可以看到路径完全不同,并且在 JDK11 上生成了一个带有双 !
的 url,它破坏了一切。
在 JDK8 中,当 parseUrl 被调用时,堆栈如下所示:
parseURL:111,JarJarURLConnection$JarJarURLStreamHandler (com.acme)
<init>:639,URL (java.net)
<init>:507,URL (java.net)
<init>:456,URL (java.net)
parseSpecs:175,JarURLConnection (java.net)
<init>:158,JarURLConnection (java.net)
<init>:81,JarURLConnection (sun.net.www.protocol.jar)
openConnection:41,Handler (sun.net.www.protocol.jar)
openConnection:1001,URL (java.net)
findResource:715,URLClasspath$Loader (sun.misc)
findResource:225,URLClasspath (sun.misc)
run:572,urlclassloader$2 (java.net)
run:570,urlclassloader$2 (java.net)
doPrivileged:-1,AccessController (java.security)
findResource:569,urlclassloader (java.net)
getResource:1089,ClassLoader (java.lang)
getResourceAsstream:233,urlclassloader (java.net)
main:23,Main (com.acme)
您可以看到我们已经在openConnection
。
在 JDK11 中它看起来像:
parseURL:111,JarJarURLConnection$JarJarURLStreamHandler (com.acme)
<init>:674,URL (java.net)
<init>:541,URL (java.net)
<init>:488,URL (java.net)
run:487,URLClasspath$3 (jdk.internal.loader)
run:476,URLClasspath$3 (jdk.internal.loader)
doPrivileged:-1,AccessController (java.security)
getLoader:475,URLClasspath (jdk.internal.loader)
getLoader:444,URLClasspath (jdk.internal.loader)
findResource:290,URLClasspath (jdk.internal.loader)
run:655,urlclassloader$2 (java.net)
run:653,AccessController (java.security)
findResource:652,urlclassloader (java.net)
getResource:1400,ClassLoader (java.lang)
getResourceAsstream:322,Main (com.acme)
URL nestedUrl = new URL(file.substring(0,file.length() - 2));
return new JarLoader(nestedUrl,jarHandler,lmap,acc);
JarLoader
构造函数创建一个新的 jar url,如下所示:
JarLoader(URL url,URLStreamHandler jarHandler,HashMap<String,Loader> loaderMap,AccessControlContext acc)
throws IOException
{
super(new URL("jar","",-1,url + "!/",jarHandler));
csu = url;
handler = jarHandler;
lmap = loaderMap;
this.acc = acc;
ensureopen();
}
JarLoader.base
属性现在具有值 jar:jarjar:jar:file:webapp.war!/lib.jar!/
,它会破坏事物。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)