2015-10-16 67 views
1

我想在运行时编译Java类。比方说,文件是这样的:javax.tools.JavaCompiler如何捕捉编译错误

public class TestClass 
{ 
    public void foo() 
    { 
     //Made error for complpilation 
     System.ouuuuut.println("Foo"); 
    } 
} 

此文件TestClass.java位于C:\

现在我已经编译此文件中的类:

import javax.tools.JavaCompiler; 
import javax.tools.ToolProvider; 

class CompilerError 
{ 
    public static void main(String[] args) 
    { 
     JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 
     compiler.run(null, null, null, "C:\\TestClass.java"); 
    } 
} 

TestClass.java有不正确的方法名称,所以它不会编译。在控制台它显示:

C:\TestClass.java:7: error: cannot find symbol 
     System.ouuuuut.println("Foo"); 
      ^
    symbol: variable ouuuuut 
    location: class System 
1 error 

这正是我需要的,但我需要它作为字符串。如果我尝试使用try/catch块:

try 
     { 
      JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 
      compiler.run(null, null, null, "C:\\TestClass.java"); 
     } catch (Throwable e){ 
      e.printStackTrace(); //or get it as String 
     } 

这是行不通的,因为通过JavaCompiler不抛出任何异常。它将错误直接打印到控制台中。是否有任何方式获得字符串格式的编译错误?

+1

也许这个问题有答案http://stackoverflow.com/questions/8708342/redirect-console-output -to-string-in-java – Verhagen

+0

谢谢,它的工作原理,我找到了另一种解决方案。 – RichardK

回答

0

最好的解决方案是使用自己的OutputStream,这将被用来代替控制台:

public static void main(String[] args) { 

     /* 
     * We create our own OutputStream, which simply writes error into String 
     */ 

     OutputStream output = new OutputStream() { 
      private StringBuilder sb = new StringBuilder(); 

      @Override 
      public void write(int b) throws IOException { 
       this.sb.append((char) b); 
      } 

      @Override 
      public String toString() { 
       return this.sb.toString(); 
      } 
     }; 

     JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 

     /* 
     * The third argument is OutputStream err, where we use our output object 
     */ 
     compiler.run(null, null, output, "C:\\TestClass.java"); 

     String error = output.toString(); //Compile error get written into String 
    }