Sunday, February 24, 2013

Domino 9 neue Optionen beim Datenbank compact

In der Version 9 wurde der compact Task um einige sehr praktische Features erweitert. Leider sind die Features in der Admin Hilfe noch nicht dokumentiert. Deshalb habe ich hier soweit bekannt die wichtigsten Infos zusammengetragen.

Compact mit mehreren Threads durchführen.

Mein absolutes Lieblingsfeature. Heutige Server mit vielen Prozessorcores und vielen Platten haben das Problem, dass bei einem Compact über alle Datenbanken Compact zwar ewig läuft, der Server jedoch nur minimal ausgelastet ist. Man hat sich dann mit .ind Files beholfen um mehr als einen Compact Task laufen lassen zu können. Die Pflege der .ind Files hat aber einen relativ großen Aufwand bedeutet und immer wieder wurden Datenbanken nicht in die .ind Files eingetragen und deshalb beim Compact nicht komprimiert. Jetzt kann man jeden Compact Befehl die Option "-# X" anhängen und es werden automatisch X Threads erzeugt die die Komprimierung ausführen. Die maximale Anzahl von Threads ist 20.

Load compact -c -# 5 z.B. führt ein copy style compact mit 5 gleichzeitig laufenden Thread durch.

Schade das ich kein Admin mehr bin. Der nächste Upgrade der ODS wird soviel einfacher und schneller sein. Ebenfalls eine große Erleichterung bei der Einführung von DAOS, da dann auch gleichzeitig in mehreren Threads Anhänge aus den Datenbanken extrahiert werden können.

Compact mit Hilfe einer neuen Replik.

In einer sehr großen Notesdatenbank kann es passieren, dass die Note ID Tabelle  zu groß, bzw. extrem fragmentiert wird. Es kann dann zu der Fehlermeldung "Unable to extend an ID table - insufficient memory" kommen. Diese ID Table wird nur beim erstellen einer neuen Replik reorganisiert. Dieses erstellen einer neuen Replik kann nun mit dem Compact Task und der neuen Option "-REPLICA" ausgeführt werden. Dabei wird ähnlich wie beim copy style compact eine neue Replik angelegt, die mit der Originaldatenbank synchronisiert wird. Dann werden alle Verbindungen zu der Original Datenbank gedroped und auf .orig  sowie die neue auf den alten Namen umbenannt. Danach werden nocheinmal etwaige Änderungen von der orig in die neue Replik synchroniesiert. Falls die Umbennenung nicht klappt, da die Datenbank trotz drop noch immer in Verwendung ist, wird ein Trigger gesetzt, dass die Umbennennung beim Server Neustart gemacht wird. Um die "-REPLICA" Funktion zu verwenden, muss das ODS auf der neuesten Version sein. Sonst bekommt man die Fehlermeldung, dass die ODS Version zu alt ist. Zusätzlich zu "-REPLICA" kann man noch mit "-IDS_FULL X" angeben, ab welchen Prozentsatz x eine Bereinigung der ID Tabelle mit Replica durchgeführt werden soll. Mit "-REN_WAIT=X" kann angegeben werden, wie viele Minuten Domino versuchen soll die Datenbank nach dem Erstellen der Replica umzubenennen, damit ein Serverneuststart vermieden werden kann. Falls die Datenbank weiter in Verwendung ist, kann man mit der Option "-RESTART" einen automatischen Serverneustart auslösen. Beim Serverneustart wird dann die neue Replik in die alte umbenannt. Das ist praktisch bei Systemdatenbanken die permanent in Verwendung sind.

Load compact -REPLICA -IDS_FULL 50 z.B. führt ein compact mithilfe einer Replik zum bereinigen der ID-Table durch, wenn die IT-Table bereits zu mehr als 50 % voll ist.

In der Public Beta hat bei mir der Parameter "-IDS_FULL" nicht funktioniert. Er hat den Compact immer gemacht, obwohl ich es an einer ganz kleinen Datenbank probiert habe. Ich habe dieses Problem im Betaforum gemeldet.

