1

我正在编写一个需要在运行时重新加载以前加载的类的应用程序。原因是该类是在运行时自动生成的,而新的实现改变了应用程序的工作方式。我只生成了该类的一个对象,并且我将它从所有依赖项中剥离了一个定义常量值的接口。重新加载时重置任何或所有成员的值没有问题。我确切地知道它什么时候改变并且我可以控制它。我唯一的问题是重新加载本身。

根据我的阅读,我应该使用 ClassLoader。我试图这样做,但我无法让它工作。

我尝试了以下方法:

  • 获取当前的 ClassLoader ( myClassObject.getClass().getClassLoader()) 并使用它重新加载类 - 不起作用。它可能会继续加载旧的实现。
  • 生成我自己的(也就是从 SO 复制粘贴并进行修改) - 不起作用,因为我生成的 ClassLoader 与生成该类的 ClassLoader 不同(例外:无法将 myClass 强制转换为 myClass)。
  • 创建一个设置超类的 ClassLoader 的构造函数似乎没有任何效果。
  • 使用我的新 ClassLoader 生成以 myClassObject 作为成员的类解决了 myClassObject 的 ClassLoader 不匹配问题,但又创建了一个新的不匹配级别。我getClassLoader()每次都用,我发现它们不匹配。
  • 我尝试添加-Djava.system.class.loader=com.test.Reoader com.test.myMainClass使其成为我的默认重新加载器,但我从编译器中得到一个错误。
  • 谷歌不断将我指向我已经阅读过的相同内容。
  • 编辑:我尝试创建一个接口并重新加载实现它的类。那也没有解决。

我知道我应该覆盖默认的 ClassLoader,但我所做的一切似乎都没有成功。

我的类加载器:

public class Reloader extends ClassLoader {

    public Reloader(){
        super(Reloader.class.getClassLoader());
    }

    @Override
    public Class<?> loadClass(String s) {
        return findClass(s);
    }

    @Override
    public Class<?> findClass(String s) {
        try {
            byte[] bytes = loadClassData(s);
            return defineClass(s, bytes, 0, bytes.length);
        } catch (IOException ioe) {
            try {
                return super.loadClass(s);
            } catch (ClassNotFoundException ignore) {}
            ioe.printStackTrace(java.lang.System.out);
            return null;
        }
    }

    private byte[] loadClassData(String className) throws IOException {
        File f = new File("out\\production\\ManoCPU\\" + className.replaceAll("\\.", "/") + ".class");
        int size = (int) f.length();
        byte buff[] = new byte[size];
        FileInputStream fis = new FileInputStream(f);
        DataInputStream dis = new DataInputStream(fis);
        dis.readFully(buff);
        dis.close();
        return buff;
    }
}

非常感谢任何可以提供帮助的人。

4

1 回答 1

1

您只能加载一次类(每个类加载器实例)。这意味着您必须丢弃已加载类的类加载器,并为更新版本的类实例化一个新的类加载器。

在处理多个类加载器时还要记住,如果你用多个类加载器加载同一个类,它们不会被识别为同一个类。

于 2013-05-17T21:50:26.830 回答