Showing posts with label Eclipse. Show all posts
Showing posts with label Eclipse. Show all posts

Friday, October 19, 2012

Selektives Auto Deployment von Widgets

Das Verpacken von Eclipse Features und Plugins in Widget ist wirklich eine praktische Sache und über den Widgetkatalog kann man diese Widgets auch gut anderen Benutzern zur Verfügung stellen. Weniger elegant sind aber die Möglichkeiten mit denen man die Installation von Widgets automatisieren kann. Standardmäßig kann man einem Widget mehrere Kategorien zuweisen. Man kann dann bei einem Benutzer eine oder mehrere dieser Kategorien in den Benutzervorgaben einstellen (oder per Desktop Policy setzen) und es werden alle Widgets dieser Kategorien bei dem Benutzer installiert und im Bedarfsfall aktualisiert.

So weit so gut, aber bei intensiverer Verwendung dieser Technik zeigen sich doch ein paar Schwachstellen:

  • Man kann zwar über Desktoppolicy festlegen welche Kategorien von Widgets bei einem Benutzer installiert werden sollen, ich kann aber nicht verhindern, dass sich ein Benutzer andere Widgetkategorien selber nachinstalliert. Das ist natürlich problematisch, wenn man Widgets hat die nicht jeder Benutzer installieren können soll.
  • Wenn man mehr als eine handvoll Widgets und Gruppen von Personen die unterschiedliche Arten von Widgets benötigen hat dann braucht man sehr viele verschiedene Desktoppolicy Dokumente und das ganze wird schnell unübersichtlich.
  • Die zur Verfügungstellung von neueren Versionen von Widgets zum Testen ist schwer oder gar nicht möglich.

Da ich in meiner Umgebung mittlerweile von allen oben angeführten Problemen betroffen bin, habe ich eine Möglichkeit zur Lösung der Probleme gesucht die ich kurz erklären möchte.

Ich habe das Design des Widgetkatalogs dahingehend erweitert, dass ich ein Mehrfachwert Leserfeld zu der Widgetmaske hinzugefügt habe. Weiters habe ich das bereits bestehende berechnete Leser Feld in der Maske von "" auf "LocalDomainServers" geändert, damit es keine Probleme bei der Replizierung von Widgets zwischen den Servern gibt.


Nun habe ich die Kategorie aller Widgets auf eine Kategorie gesetzt die bei allen Benutzern installiert wird und kann aber über das Leserfeld ganz exakt steuern wer dieses Widget bekommen soll oder nicht. Natürlich lassen sich in dem Leserfeld auch wieder Gruppen eintragen.

2 Nachteile dieser Lösung:

  • Designänderungen von Systemdatenbanken bergen immer wieder das Risiko, dass es bei Updates zu Problemen kommt. 
  • Wenn man einen Benutzer aus dem Leserfeld entfernt, wird zwar das Widgetdokument aus seinem lokalen Widgetkatalog entfernt aber leider der Provisioningprozess nicht angestartet. Das heißt das Widget wird nicht sofort entfernt, sondern erst bei der nächsten Änderung eines Widgets das auf den Rechner des Benutzers repliziert wird. Ich löse das Problem in dem ich ein Dummywidget habe, dass ich bei einer Entfernung eines Benutzers neu speichere. Dann erkennt der Notesclient die Änderung und entfernt auch das verschwundene Widget aus dem Client.

Thursday, August 23, 2012

Eclipse Befehlszeilenparameter an notes.exe übergeben.

Eclipse als Basis für Lotus Notes ab der Version 8 bietet jede Menge praktischer Befehlszeilenparameter. Normalerweise kann man diese bei einer RCP Anwendung einfach hinter die ausführbare Datei anhängen.

z.B. "eclipse.exe -console" um die OSGI Console mit eclipse mitzustarten.

Bei Lotus Notes geht das nicht so einfach, da Notes eigene Befehlszeilenparameter wie z.B. den "-sa" Parameter verwendet. Es gibt aber Abhilfe, in dem man den  Parameter "-RPARAMS" + den eclipse RCP Befehlszeilenparameter voranstellt.

z.B. um die OSGI Console mit Notes mitzustarten kann man "notes.exe -RPARAMS -console" aufrufen.

Ein anderer praktischer Befehlszeilenparamter ist "-clean" Es weist Eclipse an nicht den Extension Registry Cache zu verwenden, sondern die Plugins neu einzulesen. Dies muss man z.B. machen, wenn man neue Plugins in die Verzeichnisstruktur von Lotus Notes einkopiert hat und diese beim start von Notes verwendet werden sollen.


Eine Übersicht über alle Befehlszeilenparameter die Eclipse und damit auch Lotus Notes unterstützt findet man in der Eclipse Doku.

Tuesday, May 22, 2012

Workspace Pfad mit Einstellungen für Plugins in Notes/Eclipse

Jedes Plugin in Notes/Eclipse kann Einstellungen haben, die bestimmte Funktionalitäten des Plugins steuern.

