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.

A Rest Client now works on a strict module path and in a jlink image, with nothing to add to the application’s module-info:

  • RestClientBuilder.newBuilder() works on the module path — it used to throw ServiceConfigurationError, because the descriptors did not declare the ServiceLoader lookups the specification makes. io.vidocq.cyrano.mp.rest.client.api now declares uses RestClientBuilderResolver and uses RestClientBuilderListener, and io.vidocq.cyrano.core declares uses RestClientBuilderListener and uses RestClientListener. @Inject @RestClient goes through newBuilder(), so it was affected too, on the Vidocq runtime as well. A listener another module provides — the RestClientListener of humboldt-rest, for example — is now found. Exported Java modules, Builder and client listeners.

  • A runtime-fallback proxy for an interface of another named module — when an interface has no proxy generated by cyrano-processor, cyrano-core defines one at run time in the interface’s package. For an interface of another named module, that failed even after the module did what the error message asked. The module now declares only the opens <package> to io.vidocq.cyrano.core the message names: it does not have to read cyrano-core, and no --add-reads or --add-exports is needed. With the proxy generated at compile time by cyrano-processor, the module still needs no opens at all. Tier 3: runtime generation.

  • Reactive Streams is an optional dependency — org.reactivestreams:reactive-streams is an automatic module, and it came with cyrano-core into every Rest Client application, so jlink refused to link any of them (jlink does not support automatic modules: org.reactivestreams). It is now optional: a Rest Client application links. An application whose client methods return Publisher (server-sent events) must declare the dependency itself, and such an application cannot be linked with jlink until an explicit org.reactivestreams module exists. Reactive Streams for Publisher.

Behaviour changes

What an upgrading application has to do, for these changes and for the module-path ones above, is summed up in Upgrading from 0.3.0.

  • onNewBuilder runs once per builder — RestClientBuilder.newBuilder() notified every RestClientBuilderListener up to three times for one builder: once from the API, once from Cyrano’s resolver and once more from build(). It now notifies each listener once, when the builder is created, as the specification says, and never from build(). RestClientListener.onNewClient still runs once per build(). A listener that counted its calls sees fewer. Builder and client listeners.

  • Asynchronous responses never run on the caller’s thread — with no executorService on the builder, a method returning CompletionStage processed a response that was already complete — response filters, readers, AsyncInvocationInterceptor.applyContext — on the thread that called the method, and so was a request aborted by a filter. Each response is now processed on a new virtual thread. An executor service set on the builder is used, as before. Async — CompletionStage<T>.

  • @RestClient beans for the application’s own interfaces at build time — when the CDI extension runs inside the Vauban annotation processor, as on the Vidocq runtime, the @RegisterRestClient interface is being compiled and cannot be loaded, and the extension skipped it silently: no @RestClient bean, and @Inject @RestClient failed with an unsatisfied dependency. The bean is now declared from the compiler’s model of the interface, and the interface is loaded when the client is built. It needs the matching Vauban 0.4.0 line. Discovery: Vauban BCE.

Other CDI containers

  • Proven on Weld and Open Liberty — two new test modules run the Cyrano jars, unchanged, without Vauban: cyrano-it-weld on Weld SE 6.0 (class path), cyrano-it-openliberty as a WAR on Open Liberty 26.0.0.10 (MicroProfile 7, CDI 4.0) with Liberty’s own mpRestClient off. Both cover a processor-generated proxy and the run-time fallback. Neither is published (cyrano#34). Other CDI containers.

  • The Jakarta REST API is provided — cyrano-api and cyrano-mp-rest-client-api no longer ship jakarta.ws.rs-api; the runtime brings it (vidocq-workspace#17). This is a behaviour change for an application that compiled against Jakarta REST through Cyrano alone: it now declares the API itself. On the Vidocq runtime, the Rest Client extension brings it, together with Champollion’s JSON-B implementation, which it used to leave to the REST extension. Runtime prerequisites.