Compact upgrade

Ebenfalls neu ist die Option -upgrade die laut Hilfe die DB Classes upgraden kann. Leider konnte ich noch nicht herausbekommen was das bedeutet. Falls da jemand Infos hat bitte um einen kurzen Kommentar.

Für weitere Infos zur neuen Version schauen Sie auch auf meine Übersicht über alle Postings zum Thema Notes/Domino 9



Designer 9 hat endlich einen Debugger für SSJS in xPages

Ein großes Problem bei der Verwendung von Serverside Javascript in der xPage Entwicklung unter 8.5.x war das Fehlen eines Debuggers. In der heutigen Zeit kann man sich die Arbeit ohne leistungsfähigen Debugger eigentlich gar nicht mehr vorstellen und endlich mit Version 9 des Designers bekommen auch die xPages Entwickler diese in anderen Umgebungen selbstverständliche Hilfe.

Folgende Schritte sind für eine erfolgreiche Debug Session einzuhalten:

Als erste sollte man einen Testserver haben, da um SSJS zu Debuggen der Server mit speziellen notes.ini Variablen gestartet werden muss und diese Variablen erstens die Performance verschlechtern und auch Securityrisken mitbringen. Deshalb bitte die Testhilfeunterstützung auf keinen Fall auf produktiven Servern aktivieren!

Drei notes.ini Variablen müssen auf dem Testserver hinzugefügt werden.

JavaEnableDebug=1
JavascriptEnableDebug=1
JavaDebugOptions=transport=dt_socket,server=y,suspend=n,address=8000

Der Wert bei address gibt die Portnummer an, auf denen der Server auf Debugbefehle horchen soll. Beim Start des Debugclients im Designer muss dann genau wieder diese Portnummer angegeben werden. Der Port muss natürlich auch in einer eventuell vorhandenen Firewall freigeschalten werden.

Danach muss der Server durchgestartet werden. Laut Doku reicht das neustarten des HTTP Tasks, doch hat es in der Public Beta bei mir erst nach dem Neustart des gesamten Servers funktioniert.

Dann kann im Designer 9 eine Debugsitzung im Menü Tools gestartet werden.




Für die Debugsitzung kann man einen Namen vergeben, unter dem man die Debugkonfiguration später jederzeit wieder aktivieren kann.

Wichtig sind auch der Host und der Port. Der Host ist der Server und unter Portnummer muss die Nummer eingetragen werden, die unter "address" in der Notes.ini am Server eingetragen wurde.

Dann kann man noch einstellen, ob automatisch bei jedem Serverside javascript angehalten werden soll, oder ob nur bei explizit gesetzten Breakpoint der Debugger aktiviert werden soll.

Falls die Notes.ini Parameter nicht gesetzt sind oder der Server nicht durchgestartet wurde, bekommt man beim Start des Debuggers eine Fehlermeldung.


Wenn alles richtig gelaufen ist, bekommt man keine Fehlermeldung und beim nächsten Aufruf einer xPage auf dem Testserver wird automatisch der Debugger gestartet. Beim ersten Start des Debuggers fragt der Designer ob er zur Debugperspektive wechseln soll, was man natürlich bestätigen sollte.


Danach kann man den Javascript code Schritt für Schritt durchlaufen lassen und jederzeit die Variablen kontrollieren.


Wenn man mit dem Debuggen fertig ist, kann man die Verbindung zum Debugserver mit einem Rechtsklick auf die Verbindung und Auswahl von "Terminate" beenden.


Aufgrund der gewählten Architektur kann immer nur ein Client sich mit der Debugfunktion verbinden. Wenn ein weiterer Client eine Verbindung aufbaut, bekommt man die falsche Fehlermeldung, dass die notes.ini Variablen für die Debugfunktion nicht gesetzt sind. Deshalb sollte immer nur ein Entwickler gleichzeitig den Testserver verwenden.

Für weitere Infos zur neuen Version schauen Sie auch auf meine Übersicht über alle Postings zum Thema Notes/Domino 9 
Alle Postings zum Thema SSJS Debugger

