Skip to main content

Generate Java Package

After a domain model is ready, TeaQL can generate a Java package that application teams use from their services.

The common flow is:

Model domain
-> evaluate model
-> select current service target
-> generate Java package
-> commit and wait for CI
-> consume the package from Gradle

Define the Root Model

A root model can declare package-level identity such as service name, organization, and version:

<?xml version="1.0"?>
<root name="cmes" org="doublechaintech" version="1.0.0">
<_include file="cmes.xml"/>
</root>

The included model files define the business domain. The root file supplies package identity and must include a concrete, non-empty version; the dynamic generation target is selected separately with -Dservice.

Generate the Package

TeaQL Maven plugin 1.1.0 uses a dynamic service target. First inspect the current server catalog and evaluate the model:

mvn io.teaql:teaql-maven-plugin:1.1.0:list-services
mvn io.teaql:teaql-maven-plugin:1.1.0:eval -Dinput=model

Then generate the Java domain library with the currently advertised java-lib-core target:

mvn io.teaql:teaql-maven-plugin:1.1.0:generate \
-Dservice=java-lib-core \
-Dinput=model

The plugin help reports generated-lib as the default output directory. Use -Dteaql.output=<path> when the project requires an explicit location. Treat the live list-services output as authoritative because targets are supplied by the server rather than hard-coded as Maven goals.

When -f selects a POM outside the current shell directory, Maven plugin 1.1.0 resolves a relative -Dinput from that Maven project's base directory. If the reported input does not exist path contains a duplicated directory, correct the project-relative path or use an absolute path.

For the java-lib-core target observed on 2026-07-13, the generated Maven project selected Java 21, Spring Boot 4.1.0, and TeaQL 1.525-RELEASE. Verify these values in your generated POM because target templates can change independently of this page.

Generation can run through the TeaQL generation process and CI pipeline. The important output is a versioned package that application services can depend on.

The package should be treated as generated output:

  • update the model first;
  • regenerate the package;
  • do not hand-edit generated source files;
  • keep application-specific behavior in extension points and service code.

Verify the Generated Project

Build from the generated project directory with the Java level emitted by its POM:

mvn test

Generation success and build success are separate checks. During the 2026-07-13 verification, java-lib-core generated successfully, but its POM used the nonexistent artifactId teaql-data-service-sqlite. The official released SQLite module is io.teaql:teaql-sqlite:1.525-RELEASE.

A separate diagnostic POM using the official module then exposed a second template mismatch: generated entities override and call internalSet and internalGet, while teaql-core 1.525-RELEASE exposes __internalSet and __internalGet. Preserve the generated POM and compiler report and report both template defects. Do not patch generated entities or substitute dependency coordinates in committed generated output.

The same live catalog advertised java-app-console, but that target returned a missing application.properties.stg server-template error during verification. Treat an advertised target as discoverable until its generated workspace also passes a clean build.

Use from Gradle

After the package is published, application code can consume it through Gradle as a normal dependency.

The generated package gives the application:

  • entities;
  • Q query APIs;
  • E safe expressions;
  • checker and validation hooks;
  • runtime integration points;
  • generated request and selection APIs.

Application Code

Application code should use the generated APIs:

Q.orders()
.filterByMerchant(ctx.getMerchant())
.selectLineItemList(Q.lineItems().selectSku())
.comment("Query merchant orders")
.purpose("Load orders for the current page")
.executeForList(ctx);

If the model changes, regenerate the package instead of manually patching generated code.