解析javac编译错误
Parse javac compilation errors
我四处寻找了很多,但似乎找不到用于解析 javac 编译错误的现有库。我正在考虑自己实施一个 "javac error parser",但我可以预见它可能不会是直截了当的(需要考虑很多方面)。
我没有使用 ant 进行构建(这有很多原因),但我可以像这样收集 javac 的输出:
Something.java:1: error: Something is not abstract and does not override abstract method foo(boolean) in InterfaceSomething
public class Something implements InterfaceSomething{
^
Something.java:49: error: incompatible types: int cannot be converted to Something[]
return baz;
^
Something.java:55: error: incompatible types: int cannot be converted to Something[]
return baz;
^
Note: Something.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
3 errors
理想情况下,我想要一个包含 "Errors" 列表的对象。每个 "Error" 都有一个文件名、行号、描述和代码片段。
例如,在这种情况下,错误 0 将保持:
A String filename = "Something.java"
An int lineNum = 1
A String description = "Something is not abstract and....."
A String codeSnippet ="public class Something implements InterfaceSomething{"
在过去尝试解析很多东西后,我意识到这通常是一项相当大的工作,因为总会出现输出略有不同或出乎意料的情况(因此我正在寻找一个库,其中有人花了相当多的时间考虑这些情况,以免我重新发明轮子)。
很奇怪我找不到这个。有什么想法吗?
编辑:重要 - 我没有要求任何人为我做这件事,我完全有能力自己做,我只是想要关于任何已经存在的事情的想法或建议。我不是在寻找包括代码在内的答案,而是可能会建议此输出的格式规则的答案,或者将我定向到一些我无法找到的现有库。
我认为 JavaCompiler
and Diagnostic
类 是您要检查的内容。
这是我早期项目之一的一些代码
public String compile(String source, Object... options) {
String className = getMainClassName(source);
if (className == null) {
throw new WrongSourceStructureException("No public class which implements 'Solution'");
}
javax.tools.JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
if (compiler == null)
throw new BadEnvironmentException("You should specify path to JDK in your JDK_HOME and JAVA_HOME");
Writer err = new StringWriter();
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
List<String> compilerOptions = new ArrayList<String>();
String[] opts = new String[options.length - 1];
System.arraycopy(options, 1, opts, 0, opts.length);
if (options != null) {
compilerOptions.addAll(Arrays.asList(opts));
}
compilerOptions.add("-d");
compilerOptions.add("./tmp/classes/");
JavaFileObject codeSolution = new JavaSourceFromString(className, source);
Iterable<? extends JavaFileObject> units = Arrays.asList(codeSolution);
javax.tools.JavaCompiler.CompilationTask task = compiler.getTask(err, null, diagnostics, compilerOptions, null, units);
boolean success = task.call();
if (!success) {
StringBuilder errorMessages = new StringBuilder();
for (Diagnostic diagnostic : diagnostics.getDiagnostics()) {
errorMessages.append(diagnostic.getMessage(null)).append("\n");
}
throw new NotCompiledException(errorMessages.toString());
}
String aPackage = getPackage(source);
return ".tmp/classes/" + options[0] + aPackage.replace(".", "/") + "/" + className + ".class";
}
还有commons-jci,可能比标准的JavaCompiler更清晰。
我四处寻找了很多,但似乎找不到用于解析 javac 编译错误的现有库。我正在考虑自己实施一个 "javac error parser",但我可以预见它可能不会是直截了当的(需要考虑很多方面)。
我没有使用 ant 进行构建(这有很多原因),但我可以像这样收集 javac 的输出:
Something.java:1: error: Something is not abstract and does not override abstract method foo(boolean) in InterfaceSomething
public class Something implements InterfaceSomething{
^
Something.java:49: error: incompatible types: int cannot be converted to Something[]
return baz;
^
Something.java:55: error: incompatible types: int cannot be converted to Something[]
return baz;
^
Note: Something.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
3 errors
理想情况下,我想要一个包含 "Errors" 列表的对象。每个 "Error" 都有一个文件名、行号、描述和代码片段。
例如,在这种情况下,错误 0 将保持:
A String filename = "Something.java"
An int lineNum = 1
A String description = "Something is not abstract and....."
A String codeSnippet ="public class Something implements InterfaceSomething{"
在过去尝试解析很多东西后,我意识到这通常是一项相当大的工作,因为总会出现输出略有不同或出乎意料的情况(因此我正在寻找一个库,其中有人花了相当多的时间考虑这些情况,以免我重新发明轮子)。
很奇怪我找不到这个。有什么想法吗?
编辑:重要 - 我没有要求任何人为我做这件事,我完全有能力自己做,我只是想要关于任何已经存在的事情的想法或建议。我不是在寻找包括代码在内的答案,而是可能会建议此输出的格式规则的答案,或者将我定向到一些我无法找到的现有库。
我认为 JavaCompiler
and Diagnostic
类 是您要检查的内容。
这是我早期项目之一的一些代码
public String compile(String source, Object... options) {
String className = getMainClassName(source);
if (className == null) {
throw new WrongSourceStructureException("No public class which implements 'Solution'");
}
javax.tools.JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
if (compiler == null)
throw new BadEnvironmentException("You should specify path to JDK in your JDK_HOME and JAVA_HOME");
Writer err = new StringWriter();
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
List<String> compilerOptions = new ArrayList<String>();
String[] opts = new String[options.length - 1];
System.arraycopy(options, 1, opts, 0, opts.length);
if (options != null) {
compilerOptions.addAll(Arrays.asList(opts));
}
compilerOptions.add("-d");
compilerOptions.add("./tmp/classes/");
JavaFileObject codeSolution = new JavaSourceFromString(className, source);
Iterable<? extends JavaFileObject> units = Arrays.asList(codeSolution);
javax.tools.JavaCompiler.CompilationTask task = compiler.getTask(err, null, diagnostics, compilerOptions, null, units);
boolean success = task.call();
if (!success) {
StringBuilder errorMessages = new StringBuilder();
for (Diagnostic diagnostic : diagnostics.getDiagnostics()) {
errorMessages.append(diagnostic.getMessage(null)).append("\n");
}
throw new NotCompiledException(errorMessages.toString());
}
String aPackage = getPackage(source);
return ".tmp/classes/" + options[0] + aPackage.replace(".", "/") + "/" + className + ".class";
}
还有commons-jci,可能比标准的JavaCompiler更清晰。