Wednesday, February 20, 2013

Gedanken zur Edcom Nachlese 2013

Die letzten zwei Tage war ich auf der Edcom Nachlese in München. Zwei Tage vollgepackt mit interessanten Sessions, vielen Gesprächen mit anderen Anwendern von IBM Produkten und einer gemütlichen Abendveranstaltung mit sehr gutem Essen.

Einige Punkte die ich von der Veranstaltung mitnehmen konnte:

Die Sessions zu Connections waren teilweise eher weniger besucht. Im Vergleich dazu waren die Sessions zu Neuerungen in Notes/Domino 9 so voll, dass gar nicht alle sitzen konnten. Man sieht also, dass das Interesse an Notes nachwievor sehr groß ist.

In Notes und Domino 9 gibt es noch mehr Neuigkeiten als ich bisher kannte. Vielleicht kann ich noch den einen oder anderen Blogpost dazu erfassen, wenn ich auch diese Features getestet habe.

xPages ist noch immer ein großes Thema bei der IBM, auch wenn ich nach wie vor eher skeptisch bin was xPages betrifft. Der neue Serverside Javascript Debugger von xPages in Notes 9 sieht nicht schlecht aus.  Auch die Managed Beans die man in xPages verwenden kann, sind eine gute Erweiterung der Möglichkeiten des xPages Entwicklers.

Connections ist ein interessantes Produkt mit vielen Möglichkeiten, dass aber aufwendig einzurichten und vor allem zu administrieren ist. Was sich die IBM dabei denkt, dass es keine UI für die Administration gibt und man sämtliche Administrierungstätigkeiten in XML Dateien bzw über kryptische Befehle auf der Commandline erledigen soll, erschließt sich mir nicht wirklich.

Die TimetoAct hat mit dem Connections Administration Toolkit (CAT) ein sehr interessantes Werkzeug zur Administration von Connections im Angebot, dass die Defizite der IBM ausgleichen kann.

Scott Souder und Chris Crummney haben die Keynotes gehalten und konnten eine sehr positive Stimmung verbreiten. Scott Souder präsentierte erfreuliche Nachrichten für den Bereich Notes/Domino. Die Anzahl der Kunden mit aktiven Wartungsverträge ist 2012 wieder gestiegen. 1500 Kunden die Ihre Verträge früher nicht mehr verlängert hatten, sind 2012 wieder zurückgekehrt. Ich denke Scott Souder der Notes seit Version 1 kennt, hat die Fähigkeiten die Lücke die der Wechsel von Ed Brill zur mobility Sparte hinerlassen hat zu schließen. Ein Blog von Scott, ählich dem von Ed Brill ist bereits in Vorbereitung und soll demnächst online gehen.


Scott Souder hat in der Fragestunde gemeint, dass der Designer und der Notesclient getrennt werden sollen, damit die Eclipseversion des Designer schon früher aktualisiert werden kann. Aber auch der Client soll in der nächsten Major Version nach 9 auf die aktuelle Eclipseversion gebracht werden. Dies ist mir als Pluginentwickler von sehr großer Bedeutung Ebenfalls auf meine Frage hin wurde versprochen, dass auch die Bereiche die derzeit noch im alten Design sind an die neue Designsprache angepasst werden. z.B. der Anwendungs Öffnendialog wurde von ihm explizit erwähnt. Er meinte auch, dass seit der öffentlichen Beta im Dezember noch viele Verbesserungen eingebaut wurden.

