Java LuaJ和Android:无法绑定类

Java LuaJ和Android:无法绑定类,java,android,eclipse,lua,libgdx,Java,Android,Eclipse,Lua,Libgdx,我目前正在使用LibGDX框架用Java编写一个游戏引擎。几个月来,我已经成功地将LuaJ 3.0与我的引擎一起使用。我在Android(在两台设备上测试)或桌面(在Eclipse内外)上运行脚本都没有问题 然而,当我今天尝试部署到Android时,我得到了以下错误: org.luaj.vm2.LuaError: script:2 vm error: java.lang.ClassNotFoundException: com.javamon.console.ScriptPlayerCreate

我目前正在使用LibGDX框架用Java编写一个游戏引擎。几个月来,我已经成功地将LuaJ 3.0与我的引擎一起使用。我在Android(在两台设备上测试)或桌面(在Eclipse内外)上运行脚本都没有问题

然而,当我今天尝试部署到Android时,我得到了以下错误:

org.luaj.vm2.LuaError: script:2 vm error: java.lang.ClassNotFoundException: com.javamon.console.ScriptPlayerCreate
导致此错误的脚本行是:

Result = luajava.bindClass("com.javamon.console.ScriptPlayerCreate")
这在排版上与Android上所谓的“未找到”类完全相同

如果我尝试绑定一个常规java类,比如
java.lang.ClassNotFoundException
,我不会得到任何错误。但是,无论是从Eclipse内部运行还是通过可运行的*.jar运行,此错误都不会发生在桌面版本上

以下是从LogCat检索到的堆栈跟踪:

org.luaj.vm2.LuaError: script:2 vm error: java.lang.ClassNotFoundException: com.javamon.console.ScriptPlayerCreate
  at org.luaj.vm2.lib.jse.LuajavaLib.invoke(Unknown Source)
  at org.luaj.vm2.lib.VarArgFunction.call(Unknown Source)
  at org.luaj.vm2.LuaClosure.execute(Unknown Source)
  at org.luaj.vm2.LuaClosure.call(Unknown Source)
  at com.javamon.console.Script.runFunction(Script.java:91)
  at com.javamon.console.Script.runFunction(Script.java:96)
  at com.javamon.console.ScriptPlayerCreate.run(ScriptPlayerCreate.java:39)
让我烦恼的是最后一行
ScriptPlayerCreate
当然存在——它正在运行产生错误的脚本

我尝试过的事情:

  • 尝试不同版本的LuaJ
  • com.javamon
    包中绑定不同的类(相同的问题)
  • 更新我的ADT/SDK插件
  • 在Eclipse中清理/重建项目
  • “重新开始”(使用GUI工具创建新的LibGDX项目,并手动导入源文件)
  • 检查
    classes.dex
    --
    ScriptPlayerCreate
    肯定在那里
  • 在单独的Android设备上测试(Moto X和难以置信的2)
我想重申,我已经成功地将LuaJ与Android一起使用了几个月,没有发生任何事件。此外,自从上次(成功)部署Android以来,我还没有更改我的脚本引擎

更新 在尝试恢复到我的应用程序和Eclipse的备份版本后,问题仍然存在——即使是在另一台计算机上我开始怀疑
luajava.bindClass()
不知道如何解释
classes.dex
的内容,而是在搜索实际的类文件

当我尝试重新编译一些备份版本时,我注意到重新编译的版本几乎总是比备份的
classes.dex
文件小。也许Eclipse/Android的编译器出了问题或发生了变化


我试图手动将类文件插入APK中的com/javamon/console/文件夹,但这当然会破坏文件的完整性,即使在重新签名后,应用程序也不会加载。有什么想法吗?

回到LuaJ 2.0.1解决了这个问题

似乎2.0.1以上的所有LuaJ版本都有不同的
LuajavaLib.class
实现。在新的实现中,只有Java系统库可以通过
luajava.bindClass()
访问,而在旧版本中,
bindClass()
也允许访问本地应用程序类。所有其他脚本函数的行为正常仅影响
luajava.bindClass()

在较新版本中,如果在Java系统库中找不到类,LuaJ显然会检查本地应用程序目录。因为桌面项目是一个可运行的*.jar,并且包含实际的
文件,所以桌面版本的游戏在任何版本的LuaJ中都可以正常工作。相比之下,Android将所有内容捆绑在一个
classes.dex
文件中,从文件路径的角度来看,它是不可“搜索”的。因此出现了
ClassNotFoundException

最后:我已经成功地使用LuaJ好几个月了,那么有什么变化呢?显然,几个月前我升级到3.0时,Eclipse从未真正识别出文件更改。只有当我刷新并清理项目时,Eclipse才意识到存在一个新版本的LuaJ。因为LibGDX中的主项目只是源文件(资产位于
-android
),所以您几乎从不单击“刷新”。因此,卢阿杰问题成了某种形式的定时炸弹


我计划向作者提交一份支持票,以便他能够解决这个问题。在他这么做之前,我建议Android开发者继续使用LuaJ 2.0.1

我遇到了类似的问题,我会解决它

java:202

原创的 返回Class.forName(name,true,ClassLoader.getSystemClassLoader())

改为
返回Class.forName(name,true,Thread.currentThread().getContextClassLoader())

您还可以使用类助手修复它

创建包:
org.luaj.vm2.lib.jse
在此包中创建以下类:

package org.luaj.vm2.lib.jse;

public class Helper {
    public static JavaClass forClass(Class c) {
        return JavaClass.forClass(c);
    }

    public Class<JavaClass> huskClass() {
        return JavaClass.class;
    }
}
现在,当您运行脚本时,可以将实例传递给lua脚本:

_globals = JsePlatform.standardGlobals();
_bridge = new LuaBridge();
//...
    _globals.loadfile(scriptName)
            .call(CoerceJavaToLua.coerce(_bridge));
在LUA脚本中:

第一行:

local luaBridge = ...
-- some code here...
UserManager = luaBridge:getClass("com.dexode.cree.ScriptPlayerCreate")
-- used like luajava.bindClass("com.dexode.cree.ScriptPlayerCreate")
local luaBridge = ...
-- some code here...
UserManager = luaBridge:getClass("com.dexode.cree.ScriptPlayerCreate")
-- used like luajava.bindClass("com.dexode.cree.ScriptPlayerCreate")