繁体   English   中英

Java动态加载类问题

[英]Java dynamic loading a class issue

我正在尝试编写一个代码,该代码在从字符串创建它之后会编译并运行另一个Java类。

我的问题是我跑步时

    Class classToLoad = null;
    ClassLoader classLoader = Server.class.getClassLoader();
    try {
        classToLoad = classLoader.loadClass(className);
    } catch (Exception e) {
        e.printStackTrace();
    }

它将引发ClassNotFoundException。 我的问题与软件包无关,因为如果我调试代码并将断点放在“ getClassLoader”之前,然后重新加载类,则我的代码运行良好,并且可以看到该应用程序中最近创建的类。

如何在运行时重新加载类,以便loadClass可以工作?

看一下本教程

ClassLoader加载/重新加载示例

...让我们看一个简单的例子。 下面是一个简单的ClassLoader子类的示例。 请注意,它如何将类加载委派给其父级,但打算重新加载的是一个类。 如果此类的加载委托给父类加载器,则以后无法重新加载。 请记住,一个类只能由相同的ClassLoader实例加载一次。

如前所述,这只是一个示例,用于向您展示ClassLoader行为的基础。 它不是您自己的类加载器的生产就绪模板。 您自己的类加载器可能不应仅限于单个类,而应该知道您需要重新加载的类的集合。 另外,您可能也不应该对类路径进行硬编码。

public class MyClassLoader extends ClassLoader{

    public MyClassLoader(ClassLoader parent) {
        super(parent);
    }

    public Class loadClass(String name) throws ClassNotFoundException {
        if(!"reflection.MyObject".equals(name))
                return super.loadClass(name);

        try {
            String url = "file:C:/data/projects/tutorials/web/WEB-INF/" +
                            "classes/reflection/MyObject.class";
            URL myUrl = new URL(url);
            URLConnection connection = myUrl.openConnection();
            InputStream input = connection.getInputStream();
            ByteArrayOutputStream buffer = new ByteArrayOutputStream();
            int data = input.read();

            while(data != -1){
                buffer.write(data);
                data = input.read();
            }

            input.close();

            byte[] classData = buffer.toByteArray();

            return defineClass("reflection.MyObject",
                    classData, 0, classData.length);

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

}

下面是MyClassLoader的示例用法。

public static void main(String[] args) throws
    ClassNotFoundException,
    IllegalAccessException,
    InstantiationException {

    ClassLoader parentClassLoader = MyClassLoader.class.getClassLoader();
    MyClassLoader classLoader = new MyClassLoader(parentClassLoader);
    Class myObjectClass = classLoader.loadClass("reflection.MyObject");

    AnInterface2       object1 =
            (AnInterface2) myObjectClass.newInstance();

    MyObjectSuperClass object2 =
            (MyObjectSuperClass) myObjectClass.newInstance();

    //create new class loader so classes can be reloaded.
    classLoader = new MyClassLoader(parentClassLoader);
    myObjectClass = classLoader.loadClass("reflection.MyObject");

    object1 = (AnInterface2)       myObjectClass.newInstance();
    object2 = (MyObjectSuperClass) myObjectClass.newInstance();

}

可能会问:“您正在加载类的上下文是什么?” 将有助于更好地回答您的问题。

像Spring这样的大多数标准框架都在内部处理加载类,并仅公开那些类提供的方法。

尝试使用Class.forName(String name)尝试加载类并将句柄返回给类对象。

如果要专门使用自己的类加载器加载类,请使用重载的类: Class.forName(字符串名称,布尔值初始化,ClassLoader加载器)

但是您将需要确保您的类加载器能够找到要正确加载的类。

对于您正在使用的类加载器,请尝试: Thread.currentThread()。getContextClassLoader()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM