我想在分离的类加载器中加载库,因为不希望直接添加为依赖项,以免与项目中的其他版本冲突。 我创建了一个加载器:
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里面加载的解决方案。
答案 0 :(得分:1)
我不是100%清楚你在这里想做什么。为什么要尝试在类路径中包含冲突的依赖项?
无论如何,这是UrlClassLoader
的已知限制。您是否考虑过将嵌套jar解压缩为文件系统上的临时文件,然后将类加载器指向它?
答案 1 :(得分:0)
github.com/squark-io/nested-jar-classloader 项目能够加载嵌套 jar 文件中的类,但有很多外部依赖项。我在我的项目 (sourceforge.net/projects/mdiutilities/) 中添加了相同的机制,但在本例中没有外部依赖项。
这两个项目不是通过临时复制嵌套的 jar 文件来工作,而是直接加载类字节。