All Jakarta EE templates

Modern Jakarta EE Rules

Jakarta EE 10+ namespace migration, modular architecture, and platform conventions.

DevZone Tools1,740 copiesUpdated Apr 15, 2026Jakarta EEJava
# CLAUDE.md — Modern Jakarta EE

## Version baseline

- Jakarta EE 10 (or 11). Java 21.
- All `javax.*` packages are renamed to `jakarta.*`. Do the migration once, completely. Mixed namespaces won't link.
- Pick a runtime: WildFly, Open Liberty, Payara, Glassfish. Stay current — old Java EE versions are not Jakarta EE 10.

## Architecture

- Layered: presentation (REST, Servlets) → service (CDI beans) → persistence (JPA).
- Use **CDI** as the central glue. Don't reach for EJBs in new code unless you specifically need transactions, timers, or remoting.
- Keep beans single-responsibility. A `@Stateless` bean with 30 methods is a refactor candidate.

## Modules

- Jakarta EE specs are now Maven artifacts under `jakarta.*` group IDs:
  - `jakarta.platform:jakarta.jakartaee-api:10.0.0` (compile-only API)
- Don't bundle the API in your WAR. The runtime provides it.
- Use **MicroProfile** alongside Jakarta EE for cloud-native concerns (config, health, metrics) — it complements rather than replaces.

## Packaging

- WAR for web apps. EAR only when you genuinely need multiple modules with isolated classloaders.
- Skinny WAR + provided dependencies — let the runtime supply the platform classes.
- `pom.xml`:
  ```xml
  <dependency>
      <groupId>jakarta.platform</groupId>
      <artifactId>jakarta.jakartaee-api</artifactId>
      <version>10.0.0</version>
      <scope>provided</scope>
  </dependency>
  ```

## Deployment descriptors

- Prefer annotations over `web.xml` / `ejb-jar.xml`. They survive refactors better.
- Use descriptors only for declarative things annotations can't express well (security roles in some contexts, JNDI overrides).
- Don't have both — pick a primary source. `metadata-complete="true"` to disable annotation scanning if descriptors are authoritative.

## Logging

- **java.util.logging** is the platform default but inconvenient. Use **SLF4J + Logback** (or whatever your runtime supplies, e.g., WildFly's logging).
- Configure structured JSON output for production observability stacks.

## Testing

- **Arquillian** for integration tests against a real container. Slower than unit tests but realistic.
- For unit tests, use plain JUnit 5 + Mockito. Most beans don't need a container to test.

## Don't

- Don't write new code against Java EE 8. Migrate to Jakarta EE 10+.
- Don't deploy multiple WARs that share state via static singletons. Use a JNDI-bound resource or a shared library.
- Don't `@PersistenceContext` into a `@RequestScoped` bean and expect lazy loading to work after the request ends.
- Don't pick Jakarta EE for a single-purpose microservice that doesn't use the platform features. Spring Boot or Quarkus is usually a better fit.

Other Jakarta EE templates