A serious blow for AppDev on Notes – the proof of entitlement for Lotus Sametime is seriously screwed up!

As you probably know you are entitled to a Lotus Sametime Entry license when you have a “Lotus Notes for Collaboration” license. This is really great and a real selling point for Notes since Sametime is a “first class citizen” in the Notes 8.x client as it provides you with awareness throughout the client and in custom applications including sidebar plug-ins. It also allows for awareness in web pages using either Sametime Links (stlinks) or the newer and much better Sametime webapi (as used in Lotus Connections 2.x).

So now comes the problem – have you ever read the PoE or Proff of Entitlement for Lotus Sametime as it pertains to the Lotus Notes for Collaboration license? Probably not. Read below and weep!! (or read the full document – the text for “IBM Lotus Notes for Collaboration” is on page 2 of that document)

“A valid POE for the IBM Lotus Notes for Collaboration does not include the right to:
1. … (omitted for brevity)
2. … (omitted for brevity)
3. Enable or use IBM Lotus Sametime Limited capabilities beyond the default settings in the Program as provided to You, or as established by policy within IBM Lotus Sametime server, including without limitation: Lotus Sametime Connect client, IBM Lotus Sametime Web conferencing capabilities, access from a mobile device, use of IBM Lotus Sametime Gateway, voice chat, video chat, file transfer, geographic location awareness, IBM Lotus Sametime toolkits or APIs, or plug-ins and applications built using the IBM Lotus Sametime unique APIs available in the IBM Lotus Sametime toolkits, with the exception of the chat logging service provider interface.

A POE for IBM Lotus Notes for Collaboration includes all rights granted hereunder for IBM Lotus iNotes for Collaboration.”

So this is lawyer speak and quite convoluted but in essence it says that a Lotus Notes for Collaboration licensed user may

  • use Sametime for chat and awareness using the default settings on the server (meaning no custom business card or photo)
  • not use file transfer
  • not use any Lotus Sametime API besides the chat logging API

The first two are IMO hopeless restrictions but the last one is really, really, really, really bad! It’s beyond words actually. It means that you as a developer must require that a user has a Sametime Standard license in order to use Sametime awareness in your own applications. To be fair it could be that this is only the case for sidebar applications and SWT based composite application components and doesn’t pertain to forms/views (though you could argue that they use an API as well). Another thing that this entails is that you may not use Sametime awareness in Lotus Connections as it uses a API to do the awareness (Sametime webapi). I just checked the PoE for Lotus Connections and no further Sametime entitlement is extended there.

So what does this mean for me as an application developer? Well it means that the sidebar applications I’m developing have to distinguish between Sametime users and make sure that Sametime functionality is only exposed to Sametime Standard license holders. How do I do that? Not sure as I don’t know of an API which tells me which Sametime license the current user has. Oh – and it has to be a Notes API as I otherwise technically violate the license agreement on behalf of the user.

Who came up with this? What sense does it make to provide less functionality in API than in the UI? I really don’t get it. If I had anything to say at all the restriction on API’s in the client should be lifted. It is these API’s that makes the platform strong and feel coherent since applications running on the platform can leverage the platform.

So from being really psyched about the appdev perspective in Notes as it pertains to Sametime and how Sametime could be used throughout the client I’m now really bummed out. From a customer standpoint it’s going to be difficult to tell them that many of the demos that IBM do require a Sametime Standard license. And then we have our own applications where we have to informing and making sure they understand what they may use based on the license they hold.

Sigh….

(As always I could be wrong about this but I have just been through IBM Lotus here in Denmark which says I have understood the PoE correctly so I’m probably right.)

IBM / SAP Alloy dissected

After the announcement of the general availability of IBM/SAP Alloy the other day I downloaded the package to find out which components it is made up of. Below are some tidbits that may or may not be of interest to you.

Download packages

  • Client package == plugin
  • Domino Server package
  • SAP Server package
  • Documentation package

Parts

  • Plug-in to Notes 8.0.2 or newer
  • Domino Server component
    • Notes database with a web service
    • This database is used to configure the available applications and hostname for the SAP server
  • Updates to the user mail database
    • Description: “The Alloy by IBM and SAP Mail Template Update Tool adds additional and required design elements to the master IBM Lotus Notes and IBM Lotus Domino mail template. This is required to enable integrated Alloy functionality in user’s mail and calendar views. The additional design elements are supplied in the NDERPmail.ntf template, which is typically resident in the Dominodata directory on the Alloy server. “

