2015-10-16 90 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 
    }