New in the 0.4.0-SNAPSHOT development line — everything listed here landed after the 0.3.0 release and is not part of it. Every entry links to the section that documents it, and those sections carry the NEW badge. Each brick of the suite keeps its own page of this kind; the ecosystem index gathers them. When the next release train ships, this page is frozen with it and restarts empty on the dev line.

MicroProfile OpenAPI 4.2

Grimm targets the MicroProfile OpenAPI 4.2 API. The build pins 4.2-RC5 until the final reaches Maven Central, and the official TCK 4.2-RC5 passes at 367 / 367; the run will be repeated on the final. TCK.

  • Unknown Schema properties are extensions — a Schema keeps any property it does not know, x- prefixed or not, and writes it back. getAll() lists every property set, under its JSON name, and setAll(…​) clears them all first, as the 4.2 Javadoc says; in 0.3.0, both saw only the unknown properties. Static documents and schema overrides.

  • @Header example and examples — mapped onto the header, from annotations and from a static file. Supported annotations.

  • @ExternalDocumentation on a resource method — becomes the operation’s externalDocs. Supported annotations.

  • multipleOf and pattern from @Digits — Bean Validation @Digits gives a multipleOf on a number schema and a pattern on a string schema, never overriding a value set on the schema. Decimals are written as plain decimals (0.0000000001, not 1E-10), which a YAML 1.1 parser still reads as numbers. How annotation values are mapped.

How the model sources combine

  • The static file now wins over the OASModelReader — behaviour change. The specification’s processing rules start from the reader model, apply the static file on top of it, then the annotations, then the OASFilter. Up to 0.3.0, Grimm merged the static file first and the reader over it, so on a conflict the reader won. If your reader was meant to override META-INF/openapi.yaml, move that override to an annotation or a filter. How the sources combine, Upgrading from 0.3.0.

  • Schemas at the same position merge keyword by keyword — when two sources describe the schema of a media type, a property or items, every keyword of the higher-priority source now wins (minimum, pattern, readOnly, examples, not, …); only a handful were copied before. Its explicit empty values (default: [], const: {}, x-tags: []) are kept too. A named component schema is still taken whole. How the sources combine.

  • A summary beside a $ref is lost — OpenAPI 3.1 allows it on a Reference Object, but the MicroProfile OpenAPI model has no summary on a parameter, request body, response, header, link, security scheme or callback, so a static file that writes one loses it. This is a limitation of the API, documented rather than worked around. How the sources combine.

A more faithful document

A review of the 4.2 work found the places where Grimm dropped or bent what the application wrote. All are fixed, each with its own test; the TCK does not exercise these cases.

  • @Schema and @SchemaProperty map every attribute — @SchemaProperty used to map a dozen attributes; both annotations now share one mapping that covers bounds, lengths, counts, flags, composition, the discriminator, externalDocs with its extensions, examples and the JSON Schema 2020-12 keywords. How annotation values are mapped.

  • No more stray minItems, maxItems, maxProperties — every annotated schema used to carry minItems: 2147483647, maxItems: -2147483648 and maxProperties: 0. An attribute left at its default now writes nothing. How annotation values are mapped.

  • A partial @Schema is applied — on a parameter, request body, header or content entry, a @Schema that sets only minimum, examples, oneOf, readOnly, … was ignored in favour of the inferred schema. It is now applied. How annotation values are mapped.

  • constValue, examples and parsed extension values are JSON — constValue and examples are parsed as JSON unless the schema type is STRING, and @Extension(parseValue = true) values go through the strict JSON reader of static files instead of a lossy hand-written one. Behaviour change: lenient values that are not JSON ({a: 1}, TRUE, 1L) stay strings. How annotation values are mapped, Upgrading from 0.3.0.

  • Static-file keywords keep their type — minimum, maxLength, not, discriminator, xml, externalDocs, … read from a static file (or from an mp.openapi.schema.<FQCN> value, or a processor fragment) were stored as extensions, so an OASFilter clearing extensions wiped them; they are typed properties now. Static documents and schema overrides.

  • Static-file $ref and fields are kept — the $ref of a parameter, request body, response or callback is kept as written, as are parameter and header fields (style, explode, content, example, examples, …), discriminator x- keys, type: "null" and YAML 1.2 numbers. Static documents and schema overrides.

  • mp.openapi.schema.<FQCN> reads every keyword — the value goes through the static-file mapper instead of a converter that knew a few keywords; the ref alias works at every level, $defs and definitions included. Behaviour change: an explicit $ref is kept verbatim, so a short name there needs ref or the full #/components/schemas/…​. Static documents and schema overrides.

  • Bean Validation on a parameter reaches the document — the annotation processor built a parameter schema from its type alone, so a compile-time fragment lacked the constraints the runtime scan derives. Such a class is now left to the runtime scan. Build pipeline.

Java modules

  • Grimm ships named modules — the module-info of grimm-core, grimm-processor and grimm-cdi-vauban was never compiled into the jars, so Grimm ran as automatic modules. In a modular application, a build tool could then take grimm-cdi-vauban for a class-path jar and split its package, and /openapi answered 404 (grimm#15). Each jar now carries its descriptor: grimm-cdi-vauban requires transitive the MicroProfile OpenAPI and JAX-RS APIs its own API exposes and provides its generated _VaubanComponents, so the container builds its beans with no opens. A module-info.java that said requires grimm.cdi.vauban; now says requires io.vidocq.grimm.cdi.vauban;. Java modules, Upgrading from 0.3.0.

  • The annotation processor resolves as a module — grimm-core exports the two packages the processor uses (io.vidocq.grimm.internal, io.vidocq.grimm.internal.schema) to io.vidocq.grimm.processor as well, still as qualified exports, so the processor works from the module path (grimm#19). Java modules.

Other CDI containers

  • Proven on Weld and Open Liberty — two new test modules run the Grimm jars, unchanged, without Vauban: grimm-it-weld on Weld SE 6.0 (class path, plus two containers in one JVM) and grimm-it-openliberty as a WAR on Open Liberty 26.0.0.10 (MicroProfile 7, CDI 4.0) with Liberty’s own mpOpenAPI off. Neither is published (grimm#22). Other CDI containers.

  • vauban-api is now a runtime dependency of grimm-cdi-vauban — it was provided, so outside Vauban the model cache, the /openapi resource and the auto-discovery bean could not be loaded (BUG-20261010-01). It no longer brings the CDI API. Other CDI containers.

  • Two containers keep their documents apart — the class names the extension records used to live in a static set, cleared at each container start: two applications starting together on one server could document each other’s resources (BUG-20261010-02). They now belong to each container, through a synthetic ScannedTypes bean. Internals.

  • Resources that are not CDI beans are documented — in annotated discovery mode, the resources grimm-processor described now enter the document even when the CDI scan never saw them. Other CDI containers.

  • Jakarta REST is provided in grimm-cdi-vauban, and compile scope in grimm-processor — the runtime jar no longer ships the API (vidocq-workspace#17); this is a behaviour change for an application that compiled against Jakarta REST through Grimm alone. The processor now carries it, so an annotationProcessorPaths entry for grimm-processor works on its own. On the Vidocq runtime, the OpenAPI extension brings Jakarta REST. Other CDI containers.