Jakarta EE verständlich erklärt – mit diesen APIs baust du moderne Enterprise-Anwendungen

In diesem Beitrag geben wir einen Überblick über die wichtigsten Jakarta EE Standards und APIs, die für die Entwicklung moderner Java-Enterprise-Anwendungen unverzichtbar sind. Erfahre, wie diese Technologien helfen, skalierbare und wartbare Lösungen zu erstellen.

Enterprise-Anwendungen in Java – leistungsstark, modular und besser denn je: Mit Jakarta EE steht dir ein Standard-Set an Werkzeugen zur Verfügung, mit denen du von Messaging bis Security alles abdeckst. In dieser Beitragsreihe lernst du die wichtigsten kennen – praxisnah und auf einen Blick.

MIME-Typen clever verarbeiten – mit Jakarta Activation

Jakarta Activation hilft dir dabei, Inhalte anhand ihres MIME-Typs dynamisch zu verarbeiten – typischerweise bei E-Mails oder Webservices. Du registrierst passende Verarbeitungskomponenten, z. B. für Text oder Bilder.

<dependency>
<groupId>jakarta.activation</groupId>
<artifactId>jakarta.activation-api</artifactId>
</dependency>

import jakarta.activation.*;
import java.io.*;

public class MimeProcessor {

public static void main(String[] args) {
MailcapCommandMap commandMap = new MailcapCommandMap();
commandMap.addMailcap(„text/plain;; x-java-content-handler=com.example.TextHandler“);
commandMap.addMailcap(„image/jpeg;; x-java-content-handler=com.example.ImageHandler“);
CommandMap.setDefaultCommandMap(commandMap);

DataSource source = new FileDataSource(„beispiel.txt“);
DataHandler handler = new DataHandler(source);

try (InputStream is = handler.getInputStream()) {
System.out.println(„Typ: “ + handler.getContentType());
System.out.println(„Inhalt: “ + new String(is.readAllBytes()));
} catch (IOException e) {
e.printStackTrace();
}
}
}

Weniger Boilerplate dank Jakarta Annotations

Mit Jakarta Annotations stattest du Klassen mit Metadaten aus – etwa für Ressourcen-Injektion, Lebenszyklussteuerung oder Konfiguration. So reduziert sich dein Code enorm.

<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
</dependency>

import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import javax.sql.DataSource;

public class ResourceBean {

@Resource(name = „jdbc/MyDataSource“)
private DataSource dataSource;

@PostConstruct
public void init() {
System.out.println(„Datenquelle fertig: “ + dataSource);
}
}

Sicherheit ab Werk – mit Jakarta Authentication

Mit Jakarta Authentication kannst du eigene Login-Mechanismen erstellen. Der Container übernimmt die Integration – du kümmerst dich nur um die Regeln.

<dependency>
<groupId>jakarta.authentication</groupId>
<artifactId>jakarta.authentication-api</artifactId>
</dependency>

import jakarta.security.enterprise.*;
import jakarta.security.enterprise.authentication.mechanism.http.*;
import jakarta.security.enterprise.identitystore.*;
import jakarta.security.enterprise.credential.*;
import jakarta.inject.Inject;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.*;

@BasicAuthenticationMechanismDefinition(realmName = „example“)
@EmbeddedIdentityStoreDefinition({
@EmbeddedIdentityStoreDefinition.User(name = „user“, password = „password“, roles = „user“),
@EmbeddedIdentityStoreDefinition.User(name = „admin“, password = „admin“, roles = „admin“)
})
public class SimpleAuthenticationMechanism implements AuthenticationMechanism {

@Inject
private IdentityStoreHandler identityStoreHandler;

@Override
public AuthenticationStatus validateRequest(HttpServletRequest request, HttpServletResponse response, HttpMessageContext context) throws ServletException {
if (context.isProtected() && !context.isAuthenticationCompleted()) {
UsernamePasswordCredential credential = new UsernamePasswordCredential(
request.getParameter(„username“),
request.getParameter(„password“)
);

CredentialValidationResult result = identityStoreHandler.validate(credential);

if (result.getStatus() == CredentialValidationResult.Status.VALID) {
return context.notifyContainerAboutLogin(result.getCallerPrincipal(), result.getCallerGroups());
} else {
return context.responseUnauthorized();
}
}
return context.doNothing();
}
}

