Verwendung von Faktor-IPS-Projekten als OSGi-Bundles

Einführung

Abhängigkeiten zwischen Faktor-IPS-Projekten wurden bisher mit dem „Faktor-IPS Build Path“ im Eigenschaftsdialog eines Faktor-IPS-Projekts verwaltet. Ab der Version 3.9 von Faktor-IPS gibt es zusätzlich die Möglichkeit, diese Abhängigkeiten auf Basis von OSGi in einem Manifest zu pflegen. Für Anwender ergeben sich dadurch neue Nutzungsszenarien:

  • Java-, Plugin- und Faktor-IPS-Abhängigkeiten können im Manifest und damit an einer Stelle verwaltet werden.
  • Die Abhängigkeiten und Versionen können mit dem Industriestandard OSGi verwaltet werden.
  • In Produktdatenprojekten können die Modelldefinitionen einfach mit dem Software-Update-Mechanismus von Eclipse aktualisiert werden.

Wichtig: Um diese Funktionen nutzen zu können, muss Eclipse PDE installiert sein und alle Projekte müssen den Plugin-Container im Classpath haben. Letzteres ist automatisch der Fall, wenn es sich um ein Plugin-Projekt handelt. Im Package-Explorer kann über Kontextmenü unter Konfigurieren ein Java-Projekt zu einem Plugin-Projekt umgewandelt werden.

Anpassungen

Ob der „Faktor-IPS Build Path“ oder das Manifest verwendet wird, ist in der Datei .ipsproject einzustellen. Anstatt den „Faktor-IPS Build Path“ anzugeben, kann jetzt einfach auf das Manifest verwiesen werden. Dazu gibt man im Element IpsObjectPath das neue optionale Attribut useManifest an. Ist es auf den Wert „true“ gesetzt, werden die Pfadangaben aus dem Manifest gelesen. Weitere Elemente und Attribute sind dann im Element IpsObjectPath nicht mehr zulässig und werden ignoriert.

Ist useManifest auf „false“ gesetzt oder fehlt das Attribut, verhält sich die Konfiguration wie bisher.

Anpassung der .ipsproject-Datei

Bisher (Beispiel)

    <IpsObjectPath basePackageDerived="org.faktorips.sample.model" basePackageMergable="org.faktorips.sample.model" outputDefinedPerSrcFolder="false" 
                   outputFolderDerivedSources="derived" outputFolderMergableSources="src">
        <Entry basePackageDerived="" basePackageMergable="" outputFolderDerived="" outputFolderMergable="" sourceFolder="model" tocPath="faktorips-repository-toc.xml" 
                       type="src" validationMessagesBundle="validation-messages"/>
    </IpsObjectPath>

Neu

    <IpsObjectPath useManifest="true" />

META-INF/MANIFEST.MF

Wurde die Option useManifest in der .ipsproject-Datei aktiviert, werden die Einstellungen zum „Faktor-IPS Build Path“ in der META-INF/MANIFEST.MF-Datei hinterlegt. Weitere Attribute und Subelemente sind dann im IpsObjectPath-Element nicht mehr zulässig und werden ignoriert.

Einstellung von Abhängigkeiten im Manifest

Für die Einstellungen im Manifest stehen folgende „Header“ zur Verfügung:

Header Entsprechung in .ipsproject Bedeutung
Fips-BasePackage Attribute basePackageMergable und basePackageDerived Gibt das Base-Package für die generierten Java-Klassen an. Diese Angabe gilt für alle Source-Folder, außer wenn etwas anderes angegeben ist. Eine Unterscheidung zwischen basePackageMergable und basePackageDerived hat sich in der Praxis als irrelevant herausgestellt. Das eingestellte Package gilt daher für beide Einstellungen.
Fips-SourcecodeOutput Attribut outputFolderMergableSources Gibt den Java-Sourcecode-Folder an, in den Faktor-IPS die Java-Klassen generiert. Auch diese Angabe gilt generell, wenn sie nicht explizit überschrieben wird.
Fips-ResourceOutput Attribut outputFolderDerivedSources Gibt den Resourcen-Folder an, in den Faktor-IPS Ressourcen generiert. Auch diese Angabe gilt generell, wenn sie nicht explizit überschrieben wird.
Fips-GeneratorConfig IpsArtefactBuilderSetConfig (ab Faktor-IPS 3.22) Gibt Einstellungen für den Codegenearator an. Ohne diesen Eintrag werden die Einstellungen des referenzierenden Projekts verwendet, wenn dieses Projekt als Archiv eingebunden ist. Dies kann zu Problemen führen, wenn die Einstellungen abweichen.
Fips-ObjectDir Element Entry mit Attributtype=„src“ Gibt Quellordner an, in denen Faktor-IPS-Objekte abgelegt sind. Hier können auch mehrere Ordner mit Komma getrennt angegeben werden.

Das Fips-ObjectDir enthält als Entsprechung des Element Entry einige Attribute. Diese werden direkt hinter dem Namen des Modellordners mit Strichpunkt getrennt angegeben (siehe Beispiel weiter unten):

Attribut Entsprechung in .ipsproject Bedeutung
toc Attribut tocPath Pfad zur TOC-Datei
validation-messages Attribut validationMessagesBundle Pfad zur Datei mit den Meldungen für die Validierungsregeln.

Die Angaben des oben gezeigten IpsObjectPath können damit folgendermaßen im Manifest angegeben werden:

Fips-BasePackage: org.faktorips.sample.model
Fips-SourcecodeOutput: src
Fips-ResourceOutput: derived
Fips-ObjectDir: model;toc="faktorips-repository-toc.xml";validation-messages="validation-messages"

