Techblog

Herzlich Willkommen im Communardo Techblog, dem Entwickler-Weblog von Communardo. An dieser Stelle werden Ideen, Problemlösungen, Tipps und Problemstellungen rund um die Entwicklung webbasierter Software vorgestellt.

techblog-teaser

HyperJAXB3

, von

Im Rahmen eines Projektes sollten XML Mockup Dateien in einer Datenbank gehalten und über eine Webservice-Schnittstelle ausgelesen werden. Für gewöhnlich habe ich aus der XSD per JAXB Java Klassen generiert und in Entity Beans gemappt, die anschließend in die Datenbank geschrieben werden. Um dieses, aus meiner Sicht recht aufwendige und fehleranfällige Mapping in die Entity Beans zu umgehen, habe ich mich nach einem alternativen Framework umgesehen und bin mit Hyperjaxb3 fündig geworden. Hyperjaxb3 geht einen Schritt weiter als JAXB, in dem es die generierten Klassen per Annotation zu vollständigen JPA Entitybeans macht. Aktuell steht Hyperjaxb3 in der Version 0.5.4 unter https://hyperjaxb3.dev.java.net zum Download bereit. Unterstützt werden Hibernate und Oracle TopLink, wobei es mit einigen Anpassungen auch mit OpenJPA und EclipseLink funktioniert. Aus meiner Sicht ist aber der Einsatz von OpenJPA (1.2.2) mit Hyperjaxb3 nicht zu empfehlen, da es zu Problemen mit den Relations kam (Es werden keine bidirektionalen Beziehungen unterstützt). Ein weiteres Problem sind die unterschiedlichen Datentypen, da JAXB und JPA nicht vollständig kompatibel sind. Beispiele kann man auf der z.Z. noch etwas lückenhaften Wiki Seite von Hyperjaxb3 finden. http://confluence.highsource.org/display/HJ3/Home

Artikel vollständig lesen

Standalone Java Applikationen mit Maven

, von

Das Bauen und Ausliefern von normalen und eigenständigen Java Anwendungen die nicht in einem Webcontainer oder Applikationserver laufen sollen kann sich als schwierig erweisen. Die größten Probleme beim Erzeugen der Releases sind dabei die folgenden Punkte:

  • es müssen die benötigten Bibliotheken aufgelöst und mit in des Release gepackt werden
  • die Java Applikation muss in den meisten Fällen auf dem Zielsystem als Dienst laufen (Deamon)
  • das Erstellen und Packen des Releases sollte automatisiert erfolgen

Das Maven 2 Plugin appassembler zielt auf diesen Anwendungsfall ab und ermöglicht

  • das automatisierte Erstellen von Skripten zur einfachen Ausführung der Applikation
  • das Erzeugen von Releases die es ermöglichen, die Java Anwendung als Dienst zu betreiben
  • die Erzeugung von Repositories die alle nötigen Bibliotheken für die Anwendung enthalten.

Die Konfiguration des Plugins ist aber leider nicht ganz so einfach da die Dokumentation eher schlecht ist und ich auch auf Bugs im Plugin selber gestoßen bin. Artikel vollständig lesen

OSGI- und Spring-DM-Bundles über Eclipse und maven2 erstellen

, von

Unter http://springosgi.googlepages.com/ befindet sich ein hervorragendes Tutorial zu Spring-DM, welches nebenbei auch die Verwendung der Plugin-Development-Unterstützung von Eclipse erklärt. Wer einmal deren Vorzüge genossen hat, wird wahrscheinlich nie mehr Manifest-Dateien per Texteditor bearbeiten wollen. Außerdem ist es bei der Entwicklung angenehmer, entwickelte Bundles über einen einzigen Knopfdruck im Eclipse zu starten, anstatt sie z.B. über Maven zu bauen und den Container extern zu starten.

