2013-08-09 3 views
3

Я пытаюсь использовать пример кода, который использует javax.tools для компиляции кода, который находится в строке. Класс.forName приводит к исключению ClassNotFoundException. Кто-нибудь знает, почему? Я использую Java 7.Компиляция кода Java из строки приводит к ClassNotFoundException

 import java.io.IOException; 
     import java.io.PrintWriter; 
     import java.io.StringWriter; 
     import java.lang.reflect.InvocationTargetException; 
     import java.net.URI; 
     import java.util.ArrayList; 
     import java.util.Arrays; 
     import java.util.List; 

     import javax.tools.Diagnostic; 
     import javax.tools.DiagnosticCollector; 
     import javax.tools.JavaCompiler; 
     import javax.tools.JavaFileObject; 
     import javax.tools.SimpleJavaFileObject; 
     import javax.tools.ToolProvider; 
     import javax.tools.JavaCompiler.CompilationTask; 


     public class Main { 
      public static void main(String args[]) throws IOException { 
       JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 
       DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>(); 

       StringWriter writer = new StringWriter(); 
       PrintWriter out = new PrintWriter(writer); 
       out.println("public class HelloWorld {"); 
       out.println(" public static void main(String args[]) {"); 
       out.println(" System.out.println(\"This is in another java file\");"); 
       out.println(" }"); 
       out.println("}"); 
       out.close(); 
       JavaFileObject file = new JavaSourceFromString("HelloWorld", writer.toString()); 

       Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(file); 
       CompilationTask task = compiler.getTask(null, null, diagnostics, optionList, null, compilationUnits); 

       boolean success = task.call(); 
       for (Diagnostic diagnostic : diagnostics.getDiagnostics()) { 
        System.out.println(diagnostic.getCode()); 
        System.out.println(diagnostic.getKind()); 
        System.out.println(diagnostic.getPosition()); 
        System.out.println(diagnostic.getStartPosition()); 
        System.out.println(diagnostic.getEndPosition()); 
        System.out.println(diagnostic.getSource()); 
        System.out.println(diagnostic.getMessage(null)); 

       } 
       System.out.println("Success: " + success); 

       if (success) { 
        try { 
         Class.forName("HelloWorld").getDeclaredMethod("main", new Class[] { String[].class }) 
           .invoke(null, new Object[] { null }); 
        } catch (ClassNotFoundException e) { 
         System.err.println("Class not found: " + e); 
        } catch (NoSuchMethodException e) { 
         System.err.println("No such method: " + e); 
        } catch (IllegalAccessException e) { 
         System.err.println("Illegal access: " + e); 
        } catch (InvocationTargetException e) { 
         System.err.println("Invocation target: " + e); 
        } 
       } 
      } 
     } 

     class JavaSourceFromString extends SimpleJavaFileObject { 
      final String code; 

      JavaSourceFromString(String name, String code) { 
       super(URI.create("string:///" + name.replace('.','/') + Kind.SOURCE.extension), Kind.SOURCE); 
       this.code = code;                
      } 

      @Override 
      public CharSequence getCharContent(boolean ignoreEncodingErrors) { 
       return code; 
      } 
     } 
+0

Это означает только одно: класс HelloWorld не находится в пути к классам. – rocketboy

ответ

0

загрузчик классы не имеет ни малейшего представления о вашем HelloWorld класса. Вы можете сделать это:

URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { root.toURI().toURL() }); //root is path to class file 
Class<?> cls = Class.forName("HelloWorld", true, classLoader); 

Вы можете увидеть a full example here.

+1

Результирующий класс не должен сохраняться на диске. Кажется, что вот решение, которое я ищу: http://www.javablogging.com/dynamic-in-memory-compilation – Jochen