Java Customization
Keep business-model output generated and place application-owned behavior at the documented extension boundary:
| Concern | Guide |
|---|---|
| Trusted identity, policy, routing, and runtime resources | UserContext |
| Runtime composition and provider extensions | Runtime Extension Points |
| Entity and business identifier policies | Internal ID and Business ID |
| Localization | Internationalization |
| SQL and diagnostic logging | Logging |
| Audit delivery | Custom Audit Trail |
| Cache, locks, and routing | Cache, Distributed Locks, and Read/Write Splitting |
Framework and provider behavior must be verified independently. Continue with the current conformance snapshot; consult the Java Compatibility Archive only for its dated campaign.
Runtime infrastructure
Java exposes process-local cache and keyed lease locks through UserContext.
It also has remote cache/lock SPIs and Redis adapter classes, but the current
default Redis cache provider does not construct an operational JedisPool, and
the Redis lock release is not owner-token compare-and-delete. Supply and test a
production provider instead of assuming the SPI is ready from class presence.
teaql-cloud supplies Nacos 1.x/2.x HTTP and Consul HTTP clients for service
registration, deregistration, healthy discovery, and health; the Nacos adapter
also retrieves configuration. Read the exact maturity and Nacos 3.x boundary
in Cache, Lock, and Cloud Runtime Infrastructure.
Worked Example: Trusted Runtime and Context
Create application-scoped infrastructure once, then derive a request context
from authenticated server state. requestPolicy, tenant, and audit sink are
never populated from request JSON.
public final class RuntimeFactory {
public static TeaQLRuntime runtime(
EntityMetaFactory metadata,
DataServiceExecutor provider,
RequestPolicy requestPolicy,
RuntimeLogSink logSink,
RuntimeTelemetry telemetry) {
return TeaQLRuntime.builder()
.metadata(metadata)
.dataService("default", provider)
.requestPolicy(requestPolicy)
.logSink(logSink)
.telemetry(telemetry)
.build();
}
public static DefaultUserContext requestContext(
TeaQLRuntime runtime,
String authenticatedTenant,
AppAuditEventSink appAuditSink) {
if (authenticatedTenant == null || authenticatedTenant.isBlank()) {
throw new IllegalArgumentException("trusted tenant is required");
}
DefaultUserContext context = new DefaultUserContext(runtime);
context.putAttribute("trustedTenant", authenticatedTenant);
context.putAttribute(AppAuditEventSink.class.getName(), appAuditSink);
return context;
}
}
Readiness must use the real runtime/provider path:
DefaultUserContext probe = RuntimeFactory.requestContext(runtime, "readiness", auditSink);
probe.ensureSchema();
ensureSchema() is an explicit startup/administrative action. Do not call it
from ordinary liveness probes or per-request context creation.
Worked Example: Local Cache and Lock
This example caches an immutable application projection and protects a process-local refresh. It does not claim cross-replica coordination.
String cacheKey = tenant + ":currency:" + currencyCode;
CurrencyView cached = context.getFromLocalCache(cacheKey, CurrencyView.class);
if (cached == null) {
String lockKey = tenant + ":currency-refresh:" + currencyCode;
if (!context.tryLocalLock(lockKey, 250, 5_000)) {
throw new IllegalStateException("currency refresh is busy");
}
try {
cached = context.getFromLocalCache(cacheKey, CurrencyView.class);
if (cached == null) {
cached = loadAuthorizedCurrencyView(context, currencyCode);
context.putToLocalCache(cacheKey, cached, 300);
}
} finally {
context.unlockLocal(lockKey);
}
}
After an audited currency update, call removeFromLocalCache(cacheKey). For
multiple service replicas, install an owner-safe Remote Lock provider and make
its presence part of readiness; the current built-in Redis lock implementation
is not sufficient as the sole critical guard.