Rollenbasiert zugreifen – mit Jakarta Authorization

Mit der Authorization-API vergibst du klar definierte Rollen und schützt Methoden direkt im Code – einfach und sicher.

<dependency>
<groupId>jakarta.authorization</groupId>
<artifactId>jakarta.authorization-api</artifactId>
</dependency>

import jakarta.annotation.security.*;

@DeclareRoles({„user“, „admin“})
public class SecureResource {

@RolesAllowed(„admin“)
public void adminOnly() {
System.out.println(„Admin-Zugriff erlaubt.“);
}

@RolesAllowed({„user“, „admin“})
public void forUsers() {
System.out.println(„Zugriff für Benutzer oder Admin.“);
}
}

Große Datenmengen effizient verarbeiten – mit Jakarta Batch

Perfekt für wiederkehrende Jobs wie Rechnungsversand, Datenimporte oder regelmäßige Prozesse: Jakarta Batch bietet dir eine XML-gesteuerte Verarbeitung mit voller Kontrolle.

<dependency>
<groupId>jakarta.batch</groupId>
<artifactId>jakarta.batch-api</artifactId>
</dependency>

import jakarta.batch.api.AbstractBatchlet;
import jakarta.batch.api.listener.JobListener;
import jakarta.batch.runtime.context.JobContext;
import jakarta.inject.*;

@Named
public class SimpleBatchlet extends AbstractBatchlet {

@Inject
private JobContext jobContext;

@Override
public String process() {
String propValue = jobContext.getProperties().getProperty(„batchProp“);
System.out.println(„Batchlauf mit Property: “ + propValue);
return „COMPLETED“;
}
}

@Named
public class CustomJobListener implements JobListener {

@Override
public void beforeJob() {
System.out.println(„Job startet gleich.“);
}

@Override
public void afterJob() {
System.out.println(„Job abgeschlossen.“);
}
}

<job id=“simpleBatchJob“ xmlns=“http://xmlns.jcp.org/xml/ns/javaee“ version=“1.0″>
<step id=“step1″>
<batchlet ref=“SimpleBatchlet“>
<properties>
<property name=“batchProp“ value=“value1″/>
</properties>
</batchlet>
<listeners>
<listener ref=“CustomJobListener“/>
</listeners>
</step>
</job>

CDI: Saubere Abhängigkeiten und Lebenszyklussteuerung

Mit Jakarta CDI steuerst du den Lebenszyklus und die Injektion von Beans – ideal für modulare, testbare Architekturen.

<dependency>
<groupId>jakarta.enterprise</groupId>
<artifactId>jakarta.enterprise.cdi-api</artifactId>
</dependency>

import jakarta.enterprise.context.RequestScoped;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;

@RequestScoped
public class MessagePrinter {

@Inject
private MessageService messageService;

public void printMessage() {
System.out.println(messageService.getMessage());
}
}

@ApplicationScoped
public class MessageService {
public String getMessage() {
return „Hello, CDI!“;
}
}

Nebenläufigkeit kontrolliert umgesetzt – mit Jakarta Concurrency

Du möchtest Tasks asynchron ausführen – aber containerfreundlich und verwaltet? Jakarta Concurrency macht’s möglich.

<dependency>
<groupId>jakarta.enterprise.concurrent</groupId>
<artifactId>jakarta.enterprise.concurrent-api</artifactId>
</dependency>

import jakarta.annotation.Resource;
import jakarta.enterprise.concurrent.ManagedExecutorService;
import java.util.concurrent.*;

public class ConcurrencyExample {

@Resource
private ManagedExecutorService managedExecutorService;

public void executeTask() throws Exception {
Future<String> result = managedExecutorService.submit(() -> „Task abgeschlossen!“);
System.out.println(result.get());
}
}

Konfiguration zentral verwalten – mit Jakarta Config