Trotzdem kann es wichtig sein, dass die Bundles unabhängig von Eclipse in Maven gebaut werden können, z.B. um komplette Releases mit Tokenersetzung für verschiedene Umgebungen zu bauen. Für Maven2 existiert das Felix Bundle Plugin (http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html), welches fertige Bundles generieren kann.

Da sich die Verszeichnisstrukturen des Eclipse-Plugin-Development-Tools und eines Standard-Maven2-Projektes sehr unterscheiden, wird hier ein Weg beschrieben, wie beide Welten vereinigt werden können.

Als Verzeichnisstruktur des Maven-Projektes wird folgendes vorausgesetzt:

- src

- main

- bundle

- META-INF

- Manifest.MF

- java

Innerhalb von Eclipse muss aber das META-INF-Verzeichnis im Wurzelverzeichnis des Projektes liegen, damit es als Bundle gebaut wird. Deshalb legen wir das Plugin-Projekt innerhalb des Bundle-Ordners an und importieren alle benötigten Resourcen (in diesem Fall nur den java-Ordner) über Verlinkung in das Projekt. Dafür erstellt man einen neuen Ordner und selektiert unter Advanced die Checkbox Link to Folder in file system. Dann wählt man den Java-Ordner und fügt ihn zum Projekt hinzu. Über das Kontext-Menü -> Build Path -> Use as source folder kann dieser Ordner  als Quellordner markiert werden.

Die Verzeichnisstruktur im Eclipse-Projekt sieht jetzt folgendermaßen aus:

- META-INF

- Manifest.MF

- java (Verlinkt)

Jetzt muss nur noch das Maven-Plugin so eingerichtet werden, daß es die Bundle-Konfiguration aus der vom Eclipse erzeugten Manifest-Datei übernimmt. Das kann z.B. so aussehen:

<plugin>

<groupId>org.apache.felix</groupId>

<artifactId>maven-bundle-plugin</artifactId>

<extensions>true</extensions>

<executions>

<execution>

<id>bundle</id>

<phase>package</phase>

<goals>

<goal>bundle</goal>

<goal>install</goal>

</goals>

</execution>

</executions>

<configuration>

<instructions>

<_failok>true</_failok>

<_include>src/main/bundle/META-INF/MANIFEST.MF</_include>

<Include-Resource>{maven-resources},META-INF/spring=src/main/bundle/META-INF/spring</Include-Resource>

</instructions>

</configuration>

</plugin>

Das _include -Tag bewirkt, dass für die Bundle-Generierung die von Eclipse erzeugte Manifest-Datei verwendet wird. Leider wird in Dieser der Klassenpfad Einträge enthalten, die im erzeugten Bundle nicht mehr vorhanden sind, z.B. der bin-Ordner, in welchem die kompilierten Klassen liegen. Das Bundle-Plugin bricht an dieser Stelle ab, obwohl ungültige Klassenpfad-Einträge in Equinox nicht zu Fehlern führen. Der einfachste Weg, dieses Problem zu umgehen, ist _failok auf true zu setzen. Eleganter wäre es, den Klassenpfad-Eintrag vorher zu manipulieren. Wichtig ist nur, dass der Klassenpfad-Eintrag ./ existiert, weil das Bundle-Plugin alle Klassen im Wurzel-Verzeichnis des Bundles ablegt.

Allerdings kann nicht davon ausgegangen werden, dass sich das Bundle auf Anhieb in einem extern gestarteten equinox genauso verhält, wie in Eclipse, da Eclipse zahlreiche Umgebungsvariablen setzt, die von den Default-Werten abweichen. Sollten also ClassNotFoundExceptions bei Klassen auftreten, welche normalerweise zur JRE gehören (z.B. org.w3c.dom.Node) und innerhalb von Eclipse nicht als Dependency eingebunden werden müssen, dann lohnt sich ein Blick in die System-Properties.

Properties prop = System.getProperties();
for (Object k : prop.keySet()) {
System.out.println(k + ” – ” + prop.getProperty(k.toString()));
}