Diese Einstellungen werden in dem Pfad "workspace\.metadata\.plugins\org.eclipse.core.runtime\.settings" abgelegt. Für jedes Plugin, dass Einstellungen (Preferences) verwendet, wird ein eigenes Prefs File erstellt. Diese PrefsFiles können mit einem Texteditor problemlos editiert werden und sind als Schlüsselwort Wert Paare aufgebaut. Normalerweise ist es so, dass wenn man die Prefsdatei löscht, wird das File beim nächsten Laden des Plugins wieder mit Defaulteinstellungen erstellt. Das kann auch helfen, wenn in Lotus Notes irgendwas nicht so funktioniert wie es soll. Statt des Löschen des gesamten workspace Ordner kann man zielgerichtet einzelne Einstellung rauslöschen.

Thursday, April 19, 2012

Stacküberlauf beim Debuggen von Notesplugins

Wenn man Lotus Notes aus Eclipse zum Debuggen von selbsterstellten Plugins aufruft, wird das UI von Lotus Notes nicht richtig angezeigt und man bekommt einen sehr langen Stacktrace der mit

at java.util.regex.Pattern$Curly.match1(Pattern.java:3808) 
at java.util.regex.Pattern$Curly.match(Pattern.java:3757)
at java.util.regex.Pattern$GroupHead.match(Pattern.java:4179)
at java.util.regex.Pattern$GroupHead.match(Pattern.java:4179)
at java.util.regex.Pattern$Curly.match0(Pattern.java:3800)
at java.util.regex.Pattern$Curly.match(Pattern.java:3755)
at java.util.regex.Pattern$Begin.match(Pattern.java:3131)
at java.util.regex.Matcher.search(Matcher.java:1116)
at java.util.regex.Matcher.find(Matcher.java:546)
at com.ibm.css.parser.CSSParserImpl.parse(CSSParserImpl.java:106)
at com.ibm.css.parser.CSSParserImpl.parse(CSSParserImpl.java:59)
at com.ibm.rcp.ui.css.StyleManager.handleRules(StyleManager.java:269)
at com.ibm.rcp.ui.css.StyleManager.handleRules(StyleManager.java:275)
at com.ibm.rcp.ui.css.StyleManager.parse(StyleManager.java:218)
at com.ibm.rcp.ui.internal.themes.ThemeManager.setCurrentTheme(ThemeManager.java:303)
at com.ibm.rcp.ui.internal.themes.ThemeManager.<init>(ThemeManager.java:187)
at com.ibm.rcp.ui.internal.themes.ThemeManager.getInstance(ThemeManager.java:216)
at com.ibm.rcp.ui.internal.themes.ThemeServiceFactory.getService(ThemeServiceFactory.java:30)
at org.eclipse.osgi.framework.internal.core.ServiceUse$1.run(ServiceUse.java:117)
at java.security.AccessController.doPrivileged(AccessController.java:202)
at org.eclipse.osgi.framework.internal.core.ServiceUse.getService(ServiceUse.java:115)

 .. 51 more

endet.


Der Grund dafür ist, dass im DebugMode der Speicher auf dem Stack ausgeht. Dieses Problem kann man einfach umgehen in dem man in der Launch Configuration von Lotus Notes in Eclipse den JVM Parameter Xss1m setzt.

Folgende Schritte sind für die Änderung durchzuführen:

Den Debug Configurations Dialog über das Menü aufrufen


In der Launchconfiguration von Lotus Notes auf dem zweiten Tab "Arguments" den zusätzlichen Paramter Xss1m setzen.

Dann auf Apply drücken und die Debug Configuration starten. Dann sollte Notes ohne UI Probleme auch im Debug Mode laufen.

Monday, April 16, 2012

Den Öffnen Knopf im Lotus Notes Client erweitern

Die Dokumentation zu Expeditor ist ja eher unübersichtlich, daher hier eine kleine Anleitung wie man ein bestehendes Plugin erweitern muß, damit man im Launcher (Öffnen Knopf) eigene Einträge platzieren kann.

Die Voraussetzungen für diese Beschreibung ist, dass in Eclipse bereits die Targetplattform für Notes eingerichtet ist und sich Notes aus Eclipse heraus starten lässt. Entweder mittels Expeditor Toolkit oder der Beschreibung von Mikkel Heisterberg. 

Dann legen wir mit dem entsprechenden Assistenen in Eclipse ein neues Pluginprojekt an.

In diesem neuen Plugin müssen wir folgende zusätzliche Abhängigkeiten hinzufügen:
 
Diese sind notwendig, damit man das UI von Lotus Notes erweitern kann.

Danach kann man in seinem Plugin den Erweiterungspunkt "com.ibm.rcp.ui.launcherSet"erweitern.



Dann sollte man einen LaunchItemType anlegen. Ein LaunchItemType kann für mehrere LaunchItems zuständig sein. Die Klasse MyLaunchHandler müssen wir später noch selbst anlegen.


Jetzt können wir die von uns gewünschten LaunchItems anlegen. Zuerst "Test1"

Natürlich kann man wenn gewünscht auch noch Icons angeben.

und dann als Übung einfach noch ein zweites mit "Test2" anlegen.


