Overview
Jakarta EE (Java EE after the Eclipse handover, with the javax.* → jakarta.* namespace
move as of EE 9) and MicroProfile are contract layers: specifications with independent
implementations, not frameworks themselves. The three big frameworks relate to them very
differently — Quarkus largely implements the specs, Spring largely shadows them with
its own equivalent APIs while consuming a few implementations, and Micronaut ships its own
APIs on a JSR-330 lineage. Knowing the correspondence lets you translate skills and
libraries between stacks instantly.
Key points
- Jakarta EE defines the enterprise contracts (CDI, REST, Persistence, Servlet, Validation, Messaging, Transactions, Security…); application servers implement the platform, Quarkus implements the smaller core profile.
- MicroProfile layers microservice concerns (Config, Health, Metrics, OpenAPI, Rest Client, Fault Tolerance) on top of a CDI/JAX-RS base; SmallRye is the implementation family Quarkus ships.
- Spring implements few specs directly but consumes reference-grade implementations: Hibernate ORM for JPA, Hibernate Validator for Bean Validation, Tomcat/Jetty for Servlet.
- Micronaut is mostly equivalents: own DI (JSR-330 annotations), own HTTP layer, own Data — with opt-in bridges to Hibernate/JPA and Jakarta Validation.
- Portability consequence: JPA entities and Bean Validation annotations move between all three nearly unchanged; controller/DI layers always need rewriting to or from Spring/Micronaut idioms.
Details
Legend: ✔ implements the spec (a certified/spec-tracking implementation is on the classpath) · ≈ own equivalent API covering the same ground · — not applicable / no first-party story.
Jakarta EE specs
| Spec / API | Spring (Boot 3.x) | Quarkus | Micronaut |
|---|---|---|---|
| CDI (Jakarta Contexts & DI) | ≈ Spring DI (spring-context); different model, similar reach |
✔ ArC (CDI-lite, build-time) | ≈ Micronaut Inject — JSR-330 (jakarta.inject) annotations, own container |
| JAX-RS (Jakarta REST) | ≈ Spring MVC / WebFlux annotations | ✔ RESTEasy Reactive | ≈ Micronaut HTTP (@Controller/@Get) |
| JPA (Jakarta Persistence) | ✔ consumed via Hibernate ORM (Spring Data JPA on top) | ✔ Hibernate ORM (+ Panache) | ≈ Micronaut Data (compile-time) or ✔ via micronaut-data-hibernate-jpa |
| Servlet | ✔ consumed via embedded Tomcat/Jetty/Undertow (MVC stack) | ✔ optional (quarkus-undertow); default is Vert.x HTTP, not servlet |
— Netty-based server, no servlet container (WAR deployment aside) |
| Bean Validation (Jakarta Validation) | ✔ consumed via Hibernate Validator | ✔ Hibernate Validator | ✔/≈ honors jakarta.validation annotations via reflection-free micronaut-validation |
| JSON-B / JSON-P | ≈ Jackson by default (JSON-B optional) | ✔ Yasson (JSON-B) or Jackson | ≈ Micronaut Serialization (micronaut-serde, Jackson-compatible) |
| JMS (Jakarta Messaging) | ✔ consumed via spring-jms + a broker client (Artemis) |
≈ prefers Reactive Messaging; quarkus-artemis-jms extension exists |
— no first-party JMS; own Kafka/RabbitMQ modules |
| JTA (Jakarta Transactions) | ≈ Spring @Transactional / PlatformTransactionManager (JTA optional) |
✔ Narayana transaction manager | ≈ Micronaut's own @Transactional management (JTA-compatible annotations) |
| Jakarta Security | ≈ Spring Security (filter chain, own API) | ✔/≈ Quarkus Security + Elytron lineage; quarkus-oidc for OIDC |
≈ Micronaut Security (own module) |
| WebSocket (Jakarta WebSocket) | ≈ spring-websocket (+ STOMP) |
✔ quarkus-websockets (Jakarta WebSocket) and own WebSockets Next |
≈ Micronaut's own @ServerWebSocket |
MicroProfile specs
| Spec | Spring (Boot 3.x) | Quarkus | Micronaut |
|---|---|---|---|
| MP Config | ≈ Boot externalized config / @ConfigurationProperties |
✔ SmallRye Config | ≈ Micronaut configuration (@ConfigurationProperties) |
| MP Health | ≈ Actuator health endpoints | ✔ SmallRye Health | ≈ Micronaut Management health endpoints |
| MP Metrics | ≈ Actuator + Micrometer (de-facto standard; Quarkus uses it too) | ✔/≈ SmallRye Metrics, Micrometer now preferred | ≈ Micronaut Micrometer module |
| MP OpenAPI | ≈ springdoc-openapi (third-party de-facto) | ✔ SmallRye OpenAPI | ≈ micronaut-openapi (compile-time generation) |
| MP Rest Client | ≈ declarative HTTP interfaces (@HttpExchange) / OpenFeign |
✔ RESTEasy Reactive Rest Client | ≈ Micronaut declarative @Client |
Reading the table
The pattern: Quarkus is the standards citizen (ArC, RESTEasy, Hibernate, Narayana,
SmallRye — mostly ✔); Spring is a parallel universe with two big spec imports (JPA,
Bean Validation) and the Servlet container underneath; Micronaut re-implements the
ideas compile-time-first and keeps only the annotation vocabularies (jakarta.inject,
jakarta.validation) plus optional Hibernate. Note also what the table implies for
migrations: entities, validation constraints and (mostly) persistence code carry over;
anything touching DI wiring, security or the web layer is a rewrite.
Related
- Java application frameworks — the landscape — parent overview; positioning of the three stacks.
- Spring deep dive — the shadow-API column in detail.
- Quarkus deep dive — the spec-implementing column in detail.
- Micronaut deep dive — the equivalent-API column in detail.
- REST — JAX-RS vs Spring MVC annotations in practice.
- Frameworks × the stdlib contracts and Frameworks × tower/hyper — the same who-honors-what question against Go's stdlib interfaces and Rust's community crates.
- Health checks: liveness, readiness, startup — MicroProfile Health is the spec column behind the probe endpoints; Actuator and Micronaut Management are the equivalents.
- Correlation IDs & context propagation —
the per-stack filter contracts (
ContainerRequestFilteret al.) where request context is parsed.