Gibt alle Properties aus. Eine Beschreibung der einzelnen Parameter befindet sich hier

Wichtig sind vor allem die Parameter osgi.compatibility.bootdelegation und org.osgi.framework.system.packages.

Maven und das Trigger-Plugin in Confluence

, von

Bei der Entwicklung von Confluence Plugins kommt häufig die auf Java basierende Buildmanagement-Software Maven zum Einsatz. Ziel dabei ist es, die Entwickler vom Anlegen des Projektes bis hin zum Kompilieren und Testen zu unterstützen und möglichst viele Schritte des Softwaremanagements automatisiert ablaufen zu lassen. Ein Tutorial für die Entwicklung von Confluence Plugins mit Hilfe von Maven findet sich auf den Seiten der Confluence Community.

Wenn eine solche Entwicklungsumgebung eingerichtet wurde, kann der Buildprozess eines Plugins noch weiter vereinfacht werden. Dafür stellt Atlassian das Plugin Developer Kit for Maven2 (kurz PDK) zur Verfügung. Dabei handelt es sich um ein Maven-Plugin, welches einfach in der POM des eigenen Projektes eingebunden werden muss und dann automatisch beim Buildprozess heruntergeladen und installiert wird. Ein solcher Aufruf kann z.B. so aussehen:

<plugin>
   <groupId>com.atlassian.maven.plugins</groupId>
   <artifactId>atlassian-pdk</artifactId>
   <executions>
      <execution>
         <phase>package</phase>
         <goals>
            <goal>uninstall</goal>
            <goal>install</goal>
            <goal>rescan</goal>
         </goals>
      </execution>
   </executions>
</plugin>

Dabei können verschiedene Goals angegeben werden, welche hintereinander ausgeführt werden und z.B. das Plugin direkt nach dem kompilieren in einem laufenden Confluence deinstallieren und die neue Version installieren. Eine sinnvolle Reihenfolge wäre z.B. UninstallInstallRescan.

Vorsicht ist allerdings bei der Benutzung des Confluence Trigger Plugin Moduls geboten. Hat man einen Trigger in seiner atlassian-config.xml eingebunden und installiert das Plugin über das PDK direkt in ein laufendes Confluence, sollte nach einem Install kein explizites Enable des Plugins ausgeführt werden. Der Grund dafür ist: der Job wird bereits beim Install angelegt. Bei einem folgenden Enable wird dann erneut versucht, dieser Job anzulegen – was natürlich fehlschlägt und mit einer ObjectAlreadyExistsException quittiert wird. Ein Install und ggf. Rescan ist in diesem Fall also ausreichend.

Verwendung von Java2 5.0 Klassen mit Java2 1.4 mit Retrotranslator

, von

In einem existierenden Java2 1.4 Projekt sollen generierte XFire-Clientklassen verwendet werden. Der XFire-Codegenerator verwendet JAXB2 und ist damit auf einige Java2 5.0-Features wie Annotations angewiesen. Der Umstieg auf Java2 5.0 ist in dem Projekt keine Option und deshalb habe ich eine Möglichkeit gebraucht, die generierten Klassen mit Java2 1.4 zu verwenden.

Nach ein paar Recherchen habe ich mich für die Verwendung des freien Retrotranslator-Tools entschieden und eine Proof-Of-Concept-Implementierung realisiert. Retrotranslator kann sowohl zur Compile-Zeit als auch zur Laufzeit den Java2 5.0 Bytecode in Java2 1.4 Bytecode umwandeln. Für den eigenen Code habe ich mich für die Umwandlung zur Compilezeit entschieden und für verwendeten Code Dritter für die Umwandlung zur Laufzeit (Just in Time Compilierung).
Artikel vollständig lesen

Diese Webseite basiert auf Wordpress. © 2014 Communardo Software GmbH / Kleiststraße 10 a / D-01129 Dresden / Fon +49 (0) 351/8 33 82-0 / info@communardo.de