我有一個使用bouncyCastle jars bcprov-jdk15和bcprov-jdk16兩個版本的項目。 jvm加載舊版本,但是我寫了一個需要更新版本運行的功能。我試圖通過使用自定義類加載器來解決這個類路徑。經過一些谷歌搜索和一些以前的Stackoverflow答案[1][2]和blog,我寫了以下代碼Parent Last Class loader在委託給父類加載器之前從較新的jar加載類。父上次Classloader解決Java Class path hell?
public class ParentLastClassLoader extends ClassLoader {
private String jarFile; //Path to the jar file
private Hashtable classes = new Hashtable(); //used to cache already defined classes
public ParentLastClassLoader(ClassLoader parent, String path)
{
super(parent);
this.jarFile = path;
}
@Override
public Class<?> findClass(String name) throws ClassNotFoundException
{
System.out.println("Trying to find");
throw new ClassNotFoundException();
}
@Override
protected synchronized Class<?> loadClass(String className, boolean resolve) throws ClassNotFoundException
{
System.out.println("Trying to load");
try
{
System.out.println("Loading class in Child : " + className);
byte classByte[];
Class result = null;
//checks in cached classes
result = (Class) classes.get(className);
if (result != null) {
return result;
}
try {
JarFile jar = new JarFile(jarFile);
JarEntry entry = jar.getJarEntry(className + ".class");
InputStream is = jar.getInputStream(entry);
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
int nextValue = is.read();
while (-1 != nextValue) {
byteStream.write(nextValue);
nextValue = is.read();
}
classByte = byteStream.toByteArray();
result = defineClass(className, classByte, 0, classByte.length, null);
classes.put(className, result);
return result;
} catch (Exception e) {
throw new ClassNotFoundException(className + "Not found", e);
}
}
catch(ClassNotFoundException e){
System.out.println("Delegating to parent : " + className);
// didn't find it, try the parent
return super.loadClass(className, resolve);
}
}
}
我裝在要素的主類這一類加載器,但在功能使用的BouncyCaslte類不是由我的自定義類加載器加載。
ClassLoader loader = new ParentLastClassLoader(Thread.currentThread().getContextClassLoader(), pathToJar);
Class myClass = loader.loadClass("MainClassOfTheFeature");
Method mainMethod = myClass.getMethod("MainMethod");
mainMethod.invoke(myClass.getConstructor().newInstance());
Jvm仍然使用它從舊版本加載的類。如何讓JVM在運行該功能時從我的類加載器加載類,並在功能未運行時使用較早的jar中已加載的舊類?
編輯: 的問題仍然存在,甚至設置自定義類加載器的功能主要類的MainMethod線程上下文ClassLoader之後。
Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
我還沒有完全理解它是如何工作的或者它爲什麼需要,但這是目前我能夠自動鏈接我的jar中的其他類的唯一方法。 – Benjoyo