简体   繁体   English

由ClassLoader加载的两个类,它们不能互相调用

[英]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.

相关问题 如何从通过类加载器加载的 class 调用构造函数 - How to call constructor from class loaded via classloader 如何使用classLoader从加载的类中调用方法? - How to call a method from loaded class using classLoader? Java classloader无法在java.lang.Class的类上调用newInstance() - Java classloader Can not call newInstance() on the Class for java.lang.Class 如何在第一次加载时让Java ClassLoader输出每个类 - How do I get Java ClassLoader to output each class when loaded for the first time 为什么我的WebLogic服务器无法找到* .dll,而是已经将其加载到另一个类加载器中呢? - Why can't my WebLogic server find the *.dll, other than whan it is already loaded in another classloader? Nifi ExecuteGroovyScript-已在另一个类加载器中加载的类 - Nifi ExecuteGroovyScript - class already loaded in another classloader 如何用Java中的其他ClassLoader重新加载已加载的类? - How to reload a loaded class with different ClassLoader in Java? 是否所有类的依赖项都由同一个类加载器加载? - Are all dependencies of a class loaded by the same classloader? 如何声明由类加载器加载的 class 创建的 object - How to declare an object created by a class loaded by classloader 重新加载使用自定义类加载器加载的类 - Reload class which is loaded using custom classloader
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM