2

Javaソースファイルを受信できるJavaでサーバーを構築しています.JavaCompilerを使用して動的にコンパイルし、クラスをロードする必要があります。ただし、問題は、サーバーが同じ名前で内容が異なるファイルを受信した場合でも、以前のクラスをロードして同じ出力を与えることです。ロードしようとしているクラスのスーパークラスを作成し、別の classLoader を使用することを示唆するいくつかの回答に気付きましたが、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();     
    }
}
4

1 に答える 1

1

問題は、以前にロードされた場合、 ClassLoader.loadClassorの通常の動作はClass.forName既存のものを返すことです。Classクラス ファイルが変更されているかどうかを確認するためにクラス ファイルを確認することはありません。

(これには十分な理由があります。基本的に、Java でのオブジェクト型の ID は、クラスの完全修飾名とそのクラス ローダーで構成されるタプルと同等です。これは、JVM が許可できない (許可しない) ことを意味します。同じ名前の 2 つのクラスを "定義" するクラスローダー. これを実現しようとすると、メソッドは以前にロードされたクラスのオブジェクトをdefineClass返すだけだと思います.)Class

そう ...

達成しようとしていることを達成するには、新しいバージョンのクラスをロードするたびに新しい ClassLoader を作成する必要があります。

于 2014-10-10T03:20:10.150 に答える