Zum Hauptinhalt.
Nuxeo jUnit Tests mit Visual Studio

Nuxeo Komponenten mit Java/JNI und MS Visual Studio

Zielgruppe

Dieser Leitfaden richtet sich an diejenigen, die das Dokumentmanagementsystem Nuxeo mit C/C++ Komponenten erweitern und testen wollen. Es beschreibt Ihnen ein Verfahren, mit dem Sie jUnit Tests mit Java Native Interface JNI bequem in einer Microsoft Visual Studio Umgebung ausführen können. Dabei wird insbesondere auf die Anforderungen innerhalb des Nuxeo Umfelds eingegangen.

Vorbemerkung

Informationen, wie Sie C/C++ bzw. JNI Komponenten in Nuxeo EP implementieren können, sind rar gesät. Denn die sprachliche Dömäne von Nuxeo ist Java. Nur durch das Java local API können Sie Nuxeo EP erweitern. Das vermittelt Ihnen zumindest Opens external link in new windowNuxeo's technische Dokumentation.

Davon abgesehen verfügen Sie mit Opens external link in new windowJava Native Interface JNI und C/C++ über ähnliche Möglichkeiten. Via Opens external link in new windowCorba können Sie selbst klassische, entfernte Clients analog zu Opens external link in new windowJava RMI an Nuxeo anbinden.

Opens external link in new windowJUnit Tests der JNI Komponenten können Sie innerhalb von MS Visual Studio inklusive der Nuxeo Test-Umgebung bequem schrittweise durchführen.

Im Folgenden beschreiben wir Ihnen einen Weg, von der Erstellung einer Nuxeo Service Komponente mit Nuxeo IDE bis hin zum schrittweisen Debuggen eines JUnit/JNI Tests mit MS Visual Studio. 

 

Am Ende des Beitrags finden Sie ein einfaches Beispiel mit Projektdateien und fertigem OSGI-Bundle zum Download.

Voraussetzungen

  • Opens external link in new windowEclipse IDE for Java EE Developers
  • Eclipse Erweiterung Opens external link in new windowNuxeo IDE
  • Java Development Kit Opens external link in new windowJDK
  • Microsoft Visual Studio 2012
  • Maven 2.2.1

Nuxeo Service Komponente erzeugen

  1. Wählen Sie im Eclipse IDE den Assistenten für neue Nuxeo Artefakte.
  2. Erzeugen Sie ein neues Nuxeo Plugin Projekt und vergeben Sie Projekt ID und Root Package Name.
  3. Passen Sie die Maven Artefakt Informationen (GAV) an.
  4. Wiederholen Sie Punkt 1.
  5. Erzeugen Sie eine neue Nuxeo Komponente, wählen Sie einen vorgeschlagenen Paketnamen aus und geben Sie einen Servicenamen ein.
  6. Markieren Sie Expose this component as a service

Nuxeo IDE generiert Ihnen nun das Java Skelett für eine Nuxeo Service Komponente. Eine Service Komponente besteht aus den Methoden activate () und deactivate (), die beim Starten von Nuxeo EP respektive beim Herunterfahren aufgerufen werden.

Dadurch erhalten Sie die Möglichkeit, Ihren systemeigenen Nuxeo Service zu initialisieren und zu bereinigen. Der Aufruf von Nuxeo Core Komponenten oder Nuxeo Webservices erfolgt über JNI Callbacks.

Systemeigene Methoden integrieren

  1. Öffnen Sie das generierte Java Skelett in Eclipse IDE.
  2. Erweitern Sie die Nuxeo Service Komponente um das Laden der systemeigenen Library (Basisname ohne DLL / LIB Zusatz).
  3. Fügen Sie die Deklarationen Ihrer systemeigenen JNI Funktionen hinzu (die JNI Funktionen sind Implementierungen der zu ladenden systemeigenen Library). 
  4. Implementieren Sie die JNI Aufrufe in den Methoden activate () bzw. deactivate () der Nuxeo Service Komponente.

