Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LuaJ: Unable to call 'require' function in Lua script

Tags:

lua

luaj

There is a really good chance that I am doing something bizarre that is causing this error.

The following simple example fails:

--> thingy.lua
function doThing()
  print( "Thing has been done." );
end

and

--> test.lua
require( "thingy" );

When thingy.lua is executed, there are no problems. When test.lua is executed, I see the following error:

script:2 module 'thingy' not found: thingy
no field package.preload['thingy']
thingy.lua
no class 'thingy'

Both of these files exist in the same directory, and I can run both scripts with no error using SciTE (which is running Lua 5.1). It seems to be a path issue, so I tried setting package.path to be the absolute path to the source files.

Note: I set the path, rather than appending so that I could make certain that SciTE wasn't succeeding because of the existing relative path "?.lua".

I tested in both LauJ (using my own program) and in SciTE, finding that SciTE is able to execute test.lua, and LuaJ still unable, yielding the same error as always.

Is there something I should be doing (or not doing) in the Java code that might be capable of causing this? I have had success accessing Java from Lua scripts, just not other Lua scripts. I can access global variables and functions in LuaJ as long as I have manually run the scripts that contain them.

Just for good measure, here is the Java code I use to execute a script.

// 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();
}

The 'filename' variable used in both functions is created in the constructor of the housing class.

Update: I have found that, whatever the problem is, it exists in LuaJ version 3.0 (I'm using the JSE package). Having replaced the 3.0-alpha2 JAR file with an older 2.03 JAR, the problem is no more. While I am satisfied that I can now move ahead with the older version of LuaJ, I would still prefer to be using the most updated version.

There is something in the LuaJ Readme found here that says the following:

When require() is called, it will first attempt to load the module as a Java class that implements LuaFunction.

and under the Release Notes section:

3.0-alpha2
Supply environment as second argument to LibFunction when loading via require()

I was strongly suspecting that it has something to do with this since it was added in version 3.0-alpha2, so I downloaded version 3.0-alpha1 (was using 3.0-alpha2), expecting it to work, but it did not.

like image 887
Nathan Avatar asked Oct 03 '22 23:10

Nathan


1 Answers

After some conversations with the creator of LuaJ, we determined that the problem came from a change that was made starting in version 3.0-alpha1 where lua's package.path was being ignored when loading a script via require. What this means is that require will only look in the path "." when searching for scripts. If there are scripts called from a sub-directory, call it "place" then require could find those scripts by loading them with the dot operator:

require( "place.thingy" );

The reason, I suspect, that the number of issues with this package.path issue have been somewhat scarce in the community is because there is a way to set the path from the Java side that works in previous releases of LuaJ v3.0. (I will post an update on the proper way to do this once I have figured it out, as I am still unclear on the process.)

The long and short of the whole situation is that there should be a LuaJ v3.0-alpha3 on the way soon which allows the package.path to be set from lua.

Thanks again to Jim Roseborough for working with me to resolve the issue.

Note from Jim Roseborough: As Nathan mentioned, this was indeed a bug in luaj-3.0-alpha2 and before. This has been fixed and should work as expected in luaj-3.0-beta1 and later which is now available.

like image 197
Nathan Avatar answered Oct 13 '22 11:10

Nathan