Introduction: A New Chapter for Enterprise Java
The Java ecosystem is in a constant state of evolution, with exciting developments shaping the future of software development. From the latest OpenJDK releases and Java SE news focusing on features like virtual threads in Project Loom to the rapid advancements in frameworks, the landscape is more dynamic than ever. Amidst this flurry of activity, a significant milestone is marking a new era for enterprise applications: the growing adoption of the Jakarta EE 11 Core Profile. Recently, major players in the enterprise Java space, including Fujitsu, Open Liberty, and WildFly, have announced compatible implementations, signaling strong industry confidence in this modern, streamlined specification. This is pivotal Jakarta EE news, offering developers a powerful, standardized alternative to the full-stack platform, specifically tailored for building lightweight, cloud-native microservices and serverless functions. This article provides a comprehensive technical deep dive into the Jakarta EE 11 Core Profile, exploring its specifications, practical applications, and its place within the broader Java ecosystem news, including its relationship with Spring Boot and modern JVM features.
Section 1: What is the Jakarta EE 11 Core Profile?
For years, Java EE (and now Jakarta EE) has been the gold standard for building robust, scalable enterprise applications. However, the full platform, with its comprehensive suite of APIs, can be overkill for the microservices architecture that dominates modern cloud development. The Jakarta EE Core Profile was created to address this need, offering a curated subset of the full platform’s specifications, focusing on the essentials for building lean, efficient services.
The Philosophy: Less is More
The Core Profile’s design philosophy is centered on minimalism and performance. By excluding heavier, more traditional enterprise APIs like Jakarta Enterprise Beans (EJB), Jakarta Server Faces (JSF), and even Jakarta Persistence (JPA), it enables application servers to have a significantly smaller footprint, faster startup times, and lower resource consumption. This makes it an ideal choice for containerized environments like Docker and orchestration platforms like Kubernetes.
The Core Profile is not a replacement for the full platform but a specialized tool. It provides a standard, vendor-neutral foundation for microservices, ensuring that applications written against the Core Profile are portable across different compatible runtimes. This is a crucial piece of Java EE news for organizations looking to avoid vendor lock-in while embracing cloud-native patterns.
Key Specifications Included
The Jakarta EE 11 Core Profile is built upon a foundation of modern Java SE versions, requiring Java 17 as a minimum, allowing it to leverage language features from recent releases like Java 11 and Java 17. It includes the following key specifications:
- Jakarta CDI Lite 4.1: Provides a powerful, type-safe dependency injection framework, but in a “lite” version that allows for build-time optimization, further reducing startup overhead.
- Jakarta RESTful Web Services 3.1 (JAX-RS): The standard API for creating RESTful web services, forming the backbone of most microservice communication.
- Jakarta JSON Binding 3.0 (JSON-B): Offers a seamless, binding layer for converting Java objects to and from JSON documents with minimal boilerplate.
- Jakarta JSON Processing 2.1 (JSON-P): A lower-level API for parsing, generating, and transforming JSON using an object model or streaming model.
- Jakarta Annotations 2.1: A set of common annotations used across various Jakarta EE specifications.
- Jakarta Concurrency 3.0: Provides a standardized way to use concurrency utilities within a managed environment, ensuring threads and tasks are handled safely by the application server.
To get started with a Core Profile project, you can use build tools like Maven or Gradle. Here is a snippet from a pom.xml
file showing the primary dependency needed.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>core-profile-app</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<failOnMissingWebXml>false</failOnMissingWebXml>
</properties>
<dependencies>
<!-- This single dependency pulls in all APIs from the Core Profile -->
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-core-api</artifactId>
<version>11.0.0</version>
<scope>provided</scope>
</dependency>
<!-- JUnit 5 for testing -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.10.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>core-profile-app</finalName>
</build>
</project>
Section 2: Building a RESTful Microservice with the Core Profile
Let’s walk through building a simple “Product Service” to demonstrate how these specifications work together in a practical application. This service will expose a REST endpoint to retrieve product information.
Step 1: The JAX-RS Endpoint
The entry point for our service is a JAX-RS resource class. This class uses annotations to define the URL path and the HTTP methods it responds to. Notice how clean and declarative the code is.
package com.example.service;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
@Path("/products")
@ApplicationScoped
public class ProductResource {
@Inject
private ProductService productService;
@GET
@Path("/{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response getProductById(@PathParam("id") String id) {
return productService.findProductById(id)
.map(product -> Response.ok(product).build())
.orElse(Response.status(Response.Status.NOT_FOUND).build());
}
}
In this example, @Path("/products")
defines the base path for this resource. The getProductById
method is mapped to the subpath /{id}
and the HTTP GET
method. The @Produces(MediaType.APPLICATION_JSON)
annotation tells the JAX-RS runtime to automatically convert the returned object into a JSON string, using the underlying JSON-B provider.
Step 2: The CDI Service Bean
The business logic is encapsulated in a CDI (Contexts and Dependency Injection) bean. CDI is the glue that holds the application together, managing the lifecycle of components and injecting dependencies where needed. The @Inject
annotation in our ProductResource
is a prime example of CDI at work.
package com.example.service;
import com.example.model.Product;
import jakarta.enterprise.context.ApplicationScoped;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
@ApplicationScoped
public class ProductService {
// Using a simple in-memory map as a mock database
private final Map<String, Product> productDatabase = new ConcurrentHashMap<>();
public ProductService() {
// Pre-populate with some data
productDatabase.put("p123", new Product("p123", "Quantum Widget", 99.99));
productDatabase.put("p456", new Product("p456", "Flux Capacitor", 1250.00));
}
public Optional<Product> findProductById(String id) {
return Optional.ofNullable(productDatabase.get(id));
}
}
The @ApplicationScoped
annotation tells the CDI container to create a single instance of this class for the entire application. This service is then injected into our ProductResource
, decoupling the web layer from the business logic. This is a fundamental pattern for building testable and maintainable applications, a topic often covered in Java wisdom tips news.
Step 3: The Data Model with JSON-B
Finally, we need a simple Plain Old Java Object (POJO) to represent our product. Thanks to JSON-B, we don’t need any special annotations for basic serialization, making our model objects clean and focused on data.
package com.example.model;
// A simple record for immutability, leveraging modern Java features.
// JSON-B will automatically serialize this to JSON.
public record Product(String id, String name, double price) {
}
When a request is made to /products/p123
, JAX-RS calls our resource, which in turn calls the CDI service. The service returns a Product
record, and JSON-B handles the conversion to a JSON response like {"id":"p123","name":"Quantum Widget","price":99.99}
automatically.
Section 3: Advanced Topics and Ecosystem Integration
While the Core Profile is minimal, it’s designed to be extensible and work well with the broader Java ecosystem. This is where developers can leverage the latest Java performance news and concurrency models.
Managed Concurrency and Project Loom
The Jakarta Concurrency specification provides a ManagedExecutorService
, which is a container-managed thread pool. This is safer than creating your own threads, as the container can manage their lifecycle and context (like security context). This becomes especially powerful when combined with the latest JVM news, such as the introduction of virtual threads from Project Loom, finalized in Java 21.

