How to Bridge Lua and Java with luaj: Call Java Methods from Lua

This article explains how to use luaj, a Lua‑Java bridge, to call Java static methods from Lua, pass Lua functions to Java, handle method signatures, check call results, and manage error codes, providing practical code examples for seamless integration.

Programmer DD
Programmer DD
Programmer DD
How to Bridge Lua and Java with luaj: Call Java Methods from Lua

1. Main Features of luaj

luaj allows calling Java class static methods from Lua, supports int/float/boolean/String/Lua function parameters, can pass Lua functions to Java and retain references, and enables Java to invoke Lua global functions or referenced functions.

* can call Java static methods from Lua
* supports int/float/boolean/String/Lua function parameters
* can pass Lua function as parameter to Java and keep reference
* Java can call Lua global functions or referenced functions

luaj’s functionality is simple yet sufficient for integrating various SDKs.

2. Usage Example

Java method prototype:

public static float getNum(float n) {
    return n;
}

Lua code to call the method:

local className = "com/qeeplay/frameworks/CheShi"
local method = 'getDisplayWidth'
local n = 10
local args = { n }
local _, screenwidth = luaj.callStaticMethod(className, method, args)

3. Implementation Principle

The core goal of luaj is two‑way interaction: calling Java from Lua and calling Lua from Java.

* Find and invoke a specific Java method
* Check the call result and obtain the return value
* Pass a Lua function as a parameter to a Java method
* Invoke a Lua function from a Java method

4. Finding and Invoking a Specific Java Method

JNI’s FindClass() locates the target class; the class name uses “/” instead of “.”. After obtaining the class, GetStaticMethodID() finds the static method given its name and signature.

The signature describes parameter and return types, e.g., (Ljava/lang/String;ZZI)V. luaj can automatically guess the signature from the arguments, but you can also specify it explicitly.

local args = { n }1

Because Lua cannot distinguish integer from float, luaj assumes all numbers are floats, which may cause errors when the Java method expects an int.

public static int getNum(int n) {
    return n;
}
-- Lua call that fails because of type mismatch

Specify the correct signature to avoid the error:

local sig = "(I)I"
local _, screenwidth = luaj.callStaticMethod(className, method, args, sig)

Signature format: (parameter types)return type. Examples:

()V          // no parameters, void return
(I)V         // int parameter, void return
(Ljava/lang/String;)Z // String parameter, boolean return
(IF)Ljava/lang/String; // int and float parameters, String return

Type name mapping:

I  – int
F  – float
Z  – boolean
Ljava/lang/String; – String
V  – void

5. Checking Call Result and Getting Return Value

luaj.callStaticMethod() returns two values: a boolean indicating success and either the Java method’s return value or an error code.

* success: first value true, second value is the return value
* failure: first value false, second value is an error code

Example Java method:

public static int AddTwoNumbers(final int number1, final int number2) {
    return number1 + number2;
}

Corresponding Lua code:

local args = {2, 3}
local sig = "(II)I"
local ok, ret = luaj.callStaticMethod(className, "AddTwoNumbers", args, sig)
if not ok then
    print("luaj error:", ret)
else
    print("ret:", ret)
end

Error codes:

-1  unsupported parameter or return type
-2  invalid signature
-3  method not found
-4  exception thrown by Java method
-5  JVM error
-6  JVM error

6. Passing a Lua Function as a Parameter to Java

Lua functions are stored as values; luaj keeps a reference table and assigns an integer ID to each function passed to Java. The Java side receives this ID (int) and can invoke the Lua function.

Therefore, Java method parameters that receive a Lua function must be of type int.

public static int getNum(int n) {
    return n;
}
-- Lua side
local function callback(result)
    -- handle result
end
local args = { callback }
local sig = "(I)I"
local _, screenwidth = luaj.callStaticMethod(className, method, args, sig)
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaScriptingLuaJNIbridgeluaj
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.