2017-02-01 8 views
0

エディタがあるJavaFXアプリケーションがあります。エディタでは、ユーザーはJavaコードを記述することができ、このコードをコンパイルしてmainメソッドを実行するボタンがあります。たとえば、エディタは、このコードが含まれます。Javaランタイムコンパイラが正しく動作しない反射を使用する

public class Test { 
    public static void main(String[] args) { 
     System.out.println("hello"); 
    } 
} 

クリック上のボタンを、このコードを実行します:コンパイラのクラスでは

runButton.setOnAction(e -> { 
     compiler.set(editor.getText()); 
     try { 
      compiler.createFile(); 
     } catch (IOException e1) { 
      e1.printStackTrace(); 
     } 
     compiler.compile(); 
     compiler.run(); 

    }); 

を、次の実装があります:

public class CodeCompiler { 

public String className; 
public String code; 

public void set(String code) { 
    try { 
     this.className = code.substring(code.indexOf(" class ") + 6, code.indexOf(" {")).trim(); 
    } catch(StringIndexOutOfBoundsException e) { 

    } 
    this.code = code; 
} 

public void createFile() throws IOException { 
    PrintWriter pw = new PrintWriter("speech2code/src/main/java/" + className + ".java"); 
    pw.close(); 
    FileWriter writer = new FileWriter("speech2code/src/main/java/" + className + ".java", true); 
    writer.write(code); 
    writer.flush(); 
    writer.close(); 
} 

public void compile() { 
    File file = new File("speech2code/src/main/java/" + className + ".java"); 
    File classFile = new File("speech2code/src/main/java/" + className + ".class"); 
    classFile.delete(); // delete class file f it exists 
    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 
    compiler.run(null, null, null, file.getPath()); 
} 

public void run() { 

    Class<?> cls = null; 
    try { 
     cls = Class.forName(className); 
     System.out.println(cls == null); 
    } catch (ClassNotFoundException e) { 
     e.printStackTrace(); 
    } 
    Method meth = null; 
    try { 
     meth = cls.getMethod("main", String[].class); 
    } catch (NoSuchMethodException e) { 
     e.printStackTrace(); 
    } 
    String[] params = null; 
    try { 
     meth.invoke(null, (Object) params); 
    } catch (IllegalAccessException e) { 
     e.printStackTrace(); 
    } catch (InvocationTargetException e) { 
     e.printStackTrace(); 
    } 

} 


} 

上記のコードは、Javaファイル、クラスファイルを正常に作成し、初めて正しく実行します。ここでエディタコードを変更して何か他のものを印刷すると、コードが最初に実行されたときの結果が出力されます。したがって、この場合、現在の値ではなく、 'hello'が表示されます。

何が問題なのでしょうか? ありがとう!

答えて

0

新しいクラスの新しいクラスローダーを作成する必要があります。あなたがそれをコンパイルしたからといって、クラスはリロードされません。

URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] {classFile}); 

その後は、クラスに対して、このローダーを依頼することができます。

Class<?> cls = Class.forName(className, true, classLoader); 
関連する問題