以下简单示例失败:
--> thingy.lua function doThing() print( "Thing has been done." ); end
和
--> test.lua require( "thingy" );
当thingy.lua被执行时,没有问题.执行test.lua时,我看到以下错误:
script:2 module 'thingy' not found: thingy no field package.preload['thingy'] thingy.lua no class 'thingy'
这两个文件都存在于同一目录中,我可以使用SciTE(运行Lua 5.1)运行这两个脚本而不会出错.这似乎是一个路径问题,所以我尝试将package.path设置为源文件的绝对路径.
注意:我设置路径,而不是附加,以便我可以确定SciTE没有成功,因为现有的相对路径“?.lua”.
我在LauJ(使用我自己的程序)和SciTE中进行了测试,发现SciTE能够执行test.lua,而LuaJ仍然无法执行,并且一如既往地产生相同的错误.
我应该在Java代码中做些什么(或者不做)可能导致这种情况?我已成功从Lua脚本访问Java,而不是其他Lua脚本.只要我手动运行包含它们的脚本,我就可以访问LuaJ中的全局变量和函数.
好的方法是,这是我用来执行脚本的Java代码.
// some fancy Java code public void execute() throws ScriptException, LuaError { try { FileReader reader = new FileReader( filename ); Script_Engine.eval( reader ); reader.close(); } catch( FileNotFoundException fnfe ) { fnfe.printStackTrace(); } catch( IOException ioe ) { ioe.printStackTrace(); } } public void callFunction( String functionName, Object[] args ) throws Exception { File scriptFile = new File( filename ); FileReader reader = new FileReader( scriptFile ); CompiledScript script = ((Compilable)Script_Engine).compile( reader ); script.eval( Script_Bindings ); LuaFunction lua_function = (LuaFunction)Script_Bindings.get( functionName ); LuaValue[] vals = new LuaValue[args.length]; for( int i = 0; i < args.length; i++ ) { vals[i] = CoerceJavaToLua.coerce( args[i] ); } lua_function.invoke( vals ); reader.close(); }
两个函数中使用的’filename’变量是在外壳类的构造函数中创建的.
更新:
我发现,无论问题是什么,它都存在于LuaJ 3.0版本中(我使用的是JSE包).用旧的2.03 JAR替换3.0-alpha2 JAR文件后,问题就不复存在了.虽然我很满意我现在可以继续使用旧版本的LuaJ,但我仍然希望使用最新版本.
在LuaJ自述文件中找到了一些内容,其中包含以下内容:
When require() is called, it will first attempt to load the module as a Java class that implements LuaFunction.
并在发行说明部分下:
3.0-alpha2
Supply environment as second argument to LibFunction when loading via require()
我强烈怀疑它与此有关,因为它是在3.0-alpha2版本中添加的,所以我下载了版本3.0-alpha1(使用3.0-alpha2),期待它能够正常工作,但事实并非如此.
在与LuaJ的创建者进行了一些对话之后,我们确定问题来自于从版本3.0-alpha1开始的更改,其中在通过require加载脚本时忽略了lua的package.path.这意味着require只会查看路径“.”搜索脚本时如果存在从子目录调用的脚本,则将其称为“place”,然后require可以通过使用点运算符加载它们来查找这些脚本:require( "place.thingy" );
我怀疑,原因是这个package.path问题的问题在社区中有些缺乏,因为有一种方法可以设置从以前版本的LuaJ v3.0开始工作的Java端路径. (一旦我弄清楚了,我会在正确的方法上发布更新,因为我仍然不清楚这个过程.)
整个情况的长短不一,应该很快就会有一个LuaJ v3.0-alpha3,它允许从lua设置package.path.
再次感谢Jim Roseborough与我合作解决问题.
Jim Roseborough的注释:正如Nathan所提到的,这确实是luaj-3.0-alpha2中的一个错误.这已经修复,应该在luaj-3.0-beta1及更高版本中按预期工作,现在可用.