Cloud-Native Java with Jakarta EE 11 and MicroProfile 7
As enterprise applications shift to cloud-native architecture, traditional Java frameworks have been modernizing to keep pace. With the release of Jakarta EE 11 and MicroProfile 7, Java now offers a robust, standard-based foundation for building resilient, observable, and scalable microservices—without having to rely solely on Spring or heavy frameworks.
This article explores how Jakarta EE 11 and MicroProfile 7 are shaping the future of cloud-native Java. We’ll cover practical configuration patterns, showcase useful YAML snippets, and walk through how these technologies simplify key concerns like configuration, fault tolerance, observability, and deployment.
Why Jakarta EE 11 and MicroProfile 7?
Jakarta EE has evolved significantly since its transition from Java EE, and Jakarta EE 11 cements its focus on modular, cloud-native development. Meanwhile, MicroProfile is purpose-built for microservices, addressing modern concerns like health checks, metrics, tracing, and configuration.
Together, they offer:
- ✅ Standardized APIs for REST, DI, JSON, and CDI
- 🔧 Cloud-native essentials (circuit breakers, retries, health checks, metrics)
- ☁️ Seamless integration with Kubernetes, OpenShift, and cloud platforms
- 💡 No vendor lock-in, thanks to open standards and wide vendor support (Open Liberty, Payara, WildFly, etc.)
Core MicroProfile 7 Features (at a Glance)
| Feature | Spec/API Used |
|---|---|
| External Config | MicroProfile Config |
| Resilience Patterns | MicroProfile Fault Tolerance |
| Health Checks | MicroProfile Health |
| Metrics & Monitoring | MicroProfile Metrics |
| Distributed Tracing | MicroProfile Telemetry (OpenTelemetry-based) |
| API Documentation | MicroProfile OpenAPI |
| JWT Authentication | MicroProfile JWT Auth |
Each of these can be declaratively configured, often using application.yaml or environment variables—making containerized deployment easier.
Example: Building a Jakarta EE 11 Microservice with MicroProfile 7
Let’s say you’re building a simple product service with the following goals:
- Expose a REST API
- Read config from environment
- Implement fallback with retry logic
- Provide health and metrics endpoints
You can do all this without writing much boilerplate, thanks to Jakarta and MicroProfile.
ProductResource.java
@Path("/products")
@RequestScoped
public class ProductResource {
@Inject
Config config;
@Inject
ProductService productService;
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<Product> list() {
return productService.getAll();
}
}
ProductService.java with Fault Tolerance
@ApplicationScoped
public class ProductService {
@Retry(maxRetries = 3)
@Timeout(2000)
@Fallback(fallbackMethod = "fallbackProducts")
public List<Product> getAll() {
// Simulated database call
return fetchFromDb();
}
public List<Product> fallbackProducts() {
return List.of(new Product("default", "Fallback product"));
}
}
application.yaml: Cloud-Native Patterns
MicroProfile Config supports application.properties and application.yaml, which is better for Kubernetes readability.
Example application.yaml
mp:
config:
profile: dev
products:
cacheEnabled: true
health:
liveness:
path: /health/live
readiness:
path: /health/ready
metrics:
base:
enabled: true
vendor:
enabled: true
faultTolerance:
retry:
maxRetries: 3
delay: 500
tracing:
enabled: true
exporter: otlp
This YAML config can be mounted from ConfigMaps in Kubernetes, providing easy externalization.
Kubernetes Deployment Pattern
You can use Dockerfile + Kubernetes Deployment YAML with health and metrics endpoints auto-exposed:
Dockerfile (with Open Liberty example)
FROM icr.io/appcafe/open-liberty:kernel-slim-java17 COPY --chown=1001:0 target/app.war /config/dropins/ COPY src/main/liberty/config/server.xml /config/
Kubernetes Deployment YAML
apiVersion: apps/v1
kind: Deployment
metadata:
name: product-service
spec:
replicas: 2
selector:
matchLabels:
app: product-service
template:
metadata:
labels:
app: product-service
spec:
containers:
- name: product
image: your-org/product-service:1.0
ports:
- containerPort: 9080
env:
- name: MP_CONFIG_PROFILE
value: "dev"
readinessProbe:
httpGet:
path: /health/ready
port: 9080
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /health/live
port: 9080
Health and metrics are exposed automatically when using MicroProfile Health and Metrics specs.
Observability with MicroProfile
MicroProfile 7 now uses OpenTelemetry for distributed tracing. You can trace requests across services using tools like Jaeger, Grafana Tempo, or Honeycomb.
@Traced
@GET
@Path("/info")
public Response info() {
return Response.ok("Service Info").build();
}
MicroProfile Telemetry annotations generate trace spans automatically.
Secure Your Service with MicroProfile JWT
You can secure REST endpoints using JWT with minimal config.
Protecting Endpoints
@GET
@Path("/secure-data")
@RolesAllowed("user")
public Response secureData(@Claim("sub") String subject) {
return Response.ok("Hello, " + subject).build();
}
application.yaml
mp:
jwt:
verify:
publickey:
location: /opt/keys/public.pem
issuer: https://auth.example.com
Use Keycloak or any OIDC provider to issue the tokens.
Compatible Runtimes
You can run Jakarta EE 11 + MicroProfile 7 apps on:
- Open Liberty
- Payara Micro
- WildFly
- Helidon (supports MicroProfile APIs)
- Quarkus (uses MicroProfile under the hood)
Final Thoughts
Jakarta EE 11 and MicroProfile 7 are fully production-ready, cloud-native frameworks that provide all the capabilities you’d expect—resilience, observability, configuration, and security—without sacrificing simplicity or standards.
With simple YAML-based configuration and tight Kubernetes integration, you can confidently build, deploy, and scale Java microservices in the cloud-native world.
If you’re looking to modernize your Java stack without abandoning standards, this is your moment.