MyServiceComponent.java:

[..]
    static {
        System.loadLibrary("MyServiceComponent");
    }
    private native int _activate (ComponentContext context, Bundle bundle) throws Exception;
    private native int _deactivate (ComponentContext context) throws Exception;
    private native int _applicationStarted (ComponentContext context) throws Exception;
[..]

Verzeichnis der systemeigenen Library

Damit Java VM die systemeigene Library auch findet, können Sie entweder die PATH Umgebungsvariable aktualisieren, oder besser den JVM Parameter -Djava.library.path beim Aufruf der jUnit's Test- oder Nuxeo's Laufzeitumgebung verwenden. In Eclipse stellen Sie diesen Parameter über die Debug/Run Konfiguration bei VM arguments ein. Für die Nuxeo Laufzeitumgebung erweitern Sie hierzu die Nuxeo Konfigurationsdatei nuxeo.conf mit:

[..]
$JAVA_OPTS=$JAVA_OPTS -Djava.library.path=<native-library-path>
[..]

Gleiches gilt natürlich auch für nuxeo-sdk.conf, falls Sie mit Eclipse Nuxeo Integrationstests durchführen wollen.

JNI Stubs generieren

Haben Sie das systemeigene Interface festgelegt, können Sie JNI Stubs für das C/C++ Interface generieren:

javah -d <native projectdir> -classpath <classpath> <package>.<classname> [{<package>.<classname>}]

native projectdir:

Zielverzeichnis Ihres C/C++ - Projekts, in dem Sie die mit dem JNI Framework Nuxeo Komponente implementieren.

java projectdir:

Durch den Nuxeo Artefakte Assistenten erzeugte Java Projektverzeichnis.

package:

Packetname Ihrer Service Komponente.

classpath:

Verzeichnisse zu Ihren *.class Dateien + abhängige *.jar Dateien.

  Error: cannot access org.nuxeo.runtime.model.DefaultComponent
  class file for org.nuxeo.runtime.model.DefaultComponent not found

Falls Sie solche oder ähnliche Fehlermeldungen beim Ausführen von javah erhalten, können Sie über die Aufrufparameter des jUnit Tests s.u. die tatsächlich benötigten CLASSPATH Angaben ermitteln.

In diesem Zusammenhang können Sie auch die Java Signaturen für die JNI Callback Funktionen generieren. Achten Sie bei Angabe der CLASSPATH Option darauf, dass javap die *.class Dateien im <java projectdir>/bin/main Verzeichnis interpretiert:

javap -p -s -classpath <java projectdir>/bin/main <package>.<classname> [{<package>.<classname>}] > <native projectdir>\jni_signatures.txt

Hier reicht es beim CLASSPATH lediglich den Pfad zu den *.class-Dateien anzugeben.

Include Verzeichnisse

Um das JNI Framework in MS Visual Studio zu integrieren, müssen Sie <jdk>\include und <jdk>\include\Win32 in den Include-Verzeichnissen Ihres Projekts aufnehmen.


Tests erzeugen

Vor der Implementierung der systemeigenen JNI Funktionen werden die JUnit-Tests für das Nuxeo Plugin festgelegt. Testen Sie anschliessend die JUnit-Tests, da auftretende Fehler im Java Test-Code in der C/C++ Testumgebung nur schwer nachvollziehbar sind. Wenden Sie hierbei Technologien wie etwa Mocking (->native JNI Aufrufe) oder Code Review an.

JUnit Tests als Commandline Tool

Ihre systemeigenen JNI Implementierungen können Sie in der MS Visual Studio Umgebung schrittweise untersuchen. Hierzu müssen Sie MS Visual Studio über die Funktion Prozeß anfügen mitteilen, welche Prozesskennung der zu untersuchende JUnit Test bei Ausführung besitzt. Nachteilig ist dabei, dass Sie für jeden JUnit Testzyklus MS Visual Studio mit dem ausgeführten Prozeß synchronisieren müssen.