While the Core Profile itself doesn’t mandate virtual threads, you can easily use them within tasks submitted to a ManagedExecutorService
on a compatible JVM. This can dramatically improve the throughput of I/O-bound applications by allowing a massive number of concurrent tasks to run without being limited by the number of platform threads. This synergy between standard enterprise APIs and cutting-edge JVM features is a major theme in current Java concurrency news.
Integration with External Libraries
The absence of JPA in the Core Profile is a deliberate design choice. For many microservices, a full-blown ORM like Hibernate might be unnecessary. Developers are free to choose the data access strategy that best fits their needs, whether it’s a lightweight library like JDBI, a reactive client for a NoSQL database, or even the full Hibernate ORM added as a standalone library. This flexibility is a key advantage.
Furthermore, this lean foundation is perfect for integrating modern AI and machine learning libraries. For instance, a developer could easily incorporate LangChain4j into a service bean to add generative AI capabilities, calling out to large language models. This aligns with the latest Spring AI news, demonstrating that the Jakarta EE ecosystem is just as capable of integrating these next-generation tools.
Section 4: Best Practices and Strategic Considerations
Adopting the Jakarta EE 11 Core Profile involves more than just writing code; it requires a shift in mindset towards building smaller, more focused services.
Choosing the Right Runtime
With compatible implementations from Open Liberty, WildFly, and Fujitsu, developers have excellent choices.
- Open Liberty: Known for its extremely fast startup times and dynamic configuration, making it ideal for developer productivity and containerized deployments.
- WildFly: A powerful and mature application server from Red Hat, offering a robust and feature-rich environment.
- Fujitsu: A long-time contributor to the Java EE and Jakarta EE space, providing a reliable, enterprise-grade implementation.

Testing Strategy
Testing is crucial. For unit testing your CDI beans and business logic, standard tools like JUnit and Mockito are perfect. For integration testing your JAX-RS endpoints, you can use libraries like REST-Assured, which provide a fluent API for making HTTP requests and asserting responses. Running these tests as part of a CI/CD pipeline managed by Maven or Gradle is a standard best practice.
When to Use Core Profile vs. Full Platform or Spring Boot
The choice between Jakarta EE Core Profile, the full Jakarta EE Platform, and other frameworks like Spring Boot depends on your project’s needs.
- Use Core Profile for: New microservices, serverless functions, or any application where a small footprint and fast startup are critical.
- Use Full Platform for: Monolithic applications or services that require a broader range of traditional enterprise features like JMS, JSF, or full EJB.
- Consider Spring Boot when: Your team is already heavily invested in the Spring ecosystem or requires its specific auto-configuration and opinionated dependency management.
Conclusion: The Future is Lean and Standardized
The growing support for the Jakarta EE 11 Core Profile is one of the most exciting pieces of Jakarta EE news in recent memory. It represents a maturation of the platform, acknowledging that one size does not fit all in the age of cloud-native computing. By providing a lightweight, standardized foundation for microservices, the Core Profile empowers developers to build fast, efficient, and portable applications without sacrificing the power of a managed enterprise environment.
As more vendors release compatible implementations and the community continues to build upon this foundation, the Core Profile is poised to become a cornerstone of modern enterprise Java development. For developers looking to stay current with Java news and build the next generation of applications, exploring the Jakarta EE 11 Core Profile is not just a good idea—it’s an essential next step.