Zusätzliche Quellordner für Faktor-IPS-Objekte

Sollen mehrere Ordner für Faktor-IPS-Objekte verwendet werden, fügt man diese dem Fips-ObjectDir hinzu:

Fips-BasePackage: org.faktorips.sample.model
Fips-SourcecodeOutput: src
Fips-ResourceOutput: derived
Fips-ObjectDir: model;toc="faktorips-repository-toc.xml";validation-messages="validation-messages.properties",
 test;toc="faktorips-repository-test-toc.xml";validation-messages="validation-messages-test.properties"

Wichtig ist dabei nach einem Zeilenumbruch mindestens ein Leerzeichen am Anfang der Zeile zu schreiben.

Abweichende Base-Packages und Output-Verzeichnisse

Für die Quellordner können eigene Output-Verzeichnisse angegeben werden, die von den generell definierten Output-Verzeichnissen abweichen. Gleiches gilt für das Base-Package, in das Java-Klassen generiert werden.

Um Testcode von produktivem Code zu trennen, werden zusätzliche Abschnitte für den jeweiligen Quellordner eingefügt. Darin werden die generellen Angaben überschrieben:

Fips-BasePackage: org.faktorips.sample.model
Fips-SourcecodeOutput: src
Fips-ResourceOutput: derived
Fips-ObjectDir: model;toc="faktorips-repository-toc.xml";validation-messages="validation-messages.properties",
 test;toc="faktorips-repository-test-toc.xml";validation-messages="validation-messages-test.properties"

Name: test
Fips-SourcecodeOutput: test
Fips-ResourceOutput: testDerived

Zwischen dem Hauptteil und der Deklaration der überschriebenen Einstellungen muss eine Leerzeile eingefügt sein. Mit der Anweisung Name wird festgelegt, zu welchem Ordner die Einstellungen überschrieben werden sollen. Danach können Sourcefolder, Resourcefolder und Base-Package überschrieben werden. Es müssen nicht alle Attribute definiert werden, fehlende Definitionen werden aus dem Hauptteil oben gelesen.

Abweichende Einstellungen in referenzierten Projekten

Um ein als Archiv referenziertes Projekt mit abweichenden Einstellungen korrekt verwenden zu können, müssen die abweichende Werte unter dem Header Fips-GeneratorConfig aufgeführt werden. Insbesondere sollten die Werte changesInTimeNamingConvention, generatePublishedInterfaces und generatorLocale hier gepflegt werden, da diese sich auf die Namen und Pfade der generierten Klassen auswirken. Diese Einstellungen duplizieren derzeit die Einstellungen in der .ipsproject-Datei und müssen manuell synchronisiert werden!

Fips-GeneratorConfig: org.faktorips.devtools.stdbuilder.ipsstdbuilderset;
 changesInTimeNamingConvention="VAA";
 generatePublishedInterfaces="true";
 generatorLocale="en";
 localDateDatatypeHelperVariant="joda"

Referenzieren von Faktor-IPS-Projekten

Um Abhängigkeiten zu anderen Projekte zu definieren, müssen diese als OSGi Bundle vorliegen. Dazu muss eine MANIFEST.MF Datei mit mindestens folgenden Einträgen existieren:

Bundle-ManifestVersion: 2
Bundle-Name: <Name des Projekts>
Bundle-SymbolicName: <ID des Projekts>
Bundle-Version: <version>

Die erste Zeile legt lediglich die Version des OSGi Bundle Manifest fest und sollte so übernommen werden. Bundle-Name legt den Namen des Projekts fest. Dieser Name muss nicht eindeutig sein und darf auch Leerzeichen enthalten. Bundle-SymbolicName legt dagegen den eindeutigen Namen des Projekts fest und wird später verwendet, um die Abhängigkeit zu definieren. Die Bundle-Version legt die aktuelle Version des Projekts fest und kann zu Einschränkungen von Abhängigkeiten genutzt werden. Das Format der Version ist x.x.x.qualifier, wobei jedes x einer Zahl entspricht und der Qualifier alphanumerisch ist.

Damit auch die Abhängigkeiten für den Java Sourcecode richtig funktionieren, muss außerdem noch darauf geachtet werden, dass alle notwendigen Packages exportiert werden.

Weitere Einstellungsmöglichkeiten für OSGi Bundles können in der OSGi Spezifikation eingesehen werden.

Um ein anderes Bundle zu referenzieren, wird dieses im Manifest mit dem Header Require-Bundle referenziert:

Require-Bundle: <ID des Projekts>;bundle-version="<version>"

Bei der Version können auch Bereiche oder ungenaue Versionen angegeben werden, z.B.:

[1.0.0,1.1.0) Von 1.0.0 eingeschlossen bis 1.1.0 ausgeschlossen
1.0 Alle Versionen, die mit 1.0 beginnen

Die referenzierten OSGi Bundles können als Projekt im Workspace oder als (gepacktes) OSGi Bundle vorliegen. Die Einstellungen zum IpsObjectPath müssen wie oben beschrieben im Manifest definiert sein. Wenn das Bundle nicht im Workspace liegt, muss es über die eingestellte Target Platform erreichbar sein (siehe unten).

Die Einstellungen im Manifest können bequem über den Plugin Manifest Editor bearbeitet werden. Dieser enthält jedoch (zumindest in Eclipse 3.7) einen Fehler, wenn zusätzliche Abschnitte (z.B. zur Konfiguration eines weiteren Fips-ObjectDir, siehe oben) im Manifest enthalten sind. In diesem Fall ist im Manifest darauf zu achten, dass alle Einstellungen vor der ersten Leerzeile getroffen werden.