<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Quendor &#187; java jee j2ee maven eclipse howto tutorial</title>
	<atom:link href="http://www.quendor.org/archiv/tag/java-jee-j2ee-maven-eclipse-howto-tutorial/feed" rel="self" type="application/rss+xml" />
	<link>http://www.quendor.org</link>
	<description>Full of Useful Facts</description>
	<lastBuildDate>Thu, 20 May 2010 14:26:51 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>JEE + Maven + Eclipse</title>
		<link>http://www.quendor.org/archiv/389</link>
		<comments>http://www.quendor.org/archiv/389#comments</comments>
		<pubDate>Sun, 12 Oct 2008 20:29:34 +0000</pubDate>
		<dc:creator>Michael Kleinhenz</dc:creator>
				<category><![CDATA[Technologie]]></category>
		<category><![CDATA[java jee j2ee maven eclipse howto tutorial]]></category>

		<guid isPermaLink="false">http://www.quendor.org/?p=389</guid>
		<description><![CDATA[.!.
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 [...]]]></description>
			<content:encoded><![CDATA[<div style="display:none">.!.</div>
<p>So, heute mal wieder ein Artikel aus dem tiefen Tal der lustigen Softwarefrickeleien. Ich habe mich am Wochenende mal intensiv mit <a href="http://java.sun.com/javaee/technologies/javaee5.jsp">JEE</a>, <a href="http://www.eclipse.org/">Eclipse</a> und <a href="http://maven.apache.org/">Maven</a> und dem Zusammenspiel dieser Dinge auseinandergesetzt. Die nächste Version des <a href="https://evolvis.org/projects/eticket/">LinuxTag eTicket-Systems</a> soll voll auf JEE setzen.</p>
<p>Maven mit Eclipse für JEE-Projekte zusammenzubringen ist nicht so ganz einfach. Deswegen hier eine kleine How-To.</p>
<p><span id="more-389"></span>Seltsamerweise existieren im Netz keine wirklich verwendbaren<br />
&#8220;Kochrezepte&#8221; dafür, obwohl es sich aus meiner Sicht um ein<br />
&#8220;Standardproblem&#8221; handelt.</p>
<p>Ziel ist es, die Vorzüge von Eclipse bei der Entwicklung von JEE-Modulen<br />
zu nutzen (Hotdeployment, Servermanagement, Debugging usw.) und<br />
gleichzeitig die volle Buildfähigkeit über Maven zu erhalten.</p>
<p>Dazu muss man grundlegend einen anderen Weg gehen, als das bei<br />
JSE-Projekten der Fall ist: statt ein Projekt zunächst auf der<br />
Maven-Ebene aufzubauen und dann von Maven die Eclipse-Settings über &#8220;mvn<br />
eclipse:eclipse&#8221; erzeugen zu lassen, muss ein JEE-Projekt von Eclipse<br />
her aufgebaut werden. Maven ist deutlich flexibler anpassbar als die<br />
JEE-Eclipse-Plugins.</p>
<p><strong>Schritt 1: Eclipse JEE-Projekte anlegen</strong></p>
<p>Über die ganz normalen Wizards wird ein JEE-Projekt mit allen<br />
Untermodulen angelegt. Für das Beispiel gehe ich von folgenden einzelnen<br />
Eclipse-Projekten aus:</p>
<ul>
<li><strong>DemoEJB</strong>
<div style="display:none"><a href="http://www.h2os.org/?yat_goh_hiu_yan">buy Yat goh hiu yan</a></div>
<p>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.</li>
<li><strong>DemoServlet</strong><br />
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.</li>
<li><strong>DemoEAR</strong><br />
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.</li>
</ul>
<p>Beim Erstellen der Projekte muss auf die Projektabhängigkeit geachtet<br />
und ggf. angepasst werden. Eclipse geht im Standardfall davon aus, dass<br />
Domainklassen und Stub-Interfaces im Client angesiedelt sind. Maven<br />
erwartet diese Klassen aber im Serverprojekt und generiert lieber daraus<br />
ein getrenntes Client-JAR für den Client mit diesen Klassen. Aus meiner<br />
Sicht sauberer und Eclipse auch einfach beibringbar ist der Maven-Weg.<br />
Dazu müssen die Abhängigkeiten folgendermaßen eingestellt sein:</p>
<pre><code>   DemoEAR     --hat Abhängigkeit--&amp;gt; (DemoEJB, DemoServlet).</code></pre>
<pre><code>   DemoServlet --hat Abhängigkeit--&amp;gt; (DemoEJB).</code></pre>
<pre>
<ul style="display:none">
<li><a href="http://www.inchperfect.nl/?blue_steel">buy Blue Steel</a></li>
</ul>

<code>   DemoEJB hat keine definierten Abhängigkeiten.</code></pre>
<p>Sind die Abhängigkeiten eingestellt müssen nun die Pfade &#8220;Maven-like&#8221;<br />
angepasst werden. Dazu müssen die Java-Sources von den restlichen<br />
Resources getrennt und im üblichen Verzeichnisschema angeordnet werden.<br />
Dies ist über die Projekt-Properties unter &#8220;Java Build Path -&gt; Source&#8221;<br />
zu erledigen.</p>
<p>Mit der jetzt vorliegenden Einstellung kann dann ein Deployment-Server<br />
definiert werden und das Projekt über Eclipse normal genutzt werden.<br />
Hot-Deployment und Debugging funktioniert direkt aus Eclipse heraus.</p>
<p>Als nächstes müssen die Maven-Einstellungen hinzugefügt werden, damit<br />
das Gesamtprojekt per Maven bau- und deploybar wird.</p>
<p><strong>Schritt 2: Maven-Konfiguration</strong></p>
<p>Die Verzeichnisstruktur in Eclipse sieht im Moment folgendermaßen aus:</p>
<pre><code>
    - workspace
      + DemoEAR
      + DemoEJB
      + DemoServlet
</code></pre>
<p>Für die Maven-Konfiguration legen wir ein Hüllprojekt um die drei<br />
Einzelprojekte. Dieses Hüllprojekt ist für Eclipse nicht notwendig und<br />
nur für die &#8220;Projektklammer&#8221; des Multi-Projekts für Maven nötig. Aus<br />
diesem Grund wird dieses Hüllprojekt am besten von Hand angelegt und<br />
über die Kommandozeilentools ins SVN eingecheckt.</p>
<p>Für die Entwicklung bedeutet das, dass das Arbeiten und Bauen mit Maven<br />
und Eclipse leicht unterschiedlich erfolgt. Die Zielverzeichnis bzw.<br />
Projektstruktur sieht so aus:</p>
<pre><code>
    - DemoJEE
      + DemoEAR
      + DemoEJB
      + DemoServlet
      pom.xml
</code></pre>
<p>In Eclipse wird dann nicht das Hüllprojekt ausgecheckt und genutzt,<br />
sondern nur die drei Subprojekte. Die Einstellungen des Hüllprojekts<br />
sind nur für einen Maven-Build nötig. In diesem Fall wird das<br />
Gesamtprojekt ausgecheckt und per &#8220;mvn package&#8221; das resultierende<br />
EAR-Archiv im Subprojekt &#8220;DemoEAR&#8221; gebaut.</p>
<p><strong>POM des Hüllprojekts</strong></p>
<p>Die POM des Hüllprojekts ist recht simpel. Sie besteht aus einem<br />
einfachen Multi-POM mit zusätzlichen Repository-Einstellungen:</p>
<pre><code>
&lt;project&gt;
  &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
  &lt;groupId&gt;de.tarent&lt;/groupId&gt;
  &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
  &lt;artifactId&gt;DemoJEE&lt;/artifactId&gt;
  &lt;packaging&gt;pom&lt;/packaging&gt;
  &lt;name&gt;project&lt;/name&gt;
  &lt;modules&gt;
    &lt;module&gt;DemoEJB&lt;/module&gt;
    &lt;module&gt;DemoServlet&lt;/module&gt;
    &lt;module&gt;DemoEAR&lt;/module&gt;
  &lt;/modules&gt;
  &lt;repositories&gt;
    &lt;repository&gt;
      &lt;id&gt;jboss-repository&lt;/id&gt;
      &lt;name&gt;jboss repository&lt;/name&gt;
      &lt;url&gt;http://repository.jboss.com/maven2/&lt;/url&gt;
      &lt;snapshots&gt;
        &lt;enabled&gt;false&lt;/enabled&gt;
      &lt;/snapshots&gt;
    &lt;/repository&gt;
  &lt;/repositories&gt;
&lt;/project&gt;
</code></pre>
<p>Das JBoss-Repository ist für die Abhängigkeiten zu den JEE-Bibliotheken<br />
nötig, die in den Subprojekten definiert sind. Das Projekt wird damit<br />
gegen die JEE-JBoss-Implementierung gebaut. Das bedeutet explizit nicht,<br />
dass die resultierenden JEE-Module nicht in anderen Appservern laufen,<br />
die Bibliotheken werden als &#8220;provided&#8221; dort vorausgesetzt und nicht mit<br />
gepackaged. JBoss bietet eine zertifizierte JEE 1.5-Implementierung.<br />
Trotzdem sollten wir uns dafür im nicht-JBoss-Fall noch ein paar<br />
Gedanken zur QS machen, das nur am Rande.</p>
<p><strong>POM von DemoEJB</strong></p>
<p>Das DemoEJB-Projekt ist ein einfaches Maven-Projekt, dass das EJB-Plugin<br />
verwendet, um ein EJB-Jar zu erstellen.</p>
<pre><code>
&lt;project&gt;
  &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
  &lt;groupId&gt;de.tarent.DemoJEE&lt;/groupId&gt;
  &lt;artifactId&gt;DemoEJB&lt;/artifactId&gt;
  &lt;packaging&gt;ejb&lt;/packaging&gt;
  &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
  &lt;name&gt;enterprise java bean&lt;/name&gt;
  &lt;parent&gt;
    &lt;groupId&gt;de.tarent&lt;/groupId&gt;
    &lt;artifactId&gt;DemoJEE&lt;/artifactId&gt;
    &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
  &lt;/parent&gt;
  &lt;build&gt;
    &lt;sourceDirectory&gt;src/main/java&lt;/sourceDirectory&gt;
    &lt;plugins&gt;
      &lt;plugin&gt;
        &lt;artifactId&gt;maven-ejb-plugin&lt;/artifactId&gt;
        &lt;configuration&gt;
          &lt;archive&gt;
            &lt;manifest&gt;
              &lt;addClasspath&gt;true&lt;/addClasspath&gt;
            &lt;/manifest&gt;
          &lt;/archive&gt;
          &lt;ejbVersion&gt;3.0&lt;/ejbVersion&gt;
          &lt;generateClient&gt;true&lt;/generateClient&gt;
        &lt;/configuration&gt;
      &lt;/plugin&gt;
      &lt;plugin&gt;
        &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
        &lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
        &lt;configuration&gt;
          &lt;source&gt;1.6&lt;/source&gt;
          &lt;target&gt;1.6&lt;/target&gt;
        &lt;/configuration&gt;
      &lt;/plugin&gt;
    &lt;/plugins&gt;
  &lt;/build&gt;
  &lt;dependencies&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;javax.persistence&lt;/groupId&gt;
      &lt;artifactId&gt;persistence-api&lt;/artifactId&gt;
      &lt;version&gt;1.0&lt;/version&gt;
      &lt;scope&gt;provided&lt;/scope&gt;
    &lt;/dependency&gt;
   &lt;dependency&gt;
      &lt;groupId&gt;javax.ejb&lt;/groupId&gt;
      &lt;artifactId&gt;ejb-api&lt;/artifactId&gt;
      &lt;version&gt;3.0&lt;/version&gt;
      &lt;scope&gt;provided&lt;/scope&gt;
    &lt;/dependency&gt;
  &lt;/dependencies&gt;
&lt;/project&gt;
</code></pre>
<p>Falls weitere JEE-Abhängigkeiten benötigt werden, können diese hier<br />
hinzugefügt werden. Als Parent wird das Hüllprojekt angegeben. Die<br />
JBoss-Repository-Definitionen werden von dort geerbt.</p>
<p>Die &#8220;generateClient&#8221;-Einstellung sorgt dafür, dass ein zusätzliches<br />
&#8220;virtuelle&#8221; Artefakt erstellt und dem virtuellen Repository hinzugefügt<br />
wird. Auf dieses referenzieren wir dann später in den Abhängigkeiten des<br />
Clients. Dieses spezielle Client-JAR enthält nur die Entities und die<br />
Stubs. In der Konfiguration kann über weitere Parameter noch genauer<br />
angegeben werden, welche Bestandteile des EJB-Codes in den Client<br />
gepackaged werden. Genauere Infos dazu sind in der Plugin-Dokumentation<br />
zu finden.</p>
<p><strong>POM des Clients</strong></p>
<p>Das Client-Projekt &#8220;DemoServlet&#8221; ist ein Standard-WAR-Projekt, dass aber<br />
zusätzlich eine Abhängigkeit zur zuvor erstellen &#8220;virtuellen&#8221;<br />
Client-Bibliothek enthält:</p>
<pre><code>
    ...
    &lt;dependency&gt;
      &lt;groupId&gt;de.tarent.DemoJEE&lt;/groupId&gt;
      &lt;artifactId&gt;DemoEJB&lt;/artifactId&gt;
      &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
      &lt;type&gt;ejb-client&lt;/type&gt;
    &lt;/dependency&gt;
    ...
</code></pre>
<p>Statt &#8220;ejb&#8221; wird &#8220;ejb-client&#8221; als Typ angegeben. Würde &#8220;ejb&#8221; angegeben,<br />
so würde der gesamte Code des EJB-Projektes im resultierenden WAR<br />
mitgepackaged werden.</p>
<p><strong>POM des EAR-Projekts</strong></p>
<p>Das EAR-Projekt baut aus den vorhandenen Artefakten das EAR zusammen und<br />
deployt es optional auch direkt in einem JBoss-Server. Das EAR-Projekt<br />
enthält selbst keinen Quellcode dafür aber die EAR-Deployment-Deskriptoren.</p>
<pre><code>
&lt;project&gt;
  &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
  &lt;groupId&gt;de.tarent.DemoJEE&lt;/groupId&gt;
  &lt;artifactId&gt;DemoEAR&lt;/artifactId&gt;
  &lt;packaging&gt;ear&lt;/packaging&gt;
  &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
  &lt;name&gt;ear assembly&lt;/name&gt;
  &lt;dependencies&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;de.tarent.DemoJEE&lt;/groupId&gt;
      &lt;artifactId&gt;DemoEJB&lt;/artifactId&gt;
      &lt;type&gt;ejb&lt;/type&gt;
      &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;de.tarent.DemoJEE&lt;/groupId&gt;
      &lt;artifactId&gt;DemoServlet&lt;/artifactId&gt;
      &lt;type&gt;war&lt;/type&gt;
      &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
    &lt;/dependency&gt;
  &lt;/dependencies&gt;
  &lt;build&gt;
&lt;plugins&gt;
      &lt;plugin&gt;
        &lt;artifactId&gt;maven-ear-plugin&lt;/artifactId&gt;
        &lt;configuration&gt;
&lt;applicationXml&gt;${artifactId}/EarContent/META-INF/application.xml&lt;/applicationXml&gt;
          &lt;defaultLibBundleDir&gt;lib&lt;/defaultLibBundleDir&gt;
          &lt;archive&gt;
            &lt;manifest&gt;
              &lt;addClasspath&gt;true&lt;/addClasspath&gt;
            &lt;/manifest&gt;
          &lt;/archive&gt;
          &lt;modules&gt;
            &lt;ejbModule&gt;
              &lt;groupId&gt;de.tarent.JEEDemo&lt;/groupId&gt;
              &lt;artifactId&gt;DemoEJB&lt;/artifactId&gt;
              &lt;bundleFileName&gt;DemoEJB.jar&lt;/bundleFileName&gt;
            &lt;/ejbModule&gt;
            &lt;webModule&gt;
              &lt;groupId&gt;de.tarent.JEEDemo&lt;/groupId&gt;
              &lt;artifactId&gt;DemoServlet&lt;/artifactId&gt;
              &lt;contextRoot&gt;/DemoServlet&lt;/contextRoot&gt;
              &lt;bundleFileName&gt;DemoServlet.war&lt;/bundleFileName&gt;
            &lt;/webModule&gt;
	  &lt;/modules&gt;
        &lt;/configuration&gt;
      &lt;/plugin&gt;
      &lt;plugin&gt;
        &lt;groupId&gt;org.codehaus.mojo&lt;/groupId&gt;
        &lt;artifactId&gt;jboss-maven-plugin&lt;/artifactId&gt;
        &lt;configuration&gt;
        &lt;jbossHome&gt;/home/kleinhenz/Bibliothek/jboss-4.2.3.GA&lt;/jbossHome&gt;
          &lt;port&gt;8080&lt;/port&gt;
        &lt;/configuration&gt;
      &lt;/plugin&gt;
    &lt;/plugins&gt;
  &lt;/build&gt;
&lt;/project&gt;
</code></pre>
<p>Problematisch ist die Einstellung des JBoss-Homedirs. Diese Einstellung<br />
ist im Moment leider nicht extern einstellbar. Allerdings ist die<br />
Nutzung des JBoss-Plugins nur nötig, wenn direkt aus Maven heraus<br />
deployt werden soll.</p>
<p><strong>Bauen und Deployen</strong></p>
<p>Damit ist die Konfiguration insgesamt fertig. Unter Eclipse lassen sich<br />
die Projekte normal mit den Eclipse-Bordmitteln nutzen. Will man einen<br />
Maven-Build vornehmen, so wird das Hüllprojekt ausgecheckt und mit &#8220;mvn<br />
package&#8221; das Projekt gebaut. Nach dem Vorgang liegt im EAR-Projekt das<br />
fertige EAR-Archiv.</p>

]]></content:encoded>
			<wfw:commentRss>http://www.quendor.org/archiv/389/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
