Developing plugins for IBM Notes on Mac

I’ve been developing plugins for IBM Notes on Mac for years now but never really got around to sharing the steps on the blog. The below steps – in very crude form – works with Java 8 on Mac OS El Capitan (v. 10.11) using IBM Notes 9.0.1. The below sections are additions to the regular steps on creating a target platform documented otherwise on this blog

Main-tab

Run a product: com.ibm.notes.branding.notes

Execution Envionment: JavaSE-1.6

Arguments-tab

Program arguments:

-personality com.ibm.rcp.platform.personality
-debug
-console
-ws cocoa

VM Arguments:

-Declipse.registry.nulltoken=true
-Djava.util.logging.config.class=com.ibm.rcp.core.internal.logger.boot.LoggerConfig
-Dcom.ibm.pvc.webcontainer.port=8080
-Declipse.pluginCustomization="/Applications/IBM Notes.app/Contents/MacOS/rcp/plugin_customization.ini"
-Djava.protocol.handler.pkgs=com.ibm.net.ssl.www.protocol
-Dosgi.hook.configurators.exclude=org.eclipse.core.runtime.internal.adaptor.EclipseLogHook
-Dosgi.framework.extensions=com.ibm.rcp.core.logger.frameworkhook
-Xbootclasspath/a:"/Applications/IBM Notes.app/Contents/MacOS/rcp/eclipse/plugins/com.ibm.rcp.base_${rcp.base_version}/rcpbootcp.jar"
-XstartOnFirstThread

Environment-tab

  • DYLD_LIBRARY_PATH=/Applications/IBM Notes.app/Contents/MacOS
  • NOTESBIN=/Applications/IBM Notes.app/Contents/MacOS

OSGi, OSGi, OSGi – OSGi everywhere…

As mentioned in my OSGi presentation at AusLUG OSGi is a key technology for you if you dabble in IBM/Lotus products. Among other things it forms the basis for Lotus Expeditor (and therefore Notes, Sametime and Symphony), XPages and the XPages Extensibility Library. OSGi is now also part of Java application servers such as Websphere Application and the free and open source JBoss AS 7. The JBoss AS7 OSGi Full Presentation + Demo highlights OSGi in JBoss and has a nice introduction to OSGi. Highly recommended.

“JBoss AS7 (jboss.org/​as7) is a game-changer for both Java EE developers as well as application server administrators. And while JBoss is best known for being a Java EE container, in this session, we will focus on the OSGi capabilities of the new JBoss AS7. Starting with background information on OSGi in general, Thomas Diesler introduces the main objectives of this technology and explains the unique JBoss OSGi vision. Combining the best of two worlds we show how modern Java EE applications on AS7 can use the OSGi component model and vice versa.”

DOTS and automatic startup of bundles

Domino OSGi Tasklet Container (or DOTS for short) is an uber-cool OpenNTF project that allows you to write addins for the Domino server in Java. The project used to be called JAVADDIN which kind of gives the purpose away.

At UKLUG I was asked if there was a way to specify which bundles to automatically start at server startup. I didn’t know the answer so I wrote an e-mail to David Taieb who’s the author of the project and he quickly responded that this is indeed possible. Below is Davids answer:

Yes, you can create a file called config.ini in
{data}/domino/workspace directory and add the following line
domino.osgi.bundles.start=pluginid1,pluginId2,pluginId3

Restart http task and verify that the plugins specified are
active
>tell http osgi diag pluginId1
>tell http osgi diag pluginId2
>tell http osgi diag pluginId3

Best Regards
-david

The above is for Domino 8.5.3 – for Domino 8.5.2 the config.ini file is in the workspace.config directory.

There is a caveat though. The automatic startup isn’t performed until an XPage request is made. An extension point to make bundles automatically startup when the server is started will be added for Domino 8.5.4.

Eclipse Helios (3.6) and why it’s important to Notes administrators

Notes 8 is based on Eclipse and Eclipse use OSGi for bundle lifecycle and dependency management. Part of OSGi is the OSGi console that is a console into the inner working of OSGi. The console is very useful and may be used to diagnose Eclipse and Notes 8 issues. I’ve previously blogged about the OSGi console and how to access it in Notes in my “SWT@Notes 8: -console” post back in 2008. One of the cool things about the OSGi console is that you can write administrative commands for the console that you may invoke using the text based interface.

