LuaJ和Android:无法绑定类。
我正在使用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和Incredible 2)
我想重申,我已经成功使用LuaJ和Android进行开发_几个月_而没有事故。此外,自我上一次(成功)Android部署以来,我没有更改我的脚本引擎。
更新
尝试回到我的应用和Eclipse的备份版本后,问题仍然存在-_甚至在另一台计算机上也是如此。我开始怀疑luajava.bindClass()不知道如何解释classes.dex的内容,而是在搜索实际的类文件。
当我试图重新编译一些备份版本时,我注意到重新编译的版本几乎总是具有比备份更小的classes.dex文件。也许Eclipse/Android的编译器出了问题或发生了变化?
我尝试手动将类文件插入APK内的com/javamon/console/文件夹中,但当然会破坏文件完整性,并且即使重新签名应用程序也无法加载。有什么想法?
我遇到了类似的问题,我处理了它:
在 LuaJavaLib.java 的第 202 行:
原始代码:
return Class.forName(name, true, **ClassLoader.getSystemClassLoader**());
修改后代码:
return Class.forName(name, true, **Thread.currentThread().getContextClassLoader**());
你可以使用自己的 Helper 类来修复它。
创建包: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;
}
}
然后创建类似桥接的类:
public class LuaBridge {
public Varargs getClass(String clazzName) {
try {
Class clazz = Class.forName(clazzName);
return Helper.forClass(clazz);
} catch (Exception e) {
e.printStackTrace();
Crashlytics.logException(e);
}
return null;
}
}
现在当你运行你的脚本时,你可以把实例传给你的 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")
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
将下面翻译成中文并且保留原本的 markdown 格式:
回退到LuaJ 2.0.1解决了这个问题。
似乎所有2.0.1以上版本的LuaJ都对
LuajavaLib.class有不同的实现。在新的实现中,只有Java系统库可以通过luajava.bindClass()进行访问,而在旧版本中,bindClass()允许访问本地应用程序类。所有其他脚本函数的行为都正常;只有luajava.bindClass()受到影响。在更新的版本中,如果Java系统库中找不到类,LuaJ似乎会检查本地应用程序目录。由于Desktop项目是一个可运行的* .jar文件,并包含实际的“class”文件,因此桌面版本的游戏在任何版本的LuaJ中都会正常工作。相反,Android将所有文件打包在一个
classes.dex文件中,该文件在文件路径上不可“搜索”。因此出现了“ClassNotFoundException”。最后:我已经成功使用LuaJ几个月了,发生了什么变化?几个月前升级到3.0时,Eclipse实际上从未识别文件更改。只有当我刷新并清理项目时,Eclipse才意识到新版本的LuaJ存在。因为LibGDX中的主要项目仅为源文件(资源位于“-android”中),您几乎永远不会点击“刷新”。因此,LuaJ问题就像是一个定时炸弹。
我计划向作者提交支持票,以便他可以解决这个问题。在他这样做之前,我建议Android开发人员继续使用LuaJ 2.0.1!