Java LuaJ和Android:无法绑定类
我目前正在使用LibGDX框架用Java编写一个游戏引擎。几个月来,我已经成功地将LuaJ 3.0与我的引擎一起使用。我在Android(在两台设备上测试)或桌面(在Eclipse内外)上运行脚本都没有问题 然而,当我今天尝试部署到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
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)
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")