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.

Request entities

  • An unreadable request entity is a 400, not a 500 — malformed JSON, an empty body, a JSON value of the wrong shape or type for the Java type: the resource method is not called and Cassini answers 400 Bad Request, with an empty body unless the application maps BadRequestException. The application’s ExceptionMapper for the exception the reader threw still runs first. Up to 0.3.0, these requests answered 500 with the parser’s message (cassini#39). Unreadable request entities.

  • NoContentException becomes a BadRequestException — whatever reader throws it, the application’s included, as Jakarta REST §4.2.4 requires; the built-in JSON reader now throws it for an empty entity. Unreadable request entities.

  • No ERROR log for a client’s malformed entity — one line at DEBUG on the io.vidocq.cassini.entity logger, and the stack trace at TRACE, where each such request used to log a full stack trace at ERROR. A type the JSON-B provider cannot reach, its package not exported to it, remains a server error logged at ERROR. Unreadable request entities.

Embedding

  • A host can read the route table — CassiniStack.routes() returns the routes a stack resolved, in match order, as RouteDescription values: HTTP method, path template, resource class and method names, produced and consumed media types. A host such as Vidocq can list what an application exposes without reaching into cassini-core (cassini#41). Reading the route table.

  • Live request figures — CassiniStack.statistics() returns the counters a stack keeps: requests answered, in flight, by status class, and the total and longest time spent answering them. Reading them creates nothing and takes no lock; updating them allocates nothing and costs about 25 ns per request, so they are on by default, and statistics(false) removes them (cassini#42). Reading live request figures.

Other CDI containers

  • cassini-core no longer brings Champollion — it depends on the JSON-P and JSON-B APIs only, and the application, or its runtime, picks the implementation: the Vidocq REST extension brings Champollion, so nothing changes in a Vidocq application. A standalone application that relied on cassini-core for JSON adds champollion-jsonb (or another JSON-B implementation). Without one, the stack still starts and only a JSON entity fails (vidocq-workspace#17). Getting started.

  • cassini-cdi, a container-neutral BeanProvider — Cassini resolves its resources and providers as beans of any CDI 4 container, through CDI.current(), the BeanManager and RequestContextController, and activates the request context around each request. cassini-it-weld proves it on Chappe with Weld SE: injection, a @RequestScoped bean per request, interceptors on resources (cassini#53). Other CDI containers.

  • CassiniScopeExtension moved to cassini-cdi — the BCE that gives @Path and @Provider classes their default scope is now io.vidocq.cassini.cdi.CassiniScopeExtension; cassini-cdi-vauban depends on cassini-cdi and keeps its own, faster provider, which outranks the neutral one when Vauban runs. Nothing changes for a Vidocq application. Code that named the class io.vidocq.cassini.cdi.vauban.CassiniScopeExtension uses the new package. Java modules.