Running Java method from Luaj, "index expected, got string"

1k views Asked by At

I'm working on a small project and was hoping to include lua scripting so users could create their own content. I've gotten it to mostly work. I can load scripts, run them, or run specific Lua methods from within java, etc. But I cannot figure out how to create a method in java that can be run by the lua script.

I searched around and found this post which describes exactly what I want.

Unfortunately, I can't get it to work.

Here are the most simple examples of code that I'm trying.

Main.java

public static void main(String[] args) {    
    LuaValue _G = JsePlatform.standardGlobals();
    _G.load(new MyLib());
    _G.get("dofile").call( LuaValue.valueOf("Files/Fighters/Sticky/prop/test.lua"));
    LuaValue MyAdd = _G.get("MyAdd");
    LuaValue retvals = MyAdd.call(LuaValue.valueOf(4), LuaValue.valueOf(-110));
}

MyLib.Java

public class MyLib extends OneArgFunction {
    public static MyLib MYLIB = null;
    public MyLib() {
        MYLIB = this;
    }

public LuaValue call(LuaValue env) {
        LuaTable mine = new LuaTable(0,30); // I think "new LuaTable()" instead of "(0, 30)" is OK
        mine.set("someFunc", new SomeFunc());
        env.set("mine", mine);
        env.get("package").get("loaded").set("mine", mine);
        return mine;
    }
}

SomeFunc.java

abstract class UnaryOp extends OneArgFunction {
    public LuaValue call(LuaValue arg) {
        return valueOf(call(arg.checkdouble()));
    }
    abstract protected double call(double d);
}

final class SomeFunc extends UnaryOp {
    protected double call(double d) {
        return Math.abs(d);
    }
}

test.lua

require "mine"
function MyAdd( num1, num2 )
   return mine.someFunc(num2-2)
end
function MySubtract( num1, num2 )
    return num1 - num2
end
function MyMult( num1, num2 )
    return num1 * num2
end

The error I get is index expected, got string. This is caused at the line env.set("mine", mine); within "MyLib.java"

Full Error Message

Exception in thread "main" org.luaj.vm2.LuaError: index expected, got string
at org.luaj.vm2.LuaValue.typerror(Unknown Source)
at org.luaj.vm2.LuaValue.settable(Unknown Source)
at org.luaj.vm2.LuaValue.set(Unknown Source)
at org.luaj.vm2.LuaValue.set(Unknown Source)
at luajClasses.MyLib.call(MyLib.java:17)
at org.luaj.vm2.lib.OneArgFunction.call(Unknown Source)
at org.luaj.vm2.LuaValue.load(Unknown Source)
at luajClasses.Main.main(Main.java:17)
1

There are 1 answers

0
Aroymart On BEST ANSWER

I messed around with the code and re-read the Luaj Getting Started page and figured it out.

When creating a Library, such as I did in the "MyLib.Java" file, you need a lua variable to set the library. This variable should be of the Type "LuaTable."

When you extend "OneArgFunction" like I did, you only get one LuaValue, it is actually of type "LuaString" rather than "LuaTable."

The fix was to make the MyLib class extend twoArgFunction, as the second value is the real "env" LuaTable.

The resulting code, incase it helps anyone:

public class MyLib extends TwoArgFunction {
    public static MyLib MYLIB = null;
    public MyLib() {
        MYLIB = this;
    }

public LuaValue call(LuaValue modname, LuaValue env) {
        LuaTable mine = new LuaTable(0,30);
        mine.set("someFunc", new SomeFunc());
        env.set("mine", mine);
        env.get("package").get("loaded").set("mine", mine);
        return mine;
    }
}

For more, I suggest going to the Luaj Getting Started page and scrolling down to "Libraries of Java Functions"