[英]Two Class Loaded by ClassLoader, They Can Not Call Each Other
Assume you have two java class 假设您有两个java类
package package1;
public class SampleClass1 {
public SampleClass1() {
System.out.println("Sample Class Loaded and Called");
}
}
package package1.package2;
import package1.SampleClass1;
public class SampleClass2 {
public SampleClass2() {
new SampleClass1();
System.out.println("Sample Class 2 Loaded and Called");
}
}
and load two classes by ClassLoader something like that: 并通过ClassLoader加载两个类,如下所示:
package load;
public class LoadClassFromByteData extends ClassLoader {
private byte[] classByteData;
public LoadClassFromByteData(byte[] classByteData) {
this.classByteData = classByteData;
}
public Class<?> getLoadedClass(String className) {
return defineClass(className, classByteData, 0, classByteData.length);
}
}
// //
Class<?> loadedClass1 = loadClassFromByteData.getLoadedClass("package1.SampleClass1");
Class<?> loadedClass2 = loadClassFromByteData.getLoadedClass("package1.package2.SampleClass2");
when i call constructor of SampleClass1 like that: 当我像这样调用SampleClass1的构造函数时:
Constructor<?> mainCons1 = loadedClass1.getConstructor();
mainCons1.newInstance();
successfully, printing "Sample Class Loaded and Called" but when i call constructor of loadedClass2 load from SampleClass2 byte data i have an error like: 成功打印“ Sample Class Loaded and Called”,但是当我从SampleClass2字节数据中调用loadClass2加载的构造函数时,出现如下错误:
Constructor<?> mainCons2 = loadedClass2.getConstructor();
mainCons2.newInstance();
// And yes, first i load SampleClass1 then i load SampleClass2, finally i call SampleClass2 constructor. //是的,首先我加载SampleClass1,然后加载SampleClass2,最后我调用SampleClass2构造函数。
Exception in thread "main" java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
at db.recorder.deneme.main(deneme.java:48)
Caused by: java.lang.NoClassDefFoundError: package1/SampleClass1
at package1.package2.SampleClass2.<init>(SampleClass2.java:9)
... 5 more
Caused by: java.lang.ClassNotFoundException: package1.SampleClass1
at java.base/java.lang.ClassLoader.findClass(ClassLoader.java:718)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 6 more
I want to add this information, two Classes byte data stored in DB, and i get byte data of classes from DB. 我想添加此信息,将两个Class字节数据存储在DB中,然后从DB获取类的字节数据。 Actually, the project has not any package named package1 or package2 ! 实际上,该项目没有任何名为package1或package2的包!
Thanks for your answers and advices. 感谢您的回答和建议。
You need to supply the parent classloader. 您需要提供父类加载器。
public static class LoadClassFromByteData extends ClassLoader {
final ConcurrentHashMap<String, Class<?>> definedClassesByName = new ConcurrentHashMap<>();
LoadClassFromByteData(ClassLoader parent) {
super(parent);
}
public Class<?> getLoadedClass(String className, byte[] classAsBytes) {
return this.definedClassesByName.computeIfAbsent(className,
cn -> defineClass(cn, classAsBytes, 0, classAsBytes.length));
}
}
@Test
public void test() throws IOException, InstantiationException, IllegalAccessException {
final byte[] sampleClass1Bytes = Files.readAllBytes(SAMPLE_CLASS1_CLASS_FILE_PATH);
final byte[] sampleClass2Bytes = Files.readAllBytes(SAMPLE_CLASS2_CLASS_FILE_PATH);
final ClassLoader contextClassLoader = Thread.currentThread()
.getContextClassLoader();
final LoadClassFromByteData loadClassFromByteData = new LoadClassFromByteData(contextClassLoader);
final Class<?> sampleClass1 = loadClassFromByteData.getLoadedClass("package1.SampleClass1", sampleClass1Bytes);
final Object sampleClass1Instance = sampleClass1.newInstance();
final Class<
?> sampleClass2 = loadClassFromByteData.getLoadedClass("package1.package2.SampleClass2", sampleClass2Bytes);
final Object newInstance = sampleClass2.newInstance();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.