One major shortcoming of the OSGi console was that one could only access it once the platform was invoked that is it couldn’t be accessed once Notes was started. This is a real bummer as it could be very useful in certain troubleshooting scenarios. This is about to change.

In the upcoming Eclipse 3.6 (Helios) release we’ll get even easier access to the OSGi console as you may attach to OSGi console after launching the platform. Yeah!!

On his blog Chris Aniszczyk of Redhat has a post called “Easier access to the OSGi console“:


In Eclipse 3.6 M7, it will be easier to access the OSGi
Console within the running Eclipse. The Equinox team
added a org.eclipse.osgi.framework.console.ConsoleSession
service that you can use to get the input and output to a
console session. The PDE team took advantage of this
recently by extending the org.eclipse.ui.console.consoleFactories
extension point and allowing you to bring up the OSGi
console easily...

Using EventAdmin for interprocess-communication

One of the tricks to really loosely coupling components in Eclipse is using an event broker to publish events and subscribe to events. You can roll your own which is easy enough (lets face it – it’s a listener interface and a list keeping track of listeners) but it adds a constraint among plug-ins. Another solution is to use the OSGi EventAdmin service.

EventAdmin uses a concept of hierarchical topics much like a messaging system (JMS) and is available from all plugins. You simply add a dependency on org.eclipse.osgi.services and you’re laughing.

This “Event Admin Service specification explained by Example” post has all the info you need to get started and if you ask nicely and there’s enough interest I might even share my EventAdmin test plugin with you… 🙂

Notes 8.5 OSGi console madness

Ahhh some of the fun stuff you see when running Notes 8.5 with the OSGi console showing… 🙂

<DWSystem> null
[<DWSystem>   11:11:46:590] partial 0.000 -
   cumulative 0.000 -
   instantiate  controller
[<DWSystem>   11:11:48:545] partial 1.955 -
   cumulative 1.955 -
   instantiate  action dispatcher
[<DWSystem>   11:11:48:870] partial 0.325 -
   cumulative 2.28 -
   instantiate ComputeAttrs
[<DWSystem>   11:11:48:880] partial 0.010 -
   cumulative 2.290 -
   instantiate AttrMap
[<DWSystem>   11:11:48:910] partial 0.030 -
   cumulative 2.32 -
   instantiate distance function
[<DWSystem>   11:11:49:855] partial 0.945 -
   cumulative 3.265 -
   set incremental augmentor to  null
[<DWSystem>   11:11:49:965] partial 0.110 -
   cumulative 3.375 -
   instantiate executor
[<DWSystem>   11:11:50:906] partial 0.941 -
   cumulative 4.316 -
   instantiate displayer
[<DWSystem>   11:11:50:971] partial 0.065 -
   cumulative 4.381 -
   instantiate treewalker
[<DWSystem>   11:11:50:976] partial 0.0050 -
   cumulative 4.386 -
   instantiate the widget manager
[<DWSystem>   11:11:51:106] partial 0.130 -
   cumulative 4.516 -
   instantiate instrumentation services
[<DWSystem>   11:11:52:021] partial 0.915 -
   cumulative 5.431 -
   instantiate the abstraction module
[<DWSystem>   11:11:52:351] partial 0.330 -
   cumulative 5.761 -
   instantiate the logical name translator
factory class name
   com.ibm.pw.DocWizard.ExpeditorWidgets.ExpWidgetFactory
Create ExpWidgetFactory
factory class name
   com.ibm.pw.DocWizard.SWTWidgets.SWTWidgetFactory
[<DWSystem>   11:12:01:577] partial 9.226 -
   cumulative 14.987 -
   instantiated the widget factory
[<DWSystem>   11:12:02:009] partial 0.432 -
   cumulative 15.419 -
   instantiate step instantiator
[<DWSystem>   11:12:02:597] partial 0.588 -
   cumulative 16.007 -
   instantiated the session trace
[<DWSystem>   11:12:03:272] partial 0.675 -
   cumulative 16.682 -
   instantiated  control loop -
   done initializing DWSystem
View initialization done
CLOSING SYSTEM

SWT@Notes 8: Logging from SWT components

