You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Java ships the trace-helper generator but no libraries loader option, so metaobjects::ai::LlmCallBase cannot be loaded at all #332
The Java port has LlmTraceHelperGenerator but no way to load the metadata that generator exists to consume. There is no libraries loader option and no library/ embed on that port, so extends: metaobjects::ai::LlmCallBase cannot resolve — the documented adopter path fails with ERR_UNRESOLVED_SUPER.
A generator shipped without its input.
Evidence (against main @ 0994d6e41)
$ git ls-tree -r main --name-only | grep LlmTraceHelperGenerator.java
server/java/codegen-spring/src/main/java/com/metaobjects/generator/spring/LlmTraceHelperGenerator.java
$ git grep -l "libraries" main -- 'server/java/**/*.java' | grep -v test
(no output)
The only references to LlmCallBase in the Java tree are in a test that declares its own inline under a different package:
That is the bypass ADR-0024 already called out — "the green tests pass only because they bypass the shipped base with bespoke entities" — which is why a port can ship a generator it cannot feed and stay green.
Why it matters
This is the same defect that was just closed on the Python port (libraries=[...] + library/ + the embed generator). Until Java has the equivalent, a JVM adopter following the documented extends metaobjects::ai::LlmCallBase path cannot get past load.
Suggested shape
Mirror the Python/TypeScript design rather than inventing a third: canonical library/**/*.yaml at the repo root stays the source, each port embeds it (Python embeds as a generated source module so no build config can drop it), and the loader gains a libraries opt-in that prepends those sources.
Worth adding with it, since none of these existed on Python either:
a byte-comparison gate so a stale embed cannot ship,
an assertion that extends FAILS without the opt-in and resolves with it — the negative half is what proves the opt-in is doing the work,
Fixed on main. Java now has the whole feature, mirroring the Python/TypeScript design rather than inventing a third:
com.metaobjects.library.EmbeddedLibrary — a generated class of string constants, not a src/main/resources copy. A resource can be dropped or mangled by build configuration (resource filtering, shading, repackaging) and the failure would surface much later as ERR_UNRESOLVED_SUPER against the adopter's own metadata; a class constant cannot go missing without the class going missing. Same rationale Python records for its source module. Emitted by the existingscripts/generate-embedded-library.ts rather than a second script — two scripts walking one tree are two things that can drift.
com.metaobjects.library.LibrarySources — on-disk-first, embedded fallback, unrecognised package contributes no sources.
The opt-in: MetaDataLoader.setLibraries(...), a fromDirectory(..., libraries) overload, LoaderConfiguration.getLibraries() (a default method, so a build-tool implementor outside this repo keeps compiling), and a pom <loader><libraries><library>ai</library></libraries>. An unknown name in a pom is a hard failure listing what this version ships.
All four gates you asked for:
the byte-comparison against the canonical tree, proven by breaking it rather than by its silence — appending a line to library/ai/llm-call.yaml turns it red naming the regeneration command;
extends asserted to fail without the opt-in and resolve with it. The negative arm is worth a note: its first draft asserted only that errors were non-empty, and it passed on the loader's "Failed to load from directory <path>" envelope, which names nothing. It now asserts the failure names LlmCallBase;
ADR-0024 FIX fix(cli): scaffold outDir defaults to src/generated, not ./src/db #1, both directions. One direction alone is worthless — "every row key is a field" passes on a recorder that writes nothing, "every field is a row key" passes on one that writes the whole world;
TraceHelperOnShippedLibraryTest runs the generator against the shipped base, so the suite can now tell a world where the library loads from one where it does not exist. That was the gap that let this ship.
Activity
feat(java): the shipped library is loadable, so the generator that co…
docs(changelog): 0.24.0 records the adopter batch — #326/#327, #332/#333
dmealing commentedon Aug 21, 2026
Fixed on
main. Java now has the whole feature, mirroring the Python/TypeScript design rather than inventing a third:com.metaobjects.library.EmbeddedLibrary— a generated class of string constants, not asrc/main/resourcescopy. A resource can be dropped or mangled by build configuration (resource filtering, shading, repackaging) and the failure would surface much later asERR_UNRESOLVED_SUPERagainst the adopter's own metadata; a class constant cannot go missing without the class going missing. Same rationale Python records for its source module. Emitted by the existingscripts/generate-embedded-library.tsrather than a second script — two scripts walking one tree are two things that can drift.com.metaobjects.library.LibrarySources— on-disk-first, embedded fallback, unrecognised package contributes no sources.MetaDataLoader.setLibraries(...), afromDirectory(..., libraries)overload,LoaderConfiguration.getLibraries()(adefaultmethod, so a build-tool implementor outside this repo keeps compiling), and a pom<loader><libraries><library>ai</library></libraries>. An unknown name in a pom is a hard failure listing what this version ships.All four gates you asked for:
library/ai/llm-call.yamlturns it red naming the regeneration command;extendsasserted to fail without the opt-in and resolve with it. The negative arm is worth a note: its first draft asserted only that errors were non-empty, and it passed on the loader's"Failed to load from directory <path>"envelope, which names nothing. It now asserts the failure namesLlmCallBase;TraceHelperOnShippedLibraryTestruns the generator against the shipped base, so the suite can now tell a world where the library loads from one where it does not exist. That was the gap that let this ship.C# has the same gap and is not addressed here.
feat(csharp): the fifth port loads the shipped library too, and the c…