2017-02-01 4 views
0

J'ai une application JavaFX où il y a un éditeur. Dans l'éditeur, l'utilisateur pourra écrire du code Java et j'ai un bouton pour compiler ce code et lancer la méthode principale. Par exemple, l'éditeur contiendra ce code:Le compilateur d'exécution Java utilisant les réflexions ne fonctionne pas correctement

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

Le bouton clic, exécutera ce code:

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

    }); 

Dans la classe du compilateur, il y a la mise en œuvre suivante:

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(); 
    } 

} 


} 

Maintenant, le code ci-dessus crée avec succès le fichier java, le fichier de classe et s'exécute correctement la première fois. Maintenant, lorsque je change le code de l'éditeur pour imprimer quelque chose d'autre, il affiche le résultat de la première exécution du code. Donc, dans ce cas, il affichera toujours 'bonjour' au lieu de sa valeur actuelle.

Un problème est peut-être survenu? Merci!

Répondre

0

Vous devez créer un nouveau classloader pour la nouvelle classe. La classe n'est pas rechargée juste parce que vous l'avez compilée.

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

Ensuite, vous pouvez demander à ce chargeur pour la classe:

Class<?> cls = Class.forName(className, true, classLoader);