2017-02-01 4 views
0

У меня есть приложение JavaFX, где есть редактор. В редакторе пользователь сможет написать Java-код, и у меня есть кнопка для компиляции этого кода и запуска основного метода. Например, редактор будет содержать этот код: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); 
Смежные вопросы