Compiling java with Janino (broken Classpath)

I am trying to compile a very simple class using Janino:

import org.codehaus.commons.compiler.CompileException;
import org.codehaus.janino.ClassBodyEvaluator;

import java.io.IOException;
import java.io.StringReader;

public class JaninoTest{

    public static void main(String[] args) throws IOException, CompileException {

        String sampleClass =
                "public class Test {" +
                    "public void sampleMethod() {\n" +
                    "        JsonObject obj = new JsonObject();\n" +
                    "        obj.add(\"p1\", new JsonPrimitive(2));\n" +
                    "        System.out.println(obj.get(\"p1\"));\n" +
                    "}" +
                "}";

        ClassBodyEvaluator classBodyEvaluator = new ClassBodyEvaluator();
        classBodyEvaluator.setParentClassLoader(Thread.currentThread().getContextClassLoader());
        classBodyEvaluator.setDefaultImports(new String[] {  "com.google.gson.JsonObject",
                "com.google.gson.JsonPrimitive"});
        StringReader sr = new StringReader(sampleClass);
        classBodyEvaluator.cook(null, sr);
        Class<?> clazz = classBodyEvaluator.getClazz();
        System.out.println(clazz.getName());

    }


}

Everything works fine here, but the compiler org.codehaus.janino.ClassBodyEvaluatorhas a limit on Java 5. Therefore, I read on the Janino website that you can change the compiler to overcome this restriction

JANINO can be configured to use javax.tools.JavaCompiler, that is, JAVAC, which removes the limitations associated with Java 5.

So, I changed ClassBodyEvaluatorto this one org.codehaus.commons.compiler.jdk.ClassBodyEvaluator;, which is also available on the Janino website, and AFAIK has no Java 5 restriction.

But unfortunately, it produces the following stack trace:

Exception in thread "main" java.lang.NoClassDefFoundError: com/sun/tools/javac/main/Main$Result
    at com.sun.tools.javac.main.Main.compile(Main.java:581)
    at com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:129)
    at com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:138)
    at org.codehaus.commons.compiler.jdk.SimpleCompiler.cook(SimpleCompiler.java:128)
    at org.codehaus.commons.compiler.jdk.ClassBodyEvaluator.cook(ClassBodyEvaluator.java:197)
    at org.codehaus.commons.compiler.jdk.ClassBodyEvaluator.cook(ClassBodyEvaluator.java:108)
    at JaninoTest.main(JaninoTest.java:28)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: java.lang.ClassNotFoundException: com.sun.tools.javac.main.Main$Result
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 12 more 

This probably has to do with the compiler path, but I don't see any method in the API to somehow manipulate it.

+4

Source: https://habr.com/ru/post/1624124/


All Articles