http://aws.amazon.com/eclipse/

Now there is an Eclipse plug-in for interacting with Amazon EC2 services – very cool.

“We want to make the process of building, testing, and deploying applications on Amazon EC2 as simple and efficient as possible. Modern web applications typically run in clustered environments comprised of one or more servers. Unfortunately, setting up a cluster can involve locating, connecting, configuring and maintaining a significant amount of hardware. Once this has been done, keeping the operating system, middleware, and application code current and consistent across each server can add inefficiency and tedium to the development process. In recent years, Amazon Web Services has helped to ease much of this burden, trivializing the process of acquiring, customizing, and running server instances on demand.”

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)

If you’re wondering why your widget catalog deployment doesn’t work…

…then make sure your widget catalog is in the root of the server. This will be fixed in Notes 8.5.1 and a SPR has been generated (SPR #DMDD7Q4MWT) for Notes 8.5 FP1 so open an PMR and vote for it if this is important enough for you. For the record the way that this works is by the Notes client having a replication event listener for the widget catalog database.

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…