Heute nehmen wir uns diese Akronyme vor. Wir schauen uns an, was sie bedeuten, wofür du sie brauchst und wo die feinen, aber wichtigen Unterschiede liegen – besonders im Kontext deiner Java EE-Web-Anwendungen.
Stell dir vor, du hast eine wunderschöne Webseite mit JSF und PrimeFaces gebaut. Du hast deine .xhtml-Dateien für das Layout, deine Managed Beans (Java-Klassen, die die Logik hinter deinen Seiten steuern) und vielleicht noch ein paar CSS-Styles und JavaScript-Dateien. All diese Dinge gehören zusammen und bilden deine Webanwendung.
Ein WAR (Web Application Archive) ist im Grunde ein standardisiertes Dateiformat (ähnlich wie eine ZIP-Datei, aber mit einer speziellen Struktur), in dem du all diese Komponenten deiner Webanwendung bündelst. Es ist der Weg, wie du deine fertige Webanwendung auf einem Server bereitstellst (deployst).
Angenommen, du hast eine JSF-Seite hello.xhtml und eine zugehörige Managed Bean HelloBean.java:
// src/main/java/com/example/HelloBean.java
package com.example;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
@ManagedBean
@RequestScoped
public class HelloBean {
private String name = "Welt";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String sayHello() {
return "Hallo, " + name + "!";
}
}
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Hallo Welt!</title>
</h:head>
<h:body>
<h:form>
<p:inputText value="#{helloBean.name}" />
<p:commandButton value="Grüßen" action="#{helloBean.sayHello}" update="@form" />
<h:outputText value="#{helloBean.sayHello()}" />
</h:form>
</h:body>
</html>
Wenn du dieses Projekt baust, wird es in ein yourwebapp.war-File gepackt. Dieses WAR-File kannst du dann auf einem Application Server (wie WildFly, GlassFish oder Apache TomEE) deployen, und schwupps, deine Webanwendung ist live!
Kurz gesagt: Das WAR ist die standardisierte Verpackungseinheit für deine Webanwendung. Es enthält alles, was für die Anzeige und die grundlegende Logik deiner Oberfläche benötigt wird.
Während das WAR deine Web-Oberfläche und die damit verbundene Logik enthält, sind EJBs (Enterprise JavaBeans) spezialisierte Java-Klassen, die für die Kapselung und Bereitstellung von Unternehmenslogik zuständig sind. Stell dir vor, du hast sehr wichtige Geschäftsregeln, Datenbankzugriffe oder komplizierte Berechnungen, die nicht direkt an eine Webseite gebunden sind, sondern von verschiedenen Teilen deiner Anwendung (oder sogar von anderen Anwendungen) genutzt werden sollen. Genau hier kommen EJBs ins Spiel.
EJBs bieten dir eine Reihe von Vorteilen, die besonders in komplexen Unternehmensanwendungen wichtig sind:
Angenommen, du möchtest einen Service haben, der Produkte aus einer Datenbank lädt. Das wäre ein perfekter Kandidat für eine Stateless Session Bean:
// src/main/java/com/example/ProductService.java
package com.example;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.List;
@Stateless // Macht diese Klasse zu einer Stateless Session Bean
public class ProductService {
@PersistenceContext // Injiziert einen EntityManager für den Datenbankzugriff
private EntityManager em;
public List<Product> getAllProducts() {
// Hier würde die Logik stehen, um Produkte aus der Datenbank zu laden
// Beispielhaft geben wir eine leere Liste zurück
return em.createQuery("SELECT p FROM Product p", Product.class).getResultList();
}
public Product getProductById(long id) {
return em.find(Product.class, id);
}
}
Diese EJB würde typischerweise in einem separaten JAR-File verpackt, oder sie könnte auch Teil eines EAR-Files (Enterprise Application Archive) sein, das wir hier aber nicht im Detail behandeln.
Dein WAR (deine JSF-Anwendung) kann deine EJBs nutzen! Du kannst einfach eine EJB in deine Managed Bean injizieren (ein häufiges Muster ist, eine Managed Bean als "Controller" zu nutzen, die dann Services von EJBs aufruft):
// src/main/java/com/example/ProductManagedBean.java
package com.example;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.view.ViewScoped; // Für JSF 2.2+
import java.util.List;
@ManagedBean
@ViewScoped
public class ProductManagedBean {
@EJB // Injiziert die ProductService EJB
private ProductService productService;
private List<Product> products;
private Product selectedProduct;
@PostConstruct
public void init() {
products = productService.getAllProducts();
}
public List<Product> getProducts() {
return products;
}
public void setProducts(List<Product> products) {
this.products = products;
}
public Product getSelectedProduct() {
return selectedProduct;
}
public void setSelectedProduct(Product selectedProduct) {
this.selectedProduct = selectedProduct;
}
// Beispielmethode, die die EJB nutzt
public String viewProductDetails() {
if (selectedProduct != null) {
// Lade Details über die EJB, falls nötig
selectedProduct = productService.getProductById(selectedProduct.getId());
return "productDetails.xhtml"; // Navigiere zu einer Detailseite
}
return null;
}
}
In diesem Beispiel wird der ProductService (deine EJB) automatisch vom Application Server in deine ProductManagedBean injiziert. Deine JSF-Anwendung kann dann die Methoden des ProductService aufrufen, um mit der Datenbank zu interagieren, ohne sich um Transaktionen oder andere Enterprise-Details kümmern zu müssen – das übernimmt alles der EJB-Container!
| Merkmal | WAR | EJB |
| Zweck | Verpackung von Webanwendungen (JSF, Servlets, JSPs, HTML, CSS, JS) | Kapselung und Bereitstellung von Unternehmenslogik (Transaktionen, Sicherheit, Skalierbarkeit) |
| Inhalt | Webressourcen, JSF-Seiten, Managed Beans, Servlets | Java-Klassen mit Geschäftslogik, oft mit Datenbankzugriff |
| Lebenszyklus | Wird vom Web-Container (Teil des Application Servers) verwaltet | Wird vom EJB-Container (Teil des Application Servers) verwaltet |
| Direkte Interaktion | Direkt vom Browser über HTTP aufrufbar | Indirekt aufrufbar, typischerweise von anderen Java-Komponenten (z.B. Managed Beans) oder Remote-Clients |
| Deployment-Einheit | .war Datei | .jar Datei (für einzelne EJBs) oder Teil eines .ear (Enterprise Application Archive) |
| Typische Nutzung | User Interfaces, Web-Services (REST/SOAP Endpunkte im WAR) | Geschäftslogik, Datenzugriffsschicht, komplexe Berechnungen, Messaging, Scheduler |
Ein WAR ist der Container für deine sichtbare Webanwendung – deine JSF-Seiten, PrimeFaces-Komponenten und die zugehörige Logik, die direkt mit der UI interagiert (deine Managed Beans). Es ist das, was der Nutzer in seinem Browser sieht und bedient.
EJBs hingegen sind die unsichtbaren Helden im Hintergrund. Sie beherbergen die Kernlogik deiner Anwendung, die Geschäftsregeln, Datenbankoperationen und alles, was eine hohe Zuverlässigkeit, Sicherheit und Skalierbarkeit erfordert. Sie werden von deinem Application Server verwaltet und bieten dir eine leistungsstarke Infrastruktur, um komplexe Enterprise-Anwendungen zu bauen.
Im Zusammenspiel bilden WARs und EJBs ein starkes Team: Dein WAR präsentiert die Daten und ermöglicht die Interaktion, während die EJBs die schwere Arbeit im Hintergrund erledigen, deine Daten verwalten und die Geschäftslogik implementieren. Mit JSF und PrimeFaces im WAR und deinen EJBs als Business-Services hast du ein robustes Fundament für deine Java EE-Anwendungen!
