Maven
Embed the Lemma engine in Java, Kotlin, or Scala via com.lemmabase:lemma-engine on Maven Central. The JAR ships prebuilt lemma_jni natives for the same six targets as the Hex package (no musl).
Decimals use java.math.BigDecimal. float / double data values are rejected so binary floating point cannot silently corrupt exact magnitudes. See Precision.
Install
Maven:
<dependency>
<groupId>com.lemmabase</groupId>
<artifactId>lemma-engine</artifactId>
<version>0.9.0</version>
</dependency>
Gradle (Kotlin DSL) — consume the published artifact; this repository builds the package with Maven only:
implementation("com.lemmabase:lemma-engine:0.9.0")
Requires JDK 17+.
Java example
import com.lemmabase.lemma.Engine;
import com.lemmabase.lemma.Response;
import com.lemmabase.lemma.RunRequest;
import com.lemmabase.lemma.RuleResult;
import java.math.BigDecimal;
import java.util.Map;
try (Engine engine = Engine.create()) {
engine.load("""
spec order
data quantity: number
data unit_price: number
data tax_rate: number
rule subtotal: quantity * unit_price
rule tax: subtotal * tax_rate
rule total: subtotal + tax
""");
Response response = engine.run(
RunRequest.of("order")
.data(Map.of(
"quantity", 3,
"unit_price", new BigDecimal("19.99"),
"tax_rate", new BigDecimal("0.21"))));
RuleResult total = response.results().get("total");
BigDecimal amount = total.number();
}
Kotlin example
Same artifact:
import com.lemmabase.lemma.Engine
import com.lemmabase.lemma.RunRequest
import java.math.BigDecimal
Engine.create().use { engine ->
engine.load("""
spec order
data quantity: number
data unit_price: number
data tax_rate: number
rule subtotal: quantity * unit_price
rule tax: subtotal * tax_rate
rule total: subtotal + tax
""".trimIndent())
val response = engine.run(
RunRequest.of("order").data(
mapOf(
"quantity" to 3,
"unit_price" to BigDecimal("19.99"),
"tax_rate" to BigDecimal("0.21"),
)
)
)
val total: BigDecimal = response.results()["total"]!!.number()!!
}
API surface
| Method | Role |
|---|---|
Engine.create() / Engine.create(ResourceLimits) |
Construct engine |
load(String) / load(Map<String,String>) |
Validate and load sources (volatile or labeled) |
run(RunRequest) |
Evaluate; named fields only |
list() / show(...) / source(...) / remove(...) |
Inspect and manage loaded specs |
limits() |
Current resource limits |
Lemma.format(String) |
Format source without an engine |
close() |
Drop native engine (AutoCloseable + Cleaner) |
RunRequest.of(spec) defaults: repository null, effective null, rules null (all rules), explain false. An empty rules list is a request error. With explain(true), RuleResult.explanation() is a JSON tree matching explanation.v1.json.
Errors and veto
- Invalid Lemma or bad requests → unchecked
LemmaExceptionwith WASM-shapedEngineErrorentries. - Domain
veto→ still a successfulResponse; checkRuleResult.vetoed()/vetoReason(). - Use-after-close or invariant failures →
LemmaBugError.
Thread safety
One Engine instance; serialize access across threads (native side holds a mutex). Prefer one engine per worker, or external locking around a shared instance.
Development in this repository
cargo build -p lemma_jni
cd engine/packages/maven && ./mvnw test
cargo precommit builds lemma_jni and runs ./mvnw -B test.