我有一个jar,其中包含所有需要的外部库。我想要的只是:在运行时加载库,这样我就可以使用它们,如果它们在类路径中的话。
一些可视化:
-main.jar
-lib.jar
--apache.jar
--someother.jar
---aclass.class
等
一些不太有用的代码:
// loading libraries
ClassLoader contextCL = Thread.currentThread().getContextClassLoader();
ArrayList<URL> librariesJarsURL = new ArrayList<>();
JarFile libJar = new JarFile(libBundle);
Enumeration libJarEnum = libJar.entries();
while (libJarEnum.hasMoreElements()) {
JarEntry libJarEntry = (JarEntry) libJarEnum.nextElement();
if (!libJarEntry.isDirectory() && libJarEntry.getName().endsWith(".jar")) {
librariesJarsURL.add(new URL("jar:file://" + (libBundle.getAbsolutePath().replace("\\", "/")) + "!/" + libJarEntry.getName()));
}
}
if (librariesJarsURL.size() > 0) {
for (URL libraryJarURL : librariesJarsURL) {
System.out.println(libraryJarURL);
}
ClassLoader urlCL = URLClassLoader.newInstance(librariesJarsURL.toArray(new URL[0]), contextCL);
Thread.currentThread().setContextClassLoader(urlCL);
}
System.out.println(StringUtils.difference("zero", "zero141"));
最后一个来自Commons Apache String utils,它也应该被包含在内但是aint给我NoClassDefFoundError和ClassNotFoundException。
另外,我试图使用“反射黑客”,但它也不起作用。
这就是问题,伙计......有什么想法吗?
编辑:libBundle is kinda File object...
UPD:
/*
* Reflection hack :/
*/
public static void addURL(URL url) throws Exception
{
URLClassLoader classLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
Class uclclass = URLClassLoader.class;
// Use reflection
Method method = uclclass.getDeclaredMethod("addURL", new Class[]{URL.class});
method.setAccessible(true);
method.invoke(classLoader, new Object[]{url});
}
使用libBundle.toURI().toURL()
- 相同的错误,
addURL(new URL("jar:file://" + (libBundle.getAbsolutePath().replace("\\", "/")) + "!/"));
- 同样,
试图对lib.jar中的所有罐子做同样的事情 - 同样
尝试URLClassLoader libraryLoader = new URLClassLoader(librariesJarsURL.toArray(new URL[0]), GlobalInit.class.getClassLoader());
- 同样。
答案 0 :(得分:-1)
因此。发现Reference jars inside a jar。
这意味着我不能为这种情况制作自己的类加载器。它有点难过,因为我试过......好吧。我认为答案是:rework ur library building stuff to avoid this
。谢谢,伙计们。