Volker Weber hat seine neuesten Handys Blackberry Z10 und Nokia Lumia 920 vorgezeigt und erklärt. Blackberry 10 sieht wirklich sehr gut aus und vor allem die perfekte Trennung zwischen geschäftlicher und privater Umgebung ist ein echtes Alleinstellungsmerkmal von Blackberry. Blackberry 10 wird vom Traveler 9 unterstützt. Ein Blackberry Enterprise Server ist für Blackberry 10 nur notwendig, wenn ich die Trennung zwischen geschäftlich und privat haben möchte. Sonst kann man das Z10 auch ohne BES betreiben. Der BES 10 ist wesentlich ressourcenschonender, da er eigentlich nur mehr ein Provider für eine sichere Verbindung ins Firmennetzwerk ist. Die eigentliche Synchronisation mit Domino erfolgt ebenfalls über Activesync und dem Traveler. Auch das Lumia 920 macht einen extrem guten Eindruck und wird ebenfalls ab Traveler 9 unterstützt. Die Kamera des Lumia ist ein echtes Highlight und macht vor allem bei wenig Licht für eine Handykamera fantastische Fotos. Auch sonst läuft Windows Phone 8 extrem flüssig und ist auf jeden Fall eine Alternative zu iOS und Android.

Alles in allem eine rundum gelungene Veranstaltung, die sich auf jeden Fall ausgezahlt hat.




Sunday, February 17, 2013

Notes ist eine relationale Datenbank!

Natürlich ist der Standardspeicher NSF von Notes nach wie vor keine relationale Datenbank und auch NSFDB2 ist schon lange kein Thema mehr. Jedoch gibt es seit der Version 8 gut versteckt im Expeditor Framework eine leichtgewichtige aber nicht desto trotz sehr leistungsfähige relationale Datenbank (Apache Derby) die über eine umfangreiche SQL Unterstützung verfügt. Diese Datenbank ist sehr praktisch, wenn man Daten lokal in einer relationalen Form ablegen will. Ein Beispiel wäre man will ein Plugin, dass normalerweise nur mit einem SQL Server funktioniert offline fähig machen. Man kann aber auch Daten aus einer NSF in die Derby Datenbank kopieren und dort dann mit SQL Auswertugen über die Daten machen die mit der Notes API nur schwer oder beinahe unmöglich sind.

Wie kann man nun Apache Derby aus einem Plugin ansprechen? Als erste muss man das Derby Plugin zu den Abhängigkeiten seines Plugins hinzufügen.


Dann kann man auch schon von seinem Code auf Apache Derby zugreifen. Der folgende Code erstellt eine Datenbank mit dem Namen testDB mit einer Mitarbeitertabelle die mit ein paar Namen befüllt wird. Nachher kommt ein Query auf die neu erstellten Daten das Ergebnis wird in eine Messagebox ausgegeben. Natürlich nicht sehr sinnvoll, aber es zeigt alle notwendigen Befehle die man für die Verwendung von Derby braucht. Natürlich wird man die Initialisierung und Erstellung der Datenbank in eine eigenes Plugin auslagern, aus denen sich dann alle Plugins die Derby verwenden wollen die Connection holen. Ebenso sollte man die stmt.execute in einer Echtanwendung durch PreparedStatements ersetzen.


try {
    // Derby Datenbankverzeichnis in das Datenverzeichnis des Plugins
    // legen.
 // Dies sollte natürlich immer das gleiche sein und am besten in ein
 // Initialisierungsplugin verlegt werden.
 System.setProperty("derby.system.home", Activator.getDefault()
   .getStateLocation().toFile().getAbsolutePath());
 // Treiber für Apache Derby laden.
 Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
 // Eine Konnection zu Apache Derby erstellen und bei Bedarf die
 // Datenbank testDB erstellen.
 Connection con = DriverManager
   .getConnection("jdbc:derby:testDB;create=true");
 // Ein SQLStatement Objekt erstellen.
 Statement stmt = con.createStatement();
 // Eine Tabelle in der Datenbank erstellen.
 stmt.execute("create table mitarbeiter (name1 varchar(30), name2 varchar(30), department varchar(30))");
 // Ein paar Sätze hinzufügen.
 stmt.execute("insert into mitarbeiter values('Ralf','Petter','IT')");
 stmt.execute("insert into mitarbeiter values('Max', 'Mustermann','IT')");
 stmt.execute("insert into mitarbeiter values('Lieschen', 'Müller','Sales')");
 // Ein Query auf die Datenbank absetzen.
 ResultSet rs = stmt
   .executeQuery("Select * from mitarbeiter where department='IT'");
 // Ergebnis verarbeiten und als Messagebox anzeigen.
 StringBuilder result = new StringBuilder();
 while (rs.next()) {
  result.append((rs.getString("name1").trim() + " "
    + rs.getString("name2").trim() + "\n"));
 }
 MessageBox box = new MessageBox(PlatformUI.getWorkbench()
   .getActiveWorkbenchWindow().getShell());
 box.setMessage(result.toString());
 box.open();
 // Mitarbeiter Tabelle wieder löschen.
 stmt.execute("Drop table mitarbeiter");
 // Derby wieder herunterfahren.
 DriverManager.getConnection("jdbc:derby:;shutdown=true");
} catch (Exception e) {
 e.printStackTrace();
}

