嵌入式使用
在 Java/Kotlin 项目中嵌入 NovaLang
嵌入式使用
NovaLang 可以轻松嵌入到 Java/Kotlin 项目中,作为规则引擎、配置脚本或扩展系统使用。
添加依赖
// Gradle
implementation 'com.novalang:nova-runtime:0.1.1'
// JSR-223 支持 (可选)
implementation 'com.novalang:nova-script:0.1.1'
方式一:Nova 便捷 API(推荐)
import nova.runtime.Nova;
Nova nova = new Nova();
// 执行代码
nova.eval("println(\"Hello from Nova!\")");
// 注入变量
nova.set("name", "Alice");
nova.set("scores", Arrays.asList(90, 85, 92));
nova.eval("println(\"$name 的成绩: $scores\")");
// 读取结果
nova.eval("val result = 1 + 2");
int result = nova.get("result", int.class); // 3
// 调用 Nova 函数
nova.eval("fun add(a: Int, b: Int): Int = a + b");
int sum = nova.call("add", int.class, 10, 20); // 30
Builder DSL API
通过 Receiver Lambda 实现 Kotlin 风格的 DSL builder:
// 定义 builder 函数
nova.defineBuilderFunction("serverConfig", ServerConfig::new, config -> {
config.validate();
return config;
});
Nova 脚本侧使用:
val cfg = serverConfig {
host = "0.0.0.0"
port = 8080
}
println(cfg.host) // 0.0.0.0
以接收者调用 Nova lambda:
// 获取 Nova 中定义的 lambda
Object block = nova.get("myBlock");
// 以 receiver 调用,block 内可直接访问 receiver 的属性和方法
nova.invokeWithReceiver(block, receiver);
方式二:JSR-223 ScriptEngine
通过标准 javax.script API,支持引擎可替换:
import javax.script.*;
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nova");
// 执行
Object result = engine.eval("1 + 2"); // 3
// 变量绑定
engine.put("name", "Alice");
engine.eval("println(\"Hello, $name!\")");
String name = (String) engine.get("name");
// 预编译
Compilable compilable = (Compilable) engine;
CompiledScript compiled = compilable.compile("n * n + 1");
engine.put("n", 7);
System.out.println(compiled.eval()); // 50
注册自定义函数
@NovaFunc 注解批量注册
import nova.runtime.interpreter.NovaFunc;
public class MathUtils {
@NovaFunc("square")
public static int square(int x) {
return x * x;
}
@NovaFunc("clamp")
public static double clamp(double value, double min, double max) {
return Math.max(min, Math.min(max, value));
}
}
// 注册
Nova nova = new Nova();
nova.getInterpreter().registerAll(MathUtils.class);
nova.eval("println(square(5))"); // 25
NovaNativeFunction
import nova.runtime.interpreter.*;
NovaNativeFunction greet = NovaNativeFunction.create("greet",
(name) -> new NovaString("Hello, " + name.asString() + "!")
);
nova.getInterpreter().getGlobals().defineVal("greet", greet);
nova.eval("println(greet(\"Nova\"))"); // Hello, Nova!
安全策略
嵌入式场景下通过安全策略限制脚本行为:
import nova.runtime.interpreter.NovaSecurityPolicy;
// 预定义级别
Nova nova = new Nova(NovaSecurityPolicy.strict());
// 自定义策略
NovaSecurityPolicy policy = NovaSecurityPolicy.custom()
.allowJavaInterop(true)
.allowPackage("java.util")
.allowPackage("java.math")
.denyClass("java.lang.Runtime")
.denyMethod("java.lang.System", "exit")
.maxExecutionTime(5000)
.maxRecursionDepth(128)
.build();
Nova nova = new Nova(policy);
类型转换
Java 和 Nova 之间的值自动双向转换。NovaValue 提供类型安全的 toJava() 方法:
NovaValue result = interpreter.eval("1 + 2");
int safe = result.toJava(int.class);
String s = result.toJava(String.class);