SAP applications

  • Leave management
  • Travel management
  • Reports
  • Customized decision workflow applications

More info

IBM/SAP Alloy InfoCenter

It appears that the Notes plug-in reads the webservice address from the plugin_customization.ini file (com.ibm.nderp.client/NDERPMDWS_URL=http://hostname/nderpws.nsf/MetaDataService?openwebservice) or from the notes.ini file (NDERPMDWS_URL)

How to deploy widgets and/or plugins in your organization

Deploying widgets and/or plug-ins in your organization is very easy and there’s a number of options for doing it.

  1. Desktop policies
  2. Widget catalog via MyWidgets
  3. Drag’n’drop of widgets to the MyWidgets sidebar plug-in

Using a desktop policy is just a administration shorthand for using the widget catalog via MyWidgets.

The first thing you really should do, if not simply using publishing widgets created through the MyWidgets functionality, is to read up on and understand the Lotus Expeditor provisioning manifest syntax. The manifest is used to specify where the update site server is and which features and in which version to install. The manifest looks weird at first but it’s actaully easy enough. Unfortunately there isn’t a nice UI for creating these provisioning manifests but I head rumors in the Meet the Developers lab at Lotusphere that a UI is coming. Soon… ๐Ÿ™‚

And now for the time and frustration saver…

Absolutely make sure that you put the widget catalog in the root of the Domino server to make sure it ends up in the root of the Notes client. If you do not do this and you specify a widget catalog in the preferences the Notes client wont apply updates to the widgets when new versions are available. This is a bug at least in Notes 8.5 GOLD.

Resources:

The technique for building a better Notes Java API

This is a followup post to yesterdays post titled Want to join me in building a better Notes Java API? and here I’ll show just how easy it was to build the wrapper API.

Below is the code from the implementation of the getView(String) method of the lotus.domino.Database interface. As you can see the central element is to get the current thread the method is called on and the thread used for Notes data access. If we’re not on the Notes thread execute a blocking request and return the result. If we’re on the Notes thread simply go ahead and do the operation. Simple right?

The most difficult part of all this was that I had to write my own Notes thread handler (equivalent of NotesPlatform) as there isn’t a method for doing a blocking request on the Notes thread in NotesPlatform class supplied by Lotus.

public View getView(final String name) throws NotesException {
  // get threads
  Thread curThread = Thread.currentThread();
  Thread notesThread = NotesPlatform.getInstance().getThread();

  // decide if we're in the Notes thread or not
  if (curThread != notesThread) {
    // we're not on the Notes thread so wrap
    final Holder h = new Holder();

    NotesPlatform.getInstance().syncExec(new Runnable() {
      public void run() {
        try {
          h.value = DatabaseWrapper.this.db.getView(name);

        } catch (NotesException e) {
          h.throwable = e;
        }
      }
    });

    if (null != h.throwable) {
      throw (NotesException)h.throwable;
    } else {
      return new ViewWrapper((View)h.value);
    }

  } else {
    // we're on the thread so do request
    return new ViewWrapper(DatabaseWrapper.this.db.getView(name));
  }
}

TwitNotes 1.0.9 available and the book is now closed on v. 1.0.x :-)

So I’ve fixed the final small issues I really wanted to get fixed before focusing on the next release of TwitNotes in version 1.0.9. This release is primarily a bug fix that fixes the following:

  • Make sure the date/time of the post is represented in search results
  • Make sure the source application of the post is represented in search results
  • Make sure the Twitter tab is always the first tab and search is the second
  • Make sure TwitNotes is working perfectly on Ubuntu
  • Fix the version number in the about dialog

I’ve created a widget descriptor for TwitNotes v. 1.0.9 as well. To update or install simply drag the widget descriptor to the MyWidgets sidebar.

I know there are (small) things that could be done differently but all future work will be done on version 1.1 which has some new exciting features I think… ๐Ÿ™‚

Want to join me in building a better Notes Java API?