Eine SQL Datenbank kann in vielen Projekten sehr nützlich sein und mit dem Notesclient hat man eine sehr leistungsfähige immer bei der Hand.

Saturday, February 16, 2013

Improve sonos with a great idea of vowe

Please help and vote for the great idea of volker weber to improve the sonos experience.

https://ask.sonos.com/sonos/topics/programable_buttons_on_sonos_components

http://vowe.net/archives/013685.html

Edcom Nachlese 2013

Bin heuer das erste mal auf der Edcom Nachlese in München. Freue mich schon von den Neuheiten von der Lotusphere Connect 2013 zu hören. Leider kommt Ed Brill, der als Referent angekündigt war, verständlicherweise nicht mehr, aber ich denke es wird trotzdem eine sehr interessante Veranstaltung.

Vor allem freue ich mich auch schon auf einen Meinungsaustausch bezüglich des neuen Notesrelease, das ich persönlich eher zweispältig sehe. Siehe auch meine diversen Blogposts zum Thema Notes 9.

Notes 9 Volltextsuche kleine Änderung große Usability Verbesserung
Notes 9 Suche in Ansichten wurde vereinheitlicht und verbessert. 
Neues Feature Database Maintenance in Domino 9
Coole neue notes.ini Variable in Domino 9 für Copy style compact
Notes 9 SE erste Eindrücke aus Sicht des Plugin Entwicklers 
Erste Eindrücke vom Browserplugin und iNotes 
Notes 9 als Anwender; erster Blick Hui, zweiter Blick leider Pfui. 
Notes 9 Verbesserung beim e-mail typeahead 

Lotusscript Code aus Java plugin aufrufen

In bestehenden Notesanwendungen steckt jede Menge Lotusscript Code der über viele Jahre aufwendig entwickelt wurde, deshalb möchte man bei der Entwicklung von Plugins nicht das Rad neu erfinden, sondern bestehenden Code auch aus Eclipse plugins aufrufen. Wie dies geht möchte ich heute gerne zeigen:

Als erstes muss man die Notes API (com.ibm.notes.java.api und com.ibm.java.ui) dem Plugin als Abhängigkeit hinzufügen.

Als Beispiel habe ich eine scriptlibrary mit einer Funktion getUmsatz mit den Parametern Kundennummer und Jahr hergenommen. In der Funktion der Scriptlibrary werden aufwendige Datenbankzugriffe und Berechnungen durchgeführt, die wir in java nicht nachprogrammieren wollen.

Da man von Java nicht direkt auf die Library zugreifen kann, braucht man als erstes einen kleinen Agent der als Brücke zwischen dem Plugin und der Scriptlibrary fungiert.



Option Public
Option Declare
Use "UmsatzScriptLibrary"
Sub Initialize
 Dim ses As New NotesSession
 Dim context As NotesDocument
 Set context=ses.Documentcontext
 Call context.Replaceitemvalue("umsatz", getUmsatz(context.Getitemvalue("kundenNummer")(0), context.getItemValue("jahr")(0)))
 Print context.Getitemvalue("umsatz")(0)
 context.save True,false
End Sub


