Oct 212008
 

Schneller, höher, weiter! Das Entwickeln von JEE-Applikationen ist bestimmt durch Round-Trips aus Code-Änderung, Kompilierung, Re-Deployen und Testen. Da sich diese Round-Trips in kurzen Abständen (Minutenbereich) wiederholen, sollte das Kompilieren und Re-Deployen so wenig Zeit möglich in Anspruch nehmen. Zum einen lässt das schlicht mehr Zeit zum Programmieren und Testen. Zum anderen macht das Arbeiten den Programmierern so einfach mehr Spaß! (… und die Zufriedenheit des Programmierers ist direkt proportional zur Lebensdauer seiner Tastatur).

Re-Deployment vermeiden

Einige Änderungen im Code benötigen gar kein Re-Deployment.

Einfache Änderungen im Java-Code lassen sich direkt über die Debugging-Schnittstelle in den Application Server übertragen. Eclipse muss also per Remote Debugger mit dem Application Server verbunden sein in welchem die JEE-App läuft. Alternativ kann der Application Server auch direkt mittels Eclipse WTP im Debugging-Modus gestartet sein. Aber Vorsicht: Nach dem Neustarten des Servers sind die Änderungen wieder weg, da die Class-Dateien des Deployments geladen werden.

Einfache Änderungen beziehen sich auf das Verändern von Methodenblöcken (Method Body). Wichtig für das Funktionieren von Hot Code Replacement in Eclipse ist, dass Auto-Build (Kompilieren) aktiv ist. Wartet der Debugger gerade per Breakpoint in der veränderten Methode, so wird der aktuelle Frame vom Ausführungsstack gepoppt und die Methode wird quasi erneut mit denselben Argumenten aufgerufen.

Das Ändern der Klassensignatur ist nicht mittels Hot Code Replacement (HCR) möglich. Die Klassensignatur ändert sich zum Beispiel durch neue Methoden oder Felder, Umbenennen von Methoden oder Feldern, sowie durch Verändern von Methodensignaturen. Eclipse zeigt in diesem Fall folgendes Meldungsfenster an:

Dann ist in der Regel ein Re-Deployment notwendig. Das Neustarten des Application-Servers dauert länger und sollte vermieden werden.

Re-Deployment beschleunigen

Wenn Hot Code Replace nicht ausreicht, wird also ein Re-Deployment notwendig. Die Code-Änderungen müssen inkrementell kompiliert und dem Application Server bereitgestellt werden. Eclipse kompiliert bereits inkrementell. Warum also eine gesonderte Kompilierung per Ant durchführen? Das kostet Zeit.

Das Kopieren von Class-Dateien in das “explodierte” Deployment-Verzeichnis kostet ebenso Zeit. Praktisch ist die Verwendung von symbolischen Verzeichnislinks im Dateisystem. Entsprechende Verzeichnisse im Deployment-Verzeichnis zeigen auf die Verzeichnisse mit den Class-Dateien in Eclipse.

Folgendes Bild veranschaulicht die Verzeichnislinks bei einem meiner Projekt, welches ein Maven-Setup verwendet (erkennbar an den Verzeichnissen “target/classes”):

Die symbolischen Links werden mittels Ant-Skript und dem freien Windows-Tool Junction angelegt. Folgendes Ant-Fragment kann dabei helfen, dasselbe im eigenen Projekt zu machen:

<target name="_create_symlink" description="Creates a symbolic link">
<fail unless="from.path" />
<fail unless="to.path" />

<!-- junction executable must use absolute path since it operates in a different work directory -->
<property name="to.path.abs" location="${to.path}" />

<dirname file="${from.path}" property="from.path.dir" />
<basename file="${from.path}" property="from.path.name" />

<echo level="info" message="Creating symlink ${from.path} -> ${to.path.abs}" />
<basename file="" property="" />
<exec executable="${project.root.tools.dir}/junction.exe" dir="${from.path.dir}" failonerror="true">
  <arg value="${from.path.name}" />
  <arg value="${to.path.abs}" />
</exec>
<echo file="${from.path}_readme.txt">
  ${symlink.src.name} represents a symbolic link and it is not intended to be handled like a normal directory.
  Under Windows use the junction.exe tool to manage it!