Ob Umgebungsvariablen, Properties-Dateien oder Cloud – Konfigurationen kannst du mit Jakarta Config typisiert und zentral einlesen.

<dependency>
<groupId>jakarta.config</groupId>
<artifactId>jakarta.config-api</artifactId>
</dependency>

app.name=JakartaApp
max.users=100

import jakarta.config.Config;
import jakarta.config.ConfigProvider;
import jakarta.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class AppConfig {

private final String appName;
private final int maxUsers;

public AppConfig() {
Config config = ConfigProvider.getConfig();
this.appName = config.getValue(„app.name“, String.class);
this.maxUsers = config.getValue(„max.users“, Integer.class);
}

public void printConfig() {
System.out.println(„App: “ + appName);
System.out.println(„Maximale Nutzer: “ + maxUsers);
}
}

Externe Systeme anbinden – mit Jakarta Connectors

Wenn du mit einem ERP, CRM oder anderen Enterprise-System kommunizieren musst, helfen dir Jakarta Connectors über standardisierte Ressourcen-Adapter.

<dependency>
<groupId>jakarta.resource</groupId>
<artifactId>jakarta.resource-api</artifactId>
</dependency>

import jakarta.annotation.Resource;
import jakarta.resource.cci.*;

public class SimpleJcaExample {

@Resource(name = „eis/SimpleConnectionFactory“)
private ConnectionFactory connectionFactory;

public void executeSimpleInteraction() {
try (Connection connection = connectionFactory.getConnection()) {
System.out.println(„EIS-Verbindung erfolgreich.“);
} catch (Exception e) {
e.printStackTrace();
}
}
}

Datenzugriff leicht gemacht – mit Jakarta Data

Jakarta Data bietet dir ein Repository-Vorgehen wie in Spring: Methoden wie findByName generieren automatisch deine Queries.

<dependency>
<groupId>jakarta.data</groupId>
<artifactId>jakarta.data-api</artifactId>
</dependency>

import jakarta.data.repository.CrudRepository;

public interface ProductRepository extends CrudRepository<Product, Long> {
List<Product> findByName(String name);
}

Deployment-Daten per API – mit Jakarta Deployment

Diese API wird häufig von Containern genutzt, um Informationen über Deployments zu erhalten – für dich als Entwicklerin meist im Hintergrund relevant.

<dependency>
<groupId>jakarta.deployment</groupId>
<artifactId>jakarta.deployment-api</artifactId>
</dependency>

Simple Injektion ohne Lifecycle – mit Jakarta Inject

Für einfache Dependency Injection ohne Kontextverwaltung kommt Jakarta Inject zum Einsatz – geradlinig und effizient.

<dependency>
<groupId>jakarta.inject</groupId>
<artifactId>jakarta.inject-api</artifactId>
</dependency>

import jakarta.inject.Inject;
import jakarta.inject.Named;

@Named
public class SimpleService {
public String getInfo() {
return „Hello from SimpleService!“;
}
}

public class Consumer {

@Inject
private SimpleService simpleService;

public void displayServiceInfo() {
System.out.println(simpleService.getInfo());
}
}

Fazit: Der Werkzeugkasten für moderne Java-Anwendungen

Ob Datei-Handling, Datenmanagement oder Sicherheit: Jakarta EE liefert dir robuste Bausteine, um skalierbare, wartbare und standardisierte Enterprise-Anwendungen zu entwickeln. Schritt für Schritt kombinierst du genau die Komponenten, die du brauchst.

Fortsetzung folgt …
Im zweiten Teil zeigen wir dir APIs für JSON, Messaging, Webservices u. v. m.

Weiterführende Links

Offizielle Jakarta EE Spezifikationen

Mehr zu Softwaretechnologien bei doubleSlash

Quellen

https://jakarta.ee/specifications/

Jakarta EE ist ein Projekt der Eclipse Foundation. Das Logo ist ein eingetragenes Markenzeichen.

Der Beitrag Jakarta EE verständlich erklärt – mit diesen APIs baust du moderne Enterprise-Anwendungen erschien zuerst auf Business -Software- und IT-Blog – Wir gestalten digitale Wertschöpfung.