|
Cervantes is at |
On the application code side, migration is trivial: Cervantes strictly consumes the standard org.eclipse.microprofile.jwt. and jakarta.annotation.security. annotations. No proprietary import to replace. The gaps lie in transport/JWE configuration and in the dependency footprint.
From SmallRye JWT
SmallRye JWT is the reference implementation in Quarkus and in several Jakarta EE servers. Migration is direct — Cervantes targets strict conformance to the same spec.
| SmallRye JWT | Cervantes | Note |
|---|---|---|
|
Same annotations |
No application code change. |
|
Same |
Same standard MP interface. |
|
Same, same supported types |
Cervantes adds support for |
|
Same keys |
|
|
Same keys |
|
|
Same keys |
|
Transitive dependencies: jose4j, Jackson, … |
None ( |
Smaller classpath footprint. Immediate jlink compatibility. GraalVM native-image friendly. |
|
No equivalent (standard claims only) |
If the issuer does not place |
|
|
Rename. |
|
|
Rename ( |
Quarkus Dev Mode hot reload |
No equivalent |
The cycle is |
Notable differences
-
A128CBC-HS256unsupported — Cervantes only implementsA256GCMas JWE content-encryption algorithm (the spec default, covered by the TCK). To be added if an issuer requires it. -
No hot reflection —
@Claiminjection is resolved by a Vauban BCE at CDI compile time, not by a dynamic proxy. If you relied on an exotic SmallRye typing convention (for instance@Claim List<Integer>on a numeric claim stored as a string), check that the concrete type is in the supported list (see Reference). -
No
setAccessible(true)— any business class that must receive a@Claiminjection must be normally visible to CDI (@Dependent,@RequestScoped, …). If SmallRye opened runtime packages, Cervantes does not — open explicitly inmodule-info.java. -
mp.jwt.verify.publickey.location— PEM-vs-JWKS auto-detection is based on the format of the content, not on the file extension. A URL returning a valid JWK Set is treated as JWKS, whether it ends with.json,.jwks, or nothing. -
JWKS — lazy refresh — Cervantes does not fetch the JWK Set at startup. The first unknown
kidtriggers the fetch. Upside: fast startup, no fail-fast if the issuer is temporarily down. Downside: the first request may be slightly slower.
Classpath footprint compared
| Choice | Runtime libs pulled in |
|---|---|
SmallRye JWT |
|
Cervantes |
|
Porting checklist
-
Replace the SmallRye JWT dependency with
cervantes-cdi-vauban+cervantes-jaxrs(or simply thevidocq-runtime-cervantes-jwt-extensionwrapper if you package through Vidocq Runtime). -
Audit application annotations: they must all come from
org.eclipse.microprofile.jwt.andjakarta.annotation.security.. Replace anyio.smallrye.jwt.*annotation. -
Migrate
smallrye.jwt.properties to their standardmp.jwt.equivalents. -
Verify that the expected claims really exist on the tokens:
iss,aud,exp,groups. No exotic path-based remapping. -
Run unit tests:
./mvnw test. -
Run the TCK to validate conformance:
./run-official-tck-mp-jwt-2.1.sh(see TCK). -
Verify in a staging environment: a valid token passes through with 200, an expired one with 401, a missing role with 403.
-
Measure validation latency and compare (see Reference and
BENCH.md). Cervantes is ~1.5× slower than SmallRye on the RS256 hot-path — a deliberate trade-off against ~3 MB of vanished transitive dependencies.