One of the things that are the hardest for Notes Java developers transitioning to developing plug-ins for Notes 8 is handling threading. All access to the Notes backend classes must occur on the Notes thread using NotesJob or a thread statically initialized using NotesThread.sinitThread. This is cumbersome and prone to runtime exceptions making the development process slow and agonizing. Also most interaction is started from the UI thread making the need for handling the Notes thread all too common.

A far better approach, IMHO, would be to not require the programmer to handle the threading all together as there are solutions for this readily available. The solution isn’t hard to do.

In an effort to prove this point I sat down for an hour or so at Lotusphere (I know I’m behind in blogging this) and cooked up a wrapper API that wraps the Notes API and provides access to the Notes backend classes without the need to worry about threading. The Notes API is made up of interfaces which makes it even easier.

The whole concept with the wrapper is that the user can write code like this in an event handler

public void widgetSelected(SelectionEvent event) {
  try {
    // get value
    Session session = NotesPlatform.getInstance().getSession();
    Database db = session.getDatabase(null, "names.nsf");
    View v = db.getView("($People)");
    ViewEntryCollection vec = v.getAllEntries();

    // set value in label
    lblCount.setText("Found " + vec.getCount() + " contacts...");

    // return from event
    return;

  } catch (Exception e) {
    StringWriter sw = new StringWriter();
    e.printStackTrace(new PrintWriter(sw));
    txtException.setText(sw.toString());
  }
}

instead of doing stuff like this which includes two extra jobs and having to make sure that no Notes API access is done from the UI thread:

public void widgetSelected(SelectionEvent event) {
  // kick of Notes job to get data
  new NotesJob("Some job") {
    public IStatus runInNotesThread(ProgressMonitor m)
                               throws NotesException {
      // get value
      Session session = NotesPlatform.getInstance().getSession();
      Database db = session.getDatabase(null, "names.nsf");
      View v = db.getView("($People)");
      ViewEntryCollection vec = v.getAllEntries();

      // get count into final variable
      final int count = vec.getCount();

      // kick of new UI job to update UI
      new UIJob("Update UI") {
        public IStatus runInUIThread(IProgressMonitor monitor) {
          // set value in label
          lblCount.setText("Found " + count + " contacts...");
          return Status.OK_STATUS;
         }
      }.schedule();

      // return
      return Status.OK_STATUS;
    }
  }.schedule();

  // return
  return;
}

Besides being shorter code-wise the former code is also much easier to read and understand. The performance of the former is somewhat slower than the latter (“native” API) due to context switching but the fact that I could do this is 60 minutes proves that something can and should be done to make plug-in development easier. Imagine what could be done in more time. Tweaking for performance should be possible and easy enough. Also using this wrapper API could be a choice the developer makes – ease of use over performance… It could be a call I as a developer was willing to make.

This could actually be a good idea for a project on OpenNTF. If anyone is interested to join up on the project let me know – I’ll be interested in joining forces with someone.

Tomorrow I’ll blog about how this is done and just how easy it is.

TwitNotes – v. 1.0.7 is out

Just uploaded TwitNotes v. 1.0.7 to the update site. It’s just a small bug fix release that fixes some minor things:

  • Easier searching by responding to pressing the Enter key on the Search tab
  • Make sure all profile images are scaled to 48x48px to handle too large images (looking at you @marybethraven)
  • Attempt to fix wordwrap issue on Ubuntu – still working on that

Thanks to Brian Leonard from IBM for providing a widget descriptor to make installation a lot easier. Simply drag the link to your MyWidgets sidebar plug-in to install.

Developing plug-ins for Notes 8.0.x, Notes 8.5, Sametime 8.0.x and Sametime 7.5.x

I received an e-mail from Dirk Jebing on my blog post on deploying TwitNotes in Sametime and how I was having deployment problems due to an exception being thrown. This is a long time ago but Dirk now found the solution which actually turned out to be a close cousin to my Cross compiling sidebar plugins for Notes 8.0.x and Notes 8.5 post.


Hi Mikkel,

at least for my plugin I could solve this! The two steps I did (perhaps it may help you):
1) I realized that I build my plugin with sametime 8.01 SDK. So I changed that (that did not help at all)
2) In the sametime logs my eye fell on an UnsupportedClassVersionError. So I changed the compiler compliance level (which stood on 5.0) to 1.4, as it has been with Sametime SDK 7.5.1. And now it works!

Cya, Dirk

So the lesson is to always watch for the JDK level of the client you’re developing for…