Компиляция Java с Янино (сломанный путь к классам)
Я пытаюсь скомпилировать очень простой класс с Янино:
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());
}
}
Здесь все отлично работает, но org.codehaus.janino.ClassBodyEvaluator
у компилятора есть ограничение для Java 5. Поэтому я прочитал на сайте Janino, что вы можете изменить компилятор, чтобы преодолеть это ограничение
JANINO можно настроить на использование javax.tools.JavaCompiler, то есть JAVAC, который снимает ограничения, связанные с Java 5.
Итак, я изменился ClassBodyEvaluator
на этом org.codehaus.commons.compiler.jdk.ClassBodyEvaluator;
который также доступен на веб-сайте Janino, и AFAIK не имеет ограничений по Java 5.
Но, к сожалению, он генерирует следующую трассировку стека:
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
Вероятно, это как-то связано с classpath компилятора, но я не вижу в API какого-либо метода, каким-либо образом манипулирующего им.
Буду благодарен за любые предложения
1 ответ
Работает на меня.
<dependency>
<groupId>org.codehaus.janino</groupId>
<artifactId>janino</artifactId>
<version>3.1.6</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>