So, heute mal wieder ein Artikel aus dem tiefen Tal der lustigen Softwarefrickeleien. Ich habe mich am Wochenende mal intensiv mit JEE, Eclipse und Maven und dem Zusammenspiel dieser Dinge auseinandergesetzt. Die nächste Version des LinuxTag eTicket-Systems soll voll auf JEE setzen.
Maven mit Eclipse für JEE-Projekte zusammenzubringen ist nicht so ganz einfach. Deswegen hier eine kleine How-To.
Seltsamerweise existieren im Netz keine wirklich verwendbaren "Kochrezepte" dafür, obwohl es sich aus meiner Sicht um ein "Standardproblem" handelt.
Ziel ist es, die Vorzüge von Eclipse bei der Entwicklung von JEE-Modulen zu nutzen (Hotdeployment, Servermanagement, Debugging usw.) und gleichzeitig die volle Buildfähigkeit über Maven zu erhalten.
Dazu muss man grundlegend einen anderen Weg gehen, als das bei JSE-Projekten der Fall ist: statt ein Projekt zunächst auf der Maven-Ebene aufzubauen und dann von Maven die Eclipse-Settings über "mvn eclipse:eclipse" erzeugen zu lassen, muss ein JEE-Projekt von Eclipse her aufgebaut werden. Maven ist deutlich flexibler anpassbar als die JEE-Eclipse-Plugins.
Schritt 1: Eclipse JEE-Projekte anlegen
Über die ganz normalen Wizards wird ein JEE-Projekt mit allen Untermodulen angelegt. Für das Beispiel gehe ich von folgenden einzelnen Eclipse-Projekten aus:
Projekt, das die EJBs enthält. Hier werden (abweichend vom Eclipse-Standard) später auch die Domain-Klassen und die Remote-Stubs der EJB abgelegt. Maven erzeugt beim Releasebuild automatisch ein abgespecktes Client-JAR, dass nur die vom Client benötigten Klassen enthält. Während des Eclipse-Workflows werden die Klassen dieses Moduls vollständig mit dem Client deployt, liegen also zweimal physikalisch auf dem Server, falls der Client eine JEE-Serveranwendung wie z.B. ein WAR ist. (einmal beim EJB, einmal beim Client). Das ist verschmerzbar, stört nicht und ist durch die Eclipse-Governance auch sicher konsistent.
DemoServlet Der Client für die EJBs in Form einer JEE-Weblayer-Anwendung. Hier sind Standard-Servlets und/oder JSPs enthalten, die über JNDI auf die EJBs zugreifen. Externe Clients sind ebenfalls möglich, aber der JEE-Client ist der in diesem Fall komplexere Fall, weil das WAR ebenfalls deployt werden muss.
DemoEAR Das umgebende EAR-Projekt, dass aus dem EJB und dem WAR des Clients ein deploybares EAR-Archiv erzeugt. Da Maven kein gemeinsames Artefakt- und POM-Multiprojekt erlaubt, ist das EAR-Projekt ebenfalls ein Maven-Subprojekt.
Beim Erstellen der Projekte muss auf die Projektabhängigkeit geachtet und ggf. angepasst werden. Eclipse geht im Standardfall davon aus, dass Domainklassen und Stub-Interfaces im Client angesiedelt sind. Maven erwartet diese Klassen aber im Serverprojekt und generiert lieber daraus ein getrenntes Client-JAR für den Client mit diesen Klassen. Aus meiner Sicht sauberer und Eclipse auch einfach beibringbar ist der Maven-Weg. Dazu müssen die Abhängigkeiten folgendermaßen eingestellt sein:
DemoEJB hat keine definierten Abhängigkeiten. Sind die Abhängigkeiten eingestellt müssen nun die Pfade "Maven-like" angepasst werden. Dazu müssen die Java-Sources von den restlichen Resources getrennt und im üblichen Verzeichnisschema angeordnet werden. Dies ist über die Projekt-Properties unter "Java Build Path -> Source" zu erledigen.
Mit der jetzt vorliegenden Einstellung kann dann ein Deployment-Server definiert werden und das Projekt über Eclipse normal genutzt werden. Hot-Deployment und Debugging funktioniert direkt aus Eclipse heraus.
Als nächstes müssen die Maven-Einstellungen hinzugefügt werden, damit das Gesamtprojekt per Maven bau- und deploybar wird.
Schritt 2: Maven-Konfiguration
Die Verzeichnisstruktur in Eclipse sieht im Moment folgendermaßen aus:
- workspace + DemoEAR + DemoEJB + DemoServlet
Für die Maven-Konfiguration legen wir ein Hüllprojekt um die drei Einzelprojekte. Dieses Hüllprojekt ist für Eclipse nicht notwendig und nur für die "Projektklammer" des Multi-Projekts für Maven nötig. Aus diesem Grund wird dieses Hüllprojekt am besten von Hand angelegt und über die Kommandozeilentools ins SVN eingecheckt.
Für die Entwicklung bedeutet das, dass das Arbeiten und Bauen mit Maven und Eclipse leicht unterschiedlich erfolgt. Die Zielverzeichnis bzw. Projektstruktur sieht so aus:
In Eclipse wird dann nicht das Hüllprojekt ausgecheckt und genutzt, sondern nur die drei Subprojekte. Die Einstellungen des Hüllprojekts sind nur für einen Maven-Build nötig. In diesem Fall wird das Gesamtprojekt ausgecheckt und per "mvn package" das resultierende EAR-Archiv im Subprojekt "DemoEAR" gebaut.
POM des Hüllprojekts
Die POM des Hüllprojekts ist recht simpel. Sie besteht aus einem einfachen Multi-POM mit zusätzlichen Repository-Einstellungen:
Das JBoss-Repository ist für die Abhängigkeiten zu den JEE-Bibliotheken nötig, die in den Subprojekten definiert sind. Das Projekt wird damit gegen die JEE-JBoss-Implementierung gebaut. Das bedeutet explizit nicht, dass die resultierenden JEE-Module nicht in anderen Appservern laufen, die Bibliotheken werden als "provided" dort vorausgesetzt und nicht mit gepackaged. JBoss bietet eine zertifizierte JEE 1.5-Implementierung. Trotzdem sollten wir uns dafür im nicht-JBoss-Fall noch ein paar Gedanken zur QS machen, das nur am Rande.
POM von DemoEJB
Das DemoEJB-Projekt ist ein einfaches Maven-Projekt, dass das EJB-Plugin verwendet, um ein EJB-Jar zu erstellen.
Falls weitere JEE-Abhängigkeiten benötigt werden, können diese hier hinzugefügt werden. Als Parent wird das Hüllprojekt angegeben. Die JBoss-Repository-Definitionen werden von dort geerbt.
Die "generateClient"-Einstellung sorgt dafür, dass ein zusätzliches "virtuelle" Artefakt erstellt und dem virtuellen Repository hinzugefügt wird. Auf dieses referenzieren wir dann später in den Abhängigkeiten des Clients. Dieses spezielle Client-JAR enthält nur die Entities und die Stubs. In der Konfiguration kann über weitere Parameter noch genauer angegeben werden, welche Bestandteile des EJB-Codes in den Client gepackaged werden. Genauere Infos dazu sind in der Plugin-Dokumentation zu finden.
POM des Clients
Das Client-Projekt "DemoServlet" ist ein Standard-WAR-Projekt, dass aber zusätzlich eine Abhängigkeit zur zuvor erstellen "virtuellen" Client-Bibliothek enthält:
Statt "ejb" wird "ejb-client" als Typ angegeben. Würde "ejb" angegeben, so würde der gesamte Code des EJB-Projektes im resultierenden WAR mitgepackaged werden.
POM des EAR-Projekts
Das EAR-Projekt baut aus den vorhandenen Artefakten das EAR zusammen und deployt es optional auch direkt in einem JBoss-Server. Das EAR-Projekt enthält selbst keinen Quellcode dafür aber die EAR-Deployment-Deskriptoren.
Problematisch ist die Einstellung des JBoss-Homedirs. Diese Einstellung ist im Moment leider nicht extern einstellbar. Allerdings ist die Nutzung des JBoss-Plugins nur nötig, wenn direkt aus Maven heraus deployt werden soll.
Bauen und Deployen
Damit ist die Konfiguration insgesamt fertig. Unter Eclipse lassen sich die Projekte normal mit den Eclipse-Bordmitteln nutzen. Will man einen Maven-Build vornehmen, so wird das Hüllprojekt ausgecheckt und mit "mvn package" das Projekt gebaut. Nach dem Vorgang liegt im EAR-Projekt das fertige EAR-Archiv.
Keine Kommentare:
Kommentar veröffentlichen