</echo>
</target>

<target name="_del_symlink" description="Deletes a symbolic link">
<fail unless="from.path" />

<dirname file="${from.path}" property="from.path.dir" />
<basename file="${from.path}" property="from.path.name" />

<echo level="info" message="Deleting symlink ${from.path}" />
<exec executable="${project.root.tools.dir}/junction.exe" dir="${from.path.dir}">
  <arg value="-d" />
  <arg value="${from.path.name}" />
</exec>
<delete file="${from.path}_readme.txt" failonerror="false" />
</target>

In einem meiner Projekte (Großprojekt, JEE, Automotive) haben wir sehr viele Klassen explodiert deployt (aktuell 7299). Man kann sich Vorstellen wie viel Zeit täglich durch den Wegfall des Kopierens beim Re-Deployment gespart wird.

Re-Deployment anstossen

Nachdem die neuen Class-Dateien jetzt im Deployment-Verzeichnis bereit stehen, kann re-deployt werden. Der Application Server stoppt und entlädt die JEE-App. Dabei werden geladene Class-Dateien freigegeben. Anschließend wird die JEE-App wieder geladen und gestartet.

Das Anstoßen eines Re-Deployments ist abhängig vom Application Server. Unter JBoss funktioniert dies einfach über das Verändern des Deployment-Deskriptors. Für ein EAR-Deployment muss der Deskriptor “META-INF/application.xml” modifiziert werden. Dies lässt sich mit Ant wie folgt realisieren:

<touch file="${deploy.ear.exploded.dir}/META-INF/application.xml"/>

Unter BEA Weblogic 8 können die Weblogic Admin Tools in Ant verwendet werden:

<java classname="weblogic.Deployer" fork="true">
  <classpath>
    <pathelement location="${weblogic.lib.dir}/weblogic.jar"/>
  </classpath>

  <!-- options -->
  <arg value="-adminurl"/>
  <arg value="${domain.admin.url}"/>
  <arg value="-username"/>
  <arg value="${domain.admin.user}"/>
  <arg value="-password"/>
  <arg value="${domain.admin.pwd}"/>
  <arg value="-name"/>
  <arg value="${domain.deployment.packaged.name}"/>
  <arg value="-targets"/>
  <arg value="${domain.deployment.exploded.business.name}@${domain.deployment.target}"/>
  <arg value="-verbose"/>

  <!-- action -->
  <arg value="-redeploy"/>
</java>

Ich hoffe Eure Entwicklungsumgebung ist so schnell wie meine. Ja? Dann können wir mal um die Wette coden…

  3 Responses to “Entwicklungsumgebung für JEE-Apps beschleunigen”

  1. In diesem Zusammenhang finde ich JavaRebel auch sehr fein. Damit kann man recht munter drauflos coden und spart sich das Deployment öfters mal. Ein Artikel über JavaRebel steht auch auf meiner virtuellen Liste…

    Application-Server und hot swap aus dem Debugger? Da hatte ich den Eindruck, dass es nicht so gut läuft. Aber ich probier’s bei Gelegenheit nochmal…

  2. JavaRebel kannte ich bisher nicht. Ich habe mir eine Demo-Version heruntergeladen und jetzt in zwei Projekten eine Weile eingesetzt. Ein Projekt läuft unter JBoss 4.2.2 und ein anderes unter Glassfish V2. Eclipse meckert ab und an, dass Breakpoints nicht gesetzt werden können. Dies ist ein bekanntes Problem und kann ignoriert werden, da die Breakpoints offenbar doch gesetzt werden (Eclipse 3.4). Scheint ein nettes Tool zu sein. Ich werde mal anregen das zu kaufen, wenn das Glassfish V2 / Seam Projekt in die Implementierungsphase geht (aktuell bin ich am IV-Konzept und Prototypisieren dran).

  3. […] Sophisticated IT Blaupausen der IT-Architektur-Zunft von Marc Neumann « Entwicklungsumgebung für JEE-Apps beschleunigen […]

Leave a Reply to Markus Junginger Cancel reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>