javaandroidluaj

luaj can't import my app's classes: vm error: java.lang.ClassNotFoundException


when trying to import any class from my application, luaj(3.0-beta2) throws an exception that the class cannot be found, when importing built-in classes, there is no such problem

code run function

public static boolean run(String code){
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            PrintStream printStream = new PrintStream(baos, true, "utf-8");
            Globals globals = JsePlatform.standardGlobals();
            globals.set("logger", CoerceJavaToLua.coerce(new DLogger()));
            globals.set("binder", CoerceJavaToLua.coerce(new EventsBinder()));
            globals.set("entry", CoerceJavaToLua.coerce(new EntryPoints()));
            globals.set("file", CoerceJavaToLua.coerce(new DFile()));
            globals.set("luaj", CoerceJavaToLua.coerce(new LuaRunner()));
            globals.set("firebase", CoerceJavaToLua.coerce(new DFirebase()));
            globals.STDOUT = printStream;
            globals.load(code).call();
            String result =new String(baos.toByteArray());
            if(result != "")
            DLogger.log(result,"Luaj");
            printStream.close();
            return true;
        }catch (Exception e){
            DLogger.log("Luaj error excepted!\n "+e.getMessage(), "LuaRunner");
            return false;
        }

    }

class hierarchy in my application https://i.sstatic.net/9jbwi.png

calling the classBinder() function in my application https://i.sstatic.net/trIQj.png

it doesn't matter that the class is imported as "firebase", I need to take the interface from this class via createProxy, but the problem is the same

UPD:

found the cause of my trouble. the new version of luaj uses a different classloader that does not see the inner classes of my application

quote from the site: In newer versions, if the class is not found in the Java system libraries, LuaJ seems to check the local application directory. Because the Desktop project is a runnable *.jar and contains the actual class files, the desktop version of the game would run correctly in any version of LuaJ. In contrast, Android bundles everything in the classes.dex file, which is not "searchable" in the sense of a file path. Hence ClassNotFoundException.

also i found some solution but it throws a different error:

public class LuajFixer extends LuajavaLib {

    public LuajFixer() {
        super();
    }

    @Override
    protected Class classForName(String name) throws ClassNotFoundException{
            return Class.forName(name, true, Thread.currentThread(). getContextClassLoader());

    }
}

and new jlua runner


public static boolean run(String code){
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            PrintStream printStream = new PrintStream(baos, true, "utf-8");

            Globals globals = JsePlatform.standardGlobals();
            globals.set("logger", CoerceJavaToLua.coerce(new DLogger()));
            globals.set("binder", CoerceJavaToLua.coerce(new EventsBinder()));
            globals.set("entry", CoerceJavaToLua.coerce(new EntryPoints()));
            globals.set("file", CoerceJavaToLua.coerce(new DFile()));
            globals.set("luaj", CoerceJavaToLua.coerce(new LuaRunner()));
            globals.set("firebase", CoerceJavaToLua.coerce(new DFirebase()));
            globals.load(new LuajFixer());
            globals.STDOUT = printStream;

            LoadState.install(globals);
            LuaC.install(globals);
            globals.load(code).call();
            String result =new String(baos.toByteArray());
            if(result != "")
            DLogger.log(result,"Luaj");
            printStream.close();
            return true;
        }catch (Exception e){
            DLogger.log("Luaj error excepted!\n "+e.getMessage(), "LuaRunner");
            return false;
        }

new error screenshot


Solution

  • I had to download the library and add it manually so that I could edit this line. This helped and I no longer need the class fixer:

    LuaJavaLib.java:202

    original return Class.forName(name, true, ClassLoader.getSystemClassLoader());

    change to return Class.forName(name, true, Thread.currentThread(). getContextClassLoader());