Can janino work on Android ?
StaticCoder opened this issue · 1 comments
I ran some demo code,but get the same error :
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.myapplication2/com.example.myapplication2.MainActivity}: java.lang.UnsupportedOperationException: can't load this type of class file at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4152) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4339) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:91) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:149) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:103) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2681) at android.os.Handler.dispatchMessage(Handler.java:110) at android.os.Looper.loop(Looper.java:219) at android.app.ActivityThread.main(ActivityThread.java:8788) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1116) Caused by: java.lang.UnsupportedOperationException: can't load this type of class file at java.lang.ClassLoader.defineClass(ClassLoader.java:591) at org.codehaus.commons.compiler.util.reflect.ByteArrayClassLoader.findClass(ByteArrayClassLoader.java:95) at java.lang.ClassLoader.loadClass(ClassLoader.java:379) at java.lang.ClassLoader.loadClass(ClassLoader.java:312) at org.codehaus.janino.ClassBodyEvaluator.cook(ClassBodyEvaluator.java:299) at org.codehaus.janino.ScriptEvaluator.cook(ScriptEvaluator.java:861) at org.codehaus.janino.ScriptEvaluator.cook(ScriptEvaluator.java:778) at org.codehaus.janino.ScriptEvaluator.cook(ScriptEvaluator.java:762) at org.codehaus.janino.ExpressionEvaluator.cook(ExpressionEvaluator.java:488) at org.codehaus.janino.ExpressionEvaluator.cook(ExpressionEvaluator.java:443) at org.codehaus.janino.ExpressionEvaluator.cook(ExpressionEvaluator.java:409) at org.codehaus.janino.ExpressionEvaluator.cook(ExpressionEvaluator.java:394) at org.codehaus.commons.compiler.Cookable.cook(Cookable.java:82) at org.codehaus.commons.compiler.Cookable.cook(Cookable.java:77) at com.example.myapplication2.JaninoTest1.fun1(JaninoTest1.java:14) at com.example.myapplication2.MainActivity.onCreate(MainActivity.kt:72) at android.app.Activity.performCreate(Activity.java:8218) at android.app.Activity.performCreate(Activity.java:8206) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1320)
`package com.example.myapplication2;
import org.codehaus.commons.compiler.CompileException;
import org.codehaus.janino.ExpressionEvaluator;
import java.lang.reflect.InvocationTargetException;
public class JaninoTest1 {
public void fun1() throws InvocationTargetException {
try {
ExpressionEvaluator ee = new ExpressionEvaluator();
ee.setParameters(new String[]{"a", "b"}, new Class[]{int.class, int.class});
ee.setExpressionType(int.class);
ee.cook("a + b");
int result = (Integer) ee.evaluate(new Integer[]{8, 9});
System.out.println("result:"+result);
} catch (CompileException e) {
e.printStackTrace();
}
}
}
`
Hey Mr. Static Coder,
I'm not into Android programming, but since Android has its own VM and class file format (DALVIK), it is probably impossible to load "normal" JVM .class files. And Janino generates these and attempts to load them into the VM. The exception message and the stack trace very strongly suggest that.
Summary: On android, Janino can certainly generate .class files, but cannot load them into the VM. Effectively, Janino is of little to no use on Android. Bummer.
But AFAIK, the Android SDK includes a tool that converts JVM .class files into DALVIK .class files - it could be possible that this helper is not only runnable in the development environment, but also on the target Android system!? If so, then it would maybe be possible to translate JVM .class files on-the-fly into DALVIK .class files and then load them.
CU Arno