Der Agent macht nichts anderes, als dass er ein in Memory Dokument über den Dokumentcontext holt. Die Aufrufparameter für die getUmsatz Funktion ausliest und das Ergebnis der Funktion in der Variable Umsatz speichert. Natürlich konnte man den Agent auch dahingehend erweitern, dass in dem in Memory Dokument auch ein Parameter für die auzurufende Funktion mitgegeben wird und er dann die richtige Funktion aus der Scriptlibrary aufruft.

Wichtig bei dem Agent ist, dass man das Ziel auf "None" setzt. Sonst funktioniert der Zugriff auf das übergebene Dokument nicht zuverlässig.


Der Javateil ist etwas aufwendiger:


public static void berechneKundenUmsatz(String kundenNummer, int jahr) {
  try {
   // Starte den Zugriff auf den Workspace und erstelle ein
   // NotesAgentDataobjekt mit unserem Brückenagent.
   NotesUIWorkspace ws = new NotesUIWorkspace();
   NotesAgentData data = new NotesAgentData(new NotesDatabaseData("",
     "test.nsf"), "agent");
   // Füge die Aufrufparameter für die Scriptlibrary dem data Objekt
   // hinzu. Diese werden später im documentcontext als Items
   // verfügbar.
   data.addItem("kundenNummer", kundenNummer);
   data.addItem("jahr", new Integer(jahr).toString());
   // Erstelle ein Callback Objekt. die Methode done dieses Objekts
   // wird nach Ausführung des Brücken Agent aufgerufen.
   NotesDocumentDataCallback callBack = new NotesDocumentDataCallback() {
    @Override
    public void done(final NotesDocumentDataEvent event) {
     // Erstelle einen Notessessionjob in dem wir auf das
     // zurückgegebene Dokument zugreifen können.
     NotesSessionJob job = new NotesSessionJob(
       "verarbeite Ergebnis") {
      @Override
      protected IStatus runInNotesThread(Session session,
        IProgressMonitor arg1) throws NotesException {
       // Lade das Dokument, dass der Agent mit dem
       // Ergebnis befüllt hat.
       Document doc = event.getDocumentData()
         .open(session);
       // Speichere das Resultat in einer Finalen Variable,
       // dass wir es im UIThread weiterverwenden können.
       final double result = doc
         .getItemValueDouble("umsatz");
       // Mache irgendetwas im UI mit dem Resultat. In
       // unserem Beispiel eine Dialogbox anzeigen.
       Display.getDefault().asyncExec(new Runnable() {
        @Override
        public void run() {
         MessageBox box = new MessageBox(PlatformUI
           .getWorkbench()
           .getActiveWorkbenchWindow()
           .getShell());
         box.setMessage("Das Ergebnis ist: "
           + result);
         box.open();
        }
       });
       return Status.OK_STATUS;
      }
     };
     // starte den Notesjob
     job.schedule();
    }
   };
   // Führe den Agent mit dem data und callback Objekt aus. Der letzte
   // Parameter bedeutet, das der UIContext keine Rolle spielt. Das
   // heißt es ist egal auf welches Dokument im UI derzeit geöffnet
   // ist.
   ws.runAgent(data, callBack, false);
  } catch (NotesException e) {
   e.printStackTrace();
  }

 }
Das ist jetzt natürlich nur ein kleines Beispiel, bei dem der Aufwand vielleicht nicht dafür steht, aber in dem Lotusscript agent kann auch auf das UI zugegriffen werden. Das heißt der Agent kann Dialoge anzeigen und er kann auch mehrere Werte oder eine ganze Liste als Ergebnis zurückliefern. Damit kann man auch bei der Entwicklung von Plugins sehr leicht bestehenden Code wieder verwenden.

Wednesday, February 6, 2013

Experience Webseite der IBM wurde für Version 9 aktualisiert

Die IBM hat eine sehr schöne Webseite über die neuen Funktionen und die Vorteile von Notes 9 gegenüber anderen e-mail Systemen zusammengestellt.

Für weitere Infos zur neuen Version schauen Sie auch auf meine Übersicht über alle Postings zum Thema Notes/Domino 9 
ad