NoSuchMetodError exception while accessing user library

I have a problem with java.lang.NoSuchMethodError. This program is dedicated to the compiler API (JSR 199). When I create a prototype for this, it starts working, but when I try to turn it into a library, it throws a NoSuchMethodError Exception.

Here is the first prototype:

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;
    }
}

I changed DynaCompTest to DynamicCompiler for the library:

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();
    }
}

And I created a second prototype for testing the library:

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());
    }
}

When I test the code above, it works well and prints BUILD SUCCESSFUL, but when I tried to make it a mistake, for example, I removed the semicolon ;as the first prototype, it threw a NoSuchMethodError exception when accessing compiler.getDiagnostics().getDiagnostics()inside the loop.

, , , , Exception?

Edit

:

/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?

:

  • JDK 1.7 Oracle
  • Netbeans 7.1.1
+3
2

, Eclipse Indigo, , jar. Netbeans 7.1.1 , , , jar.

, Netbeans...

...

0

, (jars).

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.

, .

0

All Articles