As you probably know using System.out.println for logging in Java is a no-no and this is also the case when developing plugins for Notes 8 and Lotus Expeditor. This post outlines how to use the logging framework supplied with Lotus Expeditor, how to manage the logging and where the logs go.

You have probably been using log4j or similar logging framework for years. Avoiding writing to System.out is even more important when writing SWT components and plug-ins for Notes 8 a.k.a. Eclipse since the output goes to a log tucked away under the covers. Luckily there’s an approach which is so much better and more flexible.

Logging basics

Luckily logging has been built into the language (since Java 1.4) and into the Lotus Expeditor platform. Actually there is 5 different frameworks built into the Lotus Expeditor platform. Based on advise from the Lotus and personal experience I really recommend you use the java.util.logging framework built into the core Java language. This is also known as JSR47 loggers. The below graphics shows the logging sub-system of Lotus Expeditor.



Page 8 from the
IBM Lotus Expeditor 6.1 Client for Desktop Serviceability – Logging and IBM Support Assistant (PDF).

As you can see from the above you can use the following logging frameworks in Lotus Expeditor:

  • Eclipse Logging
  • OSGi Logging
  • IBM Commons Logging
  • Apache Jakarta Commons Logging
  • java.util.logging a.k.a. JSR47

I haven’t got experience with all of the these frameworks and luckily I don’t have to. I just have to know about java.util.logging and there’s an abundance of info on that on Google. The Sun tutorial might be the best place to start if you’ve never used java.util.logging. All this being equal the frameworks work the same with the only difference being how you obtain loggers and what the different logging levels are called. Log levels are called something different in the different frameworks but slide 7 in the Lotus Expeditor documentation on logging shows the mapping between the different frameworks.

Using loggers in code

Using java.util.logging in code is really easy and consists of 3 steps:

  1. Obtain the logger to use (normally in a static final variable).
  2. Write info to the logger.

The below is an example of using loggers.

package com.example.logging;

import java.util.logging.Logger;

public class MyLoggingClass {
   // logger
   private final Logger log = Logger.getLogger(
      this.getClass().getPackage().getName());

   public MyLoggingClass() {
      log.finest("Finest...");
      log.finer("Finer...");
      log.fine("Fine...");
      log.info("Info...");
      log.warning("Warning...");
      log.severe("Severe...");
   }
}

The above code creates a logger in a variable called “log” as a private variable. The logger itself is called com.example.logging which is the name used to control the log level (see below). I find it best to name the logger after the package name that contains the class. Sometimes it is however beneficial to also have a logger with more specialized names to log info on specific events.

Configuring the logger log levels

The log level for a single logger or multiple loggers can be controlled using the LogManager using the <Notes data directory>/workspace/.config/rcpinstall.properties file. To change the log level for the com.example.logging logger to FINEST add the following line to the file and restart the client:

com.example.logging.level=FINEST

To change the level dynamically use the OSGi console commands as described below.

Interacting with loggers from the OSGi console

If you start the Notes 8 client with the OSGi console visible you can interact directly with the loggers using the console command called setlogrlev. To set the log level for the com.example.logging logger to FINEST use the following command:

setlogrlev com.example.logging FINEST

Please note that the logger levels are case sensitive so you have to write “FINEST” and not “finest”.

Where the logging goes

All log messages are written to log files in the <Notes data directory>/workspace/logs directory. Opening the directory will reveal a number of files. The two most important are error-log-X.xml and trace-log-X.xml. The file names are quite explanatory and are, as the extension implies, XML-files. When you open them they’ll be rendered using a XSLT stylesheet to be displayed nicely. You can either read them using a browser or using the “Help/Support/View Log” and “Help/Support/View Trace” menu item in the Notes 8 client.

While the log files are usable I personally find it much easier and better to use the OSGi console when developing as I can adjust the log levels on the fly.

Further reading

SWT @ Notes 8: Why OSGi is important

I have posted stuff on the OSGi console previously and why it’s important but even better is to see for your self. I did this myself by adding TwitNotes console commands to the TwitNotes plugin for version 1.0.4. For the normal user it wont matter but it actually proves to be very useful for troubleshooting and something I will definitely add to the other sidebar projects I’m working on.

For more info and code example see the post “Extending the OSGI Console” by Bob Balfe.