-->

动态重新编译和重新加载类(Dynamically recompile and reload a cl

2019-10-21 03:18发布

我建立在Java中,可以接收Java源文件的服务器,它应该使用JavaCompiler进行动态编译它,然后加载类。 但问题是,如果服务器收到名称相同,但不同内容的文件,它仍然会加载前一类,并给出了相同的输出。 我注意到一些答案提示创建类,我试图加载并使用不同的类加载器的超类,但它仍的情况下,如果Java源文件是动态发送到服务器?

这里是我的编译和FileServer.java负载的方法:

public final static int FILE_SIZE = 1022386;

public static void compile(String fileName)
{
// Save source in .java file.
    File sourceFile = new File(fileName);

    // Compile source file.
    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

    DiagnosticCollector <JavaFileObject> diagnostics =
        new DiagnosticCollector<JavaFileObject>();
    StandardJavaFileManager fileManager = 
        compiler.getStandardFileManager(diagnostics, null, null);  
    File [] files = new File [] {sourceFile};
    Iterable<? extends JavaFileObject> compilationUnits =
        fileManager.getJavaFileObjectsFromFiles(Arrays.asList(files));

    String [] compileOptions = new String[] {"-classpath", "runtime.jar"};
    Iterable<String> compilationOptions = Arrays.asList(compileOptions);

    JavaCompiler.CompilationTask task =
        compiler.getTask(null, fileManager, diagnostics, compilationOptions, 
                null, compilationUnits);
    task.call();

}

public static void compileLoad (String fileName)
{
compile(fileName);

    String className = "";
    int i = 0;
    while(fileName.charAt(i) != '.') {
        className += fileName.charAt(i);
        i++;
    }

ClassLoader classLoader = FileServer.class.getClassLoader();
    // Dynamically load class and invoke its main method.
    try {
        //Class<?> cls = Class.forName(className);
    Class<?> cls = classLoader.loadClass(className);
        Method meth = cls.getMethod("main", String[].class);
        String[] params = null;
        meth.invoke(null, (Object) params);
    } catch (Exception e) {
        e.printStackTrace();     
    }
}

Answer 1:

问题是,对于正常的行为ClassLoader.loadClassClass.forName是返回现有的Class ,如果它以前加载。 他们不会看的类文件,看它是否已经改变。

(有一个很好的理由。基本上,在Java对象类型的身份相当于由类完全限定名的元组,它的类加载器。这意味着JVM不能(将不)允许类加载器“定义”两个类具有相同的名称。如果你试图做到这一点,我认为defineClass方法只会给你回Class为先前加载的类的对象。)

所以...

为了达到你想达到什么目的,你需要要加载的类的一个新版本,每次创建一个新的ClassLoader。



文章来源: Dynamically recompile and reload a class