Alternativ können Sie die JUnit Testklassen über die Console und damit auch durch die MS Visual Studio Debug Umgebung ausführen:

  1. Setzen Sie einen Breakpoint im Setup der zu testenden JUnit Klasse.
  2. Starten Sie den JUnit Test.
  3. Wählen Sie in der Debug Ansicht die Eigenschaften zum javaw Prozess aus.
  4. Unter Process Information finden Sie die zugehörigen Aufruf Parameter samt CLASSPATH.

Eclipses Prozessinformationen des JUnit Tests sind Grundlage für die Integration in die Testumgebung von MS Visual Studio.

<jdk>\bin\java.exe ^
    -D-java.library.path=<native-projectdir> ^
    -classpath "<classpath>" ^
    org.junit.runner.JUnitCore ^
    org.nuxeo.sample.native.service.MyServiceComponent

MS Visual Studio

Eigentlich ist die Integration des JUnit Tests unter MS Visual Studio jetzt nur noch eine Formalität:

  1. Wählen Sie die Projekteigenschaften der systemeigenen JNI Library auf ([Alt + F7]).
  2. Geben Sie unter Konfigurationseinstellungen - > Debugging den vollqualifizierten Dateinamen zur ausführbaren Java Engine ein.
  3. Kopieren Sie die CLASSPATH-Informationen aus der Eclipse Umgebung in die Befehlsargumente von MS Visual Studio.
  4. Löschen Sie die Eclipse-spezifischen CLASSPATH-Angaben. 

$(JAVA_HOME)\bin\java.exe -Djava.library.path=$(TargetDir) -classpath <classpath> org.junit.runner.JUnitCore <package>.<classname> 

Die Länge des CLASSPATH's erreicht bei einem Nuxeo Plugin über 31 kByte! MS Visual Studio 2012 bedankt sich mit einem Fehlverhalten beim Eingeben der Befehlsargumente und bei der Ausführung des Tests.

Workaround für MS Visual Studio 2012: 

  1. Schliessen Sie die MS Visual Studio Solution.
  2. Öffnen Sie im Projektverzeichnis der systemeigenen Nuxeo Komponente die Datei <Projektname>.vcxproj.user.
  3. Tragen Sie Ihre Befehlsargument im XML Element <LocalDebuggerCommandArguments> ein.
  4. Speichern Sie die Änderung und laden Sie die MS Visual Studio Solution neu.

Alternativ können Sie die CLASSPATH Angaben in den Befehlsargumenten auch über eine Umgebungsvariable setzen.

Außerdem können Sie die CLASSPATH Angaben auf die wirklich notwendigen JAR's reduzieren. Das Verfahren ist allerdings den Nuxeo Experten unter Ihnen vorbehalten.


Download

Die folgenden *.zip Archive enthalten Projektdateien und ein installierbares OSGI-Bundle zu den oben genannten Ausführungen. Sämtliche der hier aufgeführten Ressourcen können unter Anwendung der Opens external link in new windowLGPL 2.1 Lizenz benutzt werden.

 

Installationshinweise

Initiates file downloadreadme.txt

 

Projektdateien Eclipse

Initiates file downloadeclipse-nuxeo-ide-sample.zip

MD5:5e5e7889c1d292c4d7bf7c8b2106e7dd

494 kBytes

Projektdateien Microsoft Visual Studio 2012

Initiates file downloadMyServiceComponent.zip

MD5:983101db9ccba8435ef9244d9a29318d

27 kBytes

OSGI-Bundle des Nuxeo JNI Beispiels

Initiates file downloadlemot-sample-jni-service-5.7.2-SNAPSHOT.zip

MD5:ed9b471840b53baa0659f8d361f8e6a1

477 kBytes