URLClassLoader无法处理jar:文件网址?

时间:2016-06-04 19:56:59

标签: java url classloader urlclassloader

我想在分离的类加载器中加载库,因为不希望直接添加为依赖项,以免与项目中的其他版本冲突。 我创建了一个加载器:

public LibLoader(String resourcePath) {
    //resourcePath="/lib/Log4JHack-1.0.jar"
    URL url = getClass().getResource(resourcePath);
    loader = new URLClassLoader(new URL[] {url}, getClass().getClassLoader());
}
  

url = [file:/ D:/..../ lib / Log4JHack-1.0.jar]

如果网址是文件,则效果正常

  

url = [jar:file:/ C:/..../ Log4JHackLoader-1.0.jar!/lib/Log4JHack-1.0.jar]

如果网址是 jar:文件(jar里面的jar),那么无效

ERROR StatusLogger Unable to open jar:jar:file:/C:/Users/Dani/.m2/repository/hu/daniel/hari/log4jhack/Log4JHackLoader/1.0/Log4JHackLoader-1.0.jar!/lib/Log4JHack-1.0.jar!/META-INF/log4j-provider.properties java.net.MalformedURLException: no !/ in spec
    at java.net.URL.<init>(URL.java:620)
    at java.net.URL.<init>(URL.java:483)
    at java.net.URL.<init>(URL.java:432)
    at java.net.JarURLConnection.parseSpecs(JarURLConnection.java:175)
    at java.net.JarURLConnection.<init>(JarURLConnection.java:158)
    at sun.net.www.protocol.jar.JarURLConnection.<init>(JarURLConnection.java:81)
    at sun.net.www.protocol.jar.Handler.openConnection(Handler.java:41)
    at java.net.URL.openConnection(URL.java:972)
    at java.net.URL.openStream(URL.java:1038)
    at org.apache.logging.log4j.util.ProviderUtil.loadProvider(ProviderUtil.java:79)
    at org.apache.logging.log4j.util.ProviderUtil.<init>(ProviderUtil.java:66)
    at org.apache.logging.log4j.util.ProviderUtil.lazyInit(ProviderUtil.java:122)
    at org.apache.logging.log4j.util.ProviderUtil.hasProviders(ProviderUtil.java:106)
    at org.apache.logging.log4j.LogManager.<clinit>(LogManager.java:91)
    at hu.daniel.hari.log4jpattern.logrenderer.log4j.log4j.capture.log4j2.StringLoggerCapture.<clinit>(StringLoggerCapture.java:34)
    at hu.daniel.hari.log4jpattern.logrenderer.log4j.Log4j2Hack.doRender(Log4j2Hack.java:30)
    at hu.daniel.hari.log4jpattern.logrenderer.log4j.Log4j2Hack.render(Log4j2Hack.java:23)
    at hu.daniel.hari.log4jpattern.logrenderer.log4j.renderer.AbstractLog4jRendererAdapter.render(AbstractLog4jRendererAdapter.java:25)
    at hu.daniel.hari.log4jpattern.logrenderer.service.LogRendererServiceImpl.getOutput(LogRendererServiceImpl.java:44)
    at hu.daniel.hari.log4jpattern.logrenderer.service.LogRendererServiceImpl.render(LogRendererServiceImpl.java:37)
    at hu.daniel.hari.log4jpattern.logrenderer.TestMain.main(TestMain.java:14)
Caused by: java.lang.NullPointerException: no !/ in spec
    at sun.net.www.protocol.jar.Handler.parseAbsoluteSpec(Handler.java:171)
    at sun.net.www.protocol.jar.Handler.parseURL(Handler.java:151)
    at java.net.URL.<init>(URL.java:615)
    ... 20 more

因为我想打包可加载的Log4JHack-1.0.jar 到Log4JHackLoader-1.0.jar,我需要一个从jar里面加载的解决方案

2 个答案:

答案 0 :(得分:1)

我不是100%清楚你在这里想做什么。为什么要尝试在类路径中包含冲突的依赖项?

无论如何,这是UrlClassLoader的已知限制。您是否考虑过将嵌套jar解压缩为文件系统上的临时文件,然后将类加载器指向它?

答案 1 :(得分:0)

github.com/squark-io/nested-jar-classloader 项目能够加载嵌套 jar 文件中的类,但有很多外部依赖项。我在我的项目 (sourceforge.net/projects/mdiutilities/) 中添加了相同的机制,但在本例中没有外部依赖项。

这两个项目不是通过临时复制嵌套的 jar 文件来工作,而是直接加载类字节。