Friday, April 13, 2012

Bestehende Eclipse RCP auf den Mac portieren Teil2

Nach dem ich mich in Teil 1 damit beschäftigt habe, wie man eine Eclipse RCP für den Mac kompilieren kann, möchte ich mich jetzt damit beschäftigen, was man beim Zugriff auf Lotus Notes aus der RCP heraus beachten muss. damit diese auch auf dem Mac funktioniert.


Bevor wir uns um die Portierung auf den Mac kümmern ein paar prinzipielle Dinge wie der Zugriff auf Notes technisch funktioniert. 


Die Klassen des Java APIs von Lotus Notes befinden Sich in der Notes.jar. Diese Datei finden Sie unter Windows im Verzeichnis C:\Program Files (x86)\IBM\Lotus\Notes\jvm\lib\ext.  Diese Datei muss sich im Klassenpfad befinden, damit Sie verwendet werden kann. Ich habe diese Datei der Einfachheit in ein Plugin importiert, dass die Klassen exportiert, damit ich nicht jedesmal die Notes.jar suchen muss. Prinzipiell kennt das Java API von Notes zwei Zugriffsmöglichkeiten:

DIIOP

Dafür muss ein eigener DIIOP Task am Server laufen, der die Zugriffe auf die Dominodaten durchführt. Auf den Client ist dann nichts mehr weiter nötig als die Notes.jar. Ich verwende diese Möglichkeit nicht sehr gerne, da erstens die Performance sehr bescheiden ist und DIIOP viele Bugs hat.

Lokaler Zugriff

Dabei fungiert die Notes.jar nur als leichtgewichtiger Wrapper für die DLL nlsxbe.dll die Teil des Notes Clients ist. Die Notes.jar besteht sozusagen nur aus JNI Aufrufen. Jeder Aufruf einer Methode in der Notes.jar ruft im Hintergrund eigentlich eine Methode in der nlsxbe.dll auf. Das API der liblsxbe.dll wurde ursprünglich für Lotusscript erstellt und wird von der Notes.jar mitbenützt. Der Vorteil davon ist, dass sich das Java Api praktisch 1:1 zu dem Lotusscript API verhält. Was die Einarbeitung von Lotusscript Anwendern verkürzt. Der Nachteil für Javaentwickler ist, dass das API teilweise seltsame Eigenheiten wie z.B. die Notwendigkeit von recycle() zum aufräumen von C++ Objekten aus nlsxbe.dll notwendig macht.

Leider ist es jetzt aber so, dass die nlsxbe.dll im Hintergrund noch andere DLL's des Notes Client verwendet.

Warum muss man das ganze überhaupt wissen? Ganz einfach wenn man in sein Programm die Notes.jar einbindet und per lokalen Zugriff auf Notes Daten zugreifen will, muss die JVM die notwendigen DLL's finden. Die JVM sucht die DLL's im sogenannten Library_Path. Dieser wird mittels der JVM Option "-Djava.library.path="C:\Program Files (x86)\IBM\Lotus\Notes" gesetzt. Nun findet die JVM zumindest mal die nlsxbe.dll. Aber das die nlsxbe.dll noch andere DLL's laden will, dabei aber vom Java library path nichts mehr weiß, muß das selbe Verzeichnis wie oben auch im Windows PATH sein.

In einer RCP setzt man den Library Path am besten in der Product Beschreibung auf der Launcherseite. Diese Einstellungen können und müssen für jede Plattform extra gesetzt werden.

Hier die Einstellung für Windows

Die Doppelten "\\" sind notwendig, damit beim Erstellungsvorgang der RCP keine Zeilenschaltungen eingefügt werden.

Zusätzlich muss auf Windows unbedingt noch in der Systemsteuerung des Zielcomputers die Pfadvariable angepasst werden. Leider gibt es keine Möglichkeit dies direkt in der RCP Anwendungen zu machen. Da ich sowieso immer MSI installer baue, ist das aber kein Problem.

Hier die Einstellung für den Mac

Am Mac werden DLL's die hier die Endung .dyld haben nicht über den Pfad aufgelöst, sondern der Mac sucht diese in diversen Standardsuchpfaden in denen Notes aber nicht enthalten ist und in den Verzeichnissen die in der Umgebungsvariable "DYLD_Library_PATH" angegeben sind. Wie kann man so eine Umgebungsvariable am Mac setzen. Wie immer am Mac geht das nicht so einfach wie in anderen Umgebungen. Während es unter Windows ein UI gibt um die Umgebungsvariablen zu ändern muss man in Mac OS X wie in Unix mit Konfigurationsdateien arbeiten:

Eine globale Änderung der Umgebungsvariablen kann man für einen Benutzer machen indem man die Datei "environment.plist" im versteckten Verzeichnis ".MacOSX"anlegt. (Wie zeige ich versteckte Dateien und Ordner am Mac an?)

Die Datei muss folgenden Aufbau haben:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>DYLD_Library_PATH</key>
    <string>/Applications/Notes.app/Contents/MacOS</string>
</dict>
</plist>

Falls man Lotus Notes in ein anderes Verzeichnis installiert hat, muss man natürlich den Pfad anpassen.

Diese Vorgehendsweise hat aber den Nachteil, dass auch andere Programme durch diese Änderung beeinflusst werden und Apple in manchen Versionen seines Betriebssystems diese Vorgehendsweise überhaupt unterbunden hat.

Deshalb die bessere Möglichkeit ist es in der von Eclipse erstellten Applikation die info.plist zu ändern. Die info.plist ist am Mac die zentrale Datei die steuert wie ein Programm aufgerufen werden soll. Man findet die Datei wenn man mit der rechten Maustaste auf eine Applikation klickt und in dem Kontextmenü den Punkt "Paketinhalt zeigen" aufruft. Dann zeigt der Finder den Inhalt der Applikation an. Im Verzeichnis Contents befindet sich dann die info.plist. Einfach die Datei mit dem Editor öffnen und innerhalb des dict Blocks folgenden Inhalt einfügen.

<key>LSEnvironment</key>
<dict>
     <key>DYLD_LIBRARY_PATH</key>
     <string>/Applications/Notes.app/Contents/MacOS</string>
</dict>

Vorsicht Änderungen an der info.plist werden in MacOSX gecached und der Mac erkennt diese Änderungen leider nicht. Deshalb muss man nach der Änderung unbedingt den Cache aktualisieren:

Dazu geht man in ein Terminal und führt folgenden Befehl aus:

/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -v -f /Applications/eclipse/XXX.app

Wobei /eclipse/XXX durch den Applikationsnamen und Pfad ersetzt werden sollte.

Dann sollte auch der Zugriff auf das Java API von Notes funktionieren.

No comments:

Post a Comment

ad