Dann muss man die Klasse MyLaunchHandler erstellen. Normalerweise kann man das bequem über den Link "class*:" beim LaunchItemType machen. Aber die IBM hat obwohl Lotus Expeditor noch ziemlich neu ist schon ein ziemliches Chaos angerichtet und deshalb gibt es die Basisklasse LaunchItemContribution bereits in zwei verschiedenen Paketen. In der Extensionpointbeschreibung ist blöderweise die falsche angegeben. Aber kein Problem einfach über den Eclipse Assistenten eine neue Klasse erstellen.


Wichtig ist, dass der Name übereinstimmt mit dem Klassennamen den wir im Type angegeben haben. In Echt wird man das ganze natürlich in ein vernünftiges Paket packen. Weiters ist wichtig, dass man als Superclass die LauncherContributionItem Klasse aus com.ibm.rcp.ui.launcher und nicht die aus jfacex nimmt.

In die Neuerstellte Klasse muss dann nur noch eine Launchmethode eingefügt werden.

public void launch(int arg0) {
        super.launch(arg0);
        MessageBox msg = new           MessageBox(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
        if (getId().equals("org.startmenuitem2")) {
            msg.setMessage("Es wurde Test2 ausgewählt");
        }
        if (getId().equals("org.startmenuitem1")) {
            msg.setMessage("Es wurde Test1 ausgewählt");
        }
        msg.open();
    }


Diese wird aufgerufen jedes Mal wenn ein Launchitem des von uns erstellten Typs aufgerufen wird. Anhand von getId() kann man dann abfragen welches item konkret der Benutzer aufgerufen hat. Wir zeigen dann mal die entsprechende Messagebox an. In meinen Plugins wird meist ein Assistent aufgerufen, der von Benutzern einige Eingaben erfordert und dann z.B. eine neuen Reiter mit einem Eclipse UI im Notes öffnet.

Friday, April 13, 2012

Standardausgabe von Javaplugins im Notesstandardclient

Oft schreibt man zu Debugzwecken in eigenen Plugins Statusmeldungen an die Standardausgabe. Diese werden wenn man den Notesclient aus Eclipse aufruft auch toll in der Console von Eclipse angezeigt. Aber wo findet man diese Ausgabe wenn man den Client normal gestartet hat. Die Antwort ist ganz einfach im Menü "Hilfe" ->Support gibt es den Punkt "Trace anzeigen" wenn man diesen aufruft, bekommt man eine XML Seite in der neben vielen anderen Meldungen auch die Ausgaben die man in seien Plugins an die Standardausgabe geschickt hat angezeigt werden.


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.

Thursday, April 12, 2012

Bestehende Eclipse RCP auf den Mac portieren Teil1

Ich habe eine Eclipse RCP Anwendung erstellt, die Daten über das Java API aus einer Notesdatenbank ausliest und verarbeitet. Diese Anwendung wurde in erster Linie für Windows erstellt aber durch die Plattformunabhängigkeit von Java sollte die Anwendung ja auch problemlos am Mac laufen. Bei meinen Versuchen der Portierung auf den Mac bin ich dabei auf ein paar Hürden gestossen, die nicht ganz einfach zum Umschiffen waren:

Teil1: Installation des Deltapacks in die Targetplattform

Das Deltapack muss die selbe Version haben wie die Targetplattform. Für 3.7 findet man das Delta Pack z.B. auf http://download.eclipse.org/eclipse/downloads/drops/R-3.7-201106131736/winPlatform.php .


Den Inhalt des Zips dann einfach in das Verzeichnis der Targetplattform entpacken.

In seiner Eclipse Entwicklungsumgebung muss man nach dem Entpacken die Targetplattform neu einlesen, damit Eclipse die Änderungen erkennt.


Danach sollte es problemlos möglich sein die bestehende Anwendung nicht nur für die aktuelle Plattform sondern auch für andere Plattformen wie den Mac zu erstellen.

Man geht dazu in die Produktdefinition der RCP Anwendung. Als erstes auf die Seite "Dependencies" und klickt dort auf den Knopf "Add required plugins". Es sollten dann automatisch die Fragmente für die verschiedenen Platfformen hinzugefügt werden.

 Jetzt kann man auf der Overview Seite auf den Link "Eclipse product export wizard" klicken. Wenn das Deltapack ordnungsgemäß installiert wurde, dann bekommt man in dem Assistenten die Möglichkeit die RCP für verschiedene Plattformen zu packen. Ganz wichtig ist, es wenn man eine Anwendung für den Mac erstellt diese unbedingt in ein ZIP zu exportieren, da es sonst zu Problemen mit den Dateinamen unter Windows kommen kann.

Auf der nächsten Seite des Assistenten kann man dann die Zielplattform auswählen dier erstellt werden soll. In meinen Fall Mac OS cocoa.


Das erstellte ZIP kann man dann einfach auf dem Mac in den Programme ordner entpacken und die Anwendung kann schon mal aufgerufen werden.

Für den Zugriff auf Notes sind jedoch noch weitere Schritte nötig, die ich im nächsten Blog Post näher erklären will.


ad