我对java.lang.NoSuchMethodError有问题。该程序与Compiler API(JSR 199)有关。当我为此创建一个原型时,它可以运行,但是当我尝试使其成为库时,它将引发NoSuchMethodError Exception。
这是第一个原型:
public class DynaCompTest {
public static void main(String[] args) {
String fullName = "HelloWorld";
StringBuilder sourceCode = new StringBuilder();
sourceCode.append("public class HelloWorld {\n")
.append("\tpublic static void main(String[] args) {\n")
.append("\t\tSystem.out.println(\"Hello World\")\n")
.append("\t}\n")
.append("}");
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
JavaFileManager fileManager = new ClassFileManager(compiler.getStandardFileManager(null, null, null));
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
List<JavaFileObject> jFiles = new ArrayList<>();
jFiles.add(new CharSequenceJavaFileObject(fullName, sourceCode));
compiler.getTask(null, fileManager, diagnostics, null, null, jFiles).call();
for (Diagnostic diagnostic : diagnostics.getDiagnostics()) {
System.out.format("Error on line %d in %s\n", diagnostic.getLineNumber(), diagnostic);
}
}
}
public class CharSequenceJavaFileObject extends SimpleJavaFileObject {
private CharSequence content;
public CharSequenceJavaFileObject(String className, CharSequence content) {
super(URI.create("string:///" + className.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);
this.content = content;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return content;
}
}
public class ClassFileManager extends ForwardingJavaFileManager {
private JavaClassObject jClassObject;
public ClassFileManager(StandardJavaFileManager standardManager) {
super(standardManager);
}
@Override
public ClassLoader getClassLoader(Location location) {
return new SecureClassLoader() {
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
byte[] b = jClassObject.getBytes();
return super.defineClass(name, jClassObject.getBytes(), 0, b.length);
}
};
}
@Override
public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling) throws IOException {
jClassObject = new JavaClassObject(className, kind);
return jClassObject;
}
}
public class JavaClassObject extends SimpleJavaFileObject {
protected final ByteArrayOutputStream bos = new ByteArrayOutputStream();
public JavaClassObject(String name, Kind kind) {
super(URI.create("string:///" + name.replace('.', '/') + kind.extension), kind);
}
public byte[] getBytes() {
return bos.toByteArray();
}
@Override
public OutputStream openOutputStream() {
return bos;
}
}
我将DynaCompTest更改为该库的DynamicCompiler:
public class DynamicCompiler {
private JavaCompiler compiler;
private JavaFileManager fileManager;
private List<JavaFileObject> jFiles;
private DiagnosticCollector<JavaFileObject> diagnostics;
public DiagnosticCollector<JavaFileObject> getDiagnostics() {
return diagnostics;
}
public DynamicCompiler(String className, StringBuilder sourceCode) {
compiler = ToolProvider.getSystemJavaCompiler();
fileManager = new ClassFileManager(compiler.getStandardFileManager(null, null, null));
diagnostics = new DiagnosticCollector<>();
jFiles = new ArrayList<>();
jFiles.add(new CharSequenceJavaFileObject(className, sourceCode));
}
public boolean doCompilation() {
return compiler.getTask(null, fileManager, diagnostics, null, null, jFiles).call();
}
}
我创建了Second Prototype来测试库:
public class Compiler {
private static StringBuilder sourceCode = new StringBuilder();
public static void main(String[] args) {
boolean status;
sourceCode.append("public class HelloWorld {\n")
.append("\tpublic static void main(String[] args) {\n")
.append("\t\tSystem.out.println(\"Hello World\");\n")
.append("\t}\n")
.append("}");
DynamicCompiler compiler = new DynamicCompiler("HelloWorld", sourceCode);
status = compiler.doCompilation();
StringBuilder messages = new StringBuilder();
if (!status) {
for (Diagnostic diagnostic : compiler.getDiagnostics().getDiagnostics()) {
messages.append("Error on line ")
.append(diagnostic.getLineNumber())
.append(" in ")
.append(diagnostic)
.append("\n");
}
} else {
messages.append("BUILD SUCCESSFUL ");
}
System.out.println(messages.toString());
}
}
当我使用上面的代码进行测试时,它可以很好地运行并打印BUILD SUCCESSFUL
,但是当我尝试使其出错时,例如像第一个原型一样,我删除了分号;
,则在循环内访问compiler.getDiagnostics().getDiagnostics()
时会抛出NoSuchMethodError Exception 。
问题是,为什么在尝试生成错误时在“第一原型”中运行良好,但是当我尝试使用自己的库时却变为异常?
编辑
这是堆栈跟踪:
/HelloWorld.java:3: error: ';' expected
System.out.println("Hello World")
^
1 error
Exception in thread "main" java.lang.NoSuchMethodError: org.ert.lib.DynamicCompiler.getDiagnostics()Ljavax/tools/DiagnosticCollector;
at org.ert.exp.Compiler.main(Compiler.java:28)
Java Result: 1
应该是这样的:
Error on line 3 in /HelloWorld.java:3: error: ';' expected
System.out.println("Hello World")
^
尝试调试时,显示错误:
public DiagnosticCollector<JavaFileObject> getDiagnostics() {
return diagnostics; // Set Breakpoint here
}
这是错误消息:
Not able to submit breakpoint LineBreakpoint DynamicCompiler.java : 25, reason: No executable location available at line 25 in class org.ert.lib.DynamicCompiler.
Invalid LineBreakpoint DynamicCompiler.java : 25
更新资料
遇到问题了,如果我们添加整个项目而不是构建库的jar,就会出现此问题。因此,当我构建库jar时,它可以工作。但是任何人都可以解释为什么当我尝试添加整个项目而不是jar文件时为什么会发生这种情况?
注意
我正在使用:
来自Oracle的JDK 1.7
Netbeans 7.1.1
java大神给出的解决方案
看来您在两个不同的库(罐)中存在相似的类。
例如
com.test.Example.class in a.jar
com.test.Example.class in b.jar
现在,类加载器将加载第一个Example.class,似乎您需要b.jar中存在的类。然后它将不会引发诸如NoMethodFound之类的异常,而是会引发NoSuchMethodFound的异常,因为类仍存在于内存中,但找不到所需的方法。
这些问题可以通过更改库顺序来解决。您需要提高所需库的顺序。你可以从日食中做到这一点
Project Setting -> Java Build Path -> Order and Export.
希望这会有所帮助。
当回复有时是一个对象有时是一个数组时,如何在使用改造时解析JSON回复? - java我正在使用Retrofit来获取JSON答复。这是我实施的一部分-@GET("/api/report/list") Observable<Bills> listBill(@Query("employee_id") String employeeID); 而条例草案类是-public static class…
java:继承 - java有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…
Java-如何将此字符串转换为日期? - java我从服务器收到此消息,我不明白T和Z的含义,2012-08-24T09:59:59Z将此字符串转换为Date对象的正确SimpleDateFormat模式是什么? java大神给出的解决方案 这是ISO 8601标准。您可以使用SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy-MM…
java.net.URI.create异常 - javajava.net.URI.create("http://adserver.adtech.de/adlink|3.0") 抛出java.net.URISyntaxException: Illegal character in path at index 32: http://adserver.adtech.de/adlink|3.0 虽然n…
从方法返回数组-Java - javaprivate static Coordinate[] getCircleCoordintaes() { Coordinate coordinates[] = {new Coordinate(0, 0)}; return coordinates; } 以上程序工作正常。在上面的程序中,返回的坐标数组首先初始化了数组使用这条线Coordinate coordi…