Show ‘n Tell Thursday: Maximizing tabs in DDE (20 October 2011)


It has been a looooooooooooooooong time since I did a SnTT but I found it fitting for this week. The tip is short and very straight forward but will make it easier and more productive for you to work in Domino Designer on Eclipse (DDE).

If you are like me like the navigator in DDE is on the left, and the outline/controls/data views are on the right. You realize that you do not have much space left for code in the center editor. Bummer! 😦 To help remedy that you may either minimize or close the views on the right but that really isn’t ideal as it takes time and some times you need the views e.g. for XPages work. As an alternative you could figure out which views you use for what tasks and create custom perspectives in DDE for those tasks which isn’t for the Eclipse-superuser. You could also choose the easy solution – simply maximize the editor.

Maximizing the editor is easy. You simply double-click the tab or press Ctrl-M to make the editor go fullscreen. When done you simply double-click the tab again or press Ctrl-M to return it to being “in the middle”. Easy and quick.

Hope it works as nicely for you as it does for me.

Show ‘n Tell Thursday: Configuring Ubuntu for Notes 8 plugin development (2 April 2009)


This weeks SnTT post is about configuring Eclipse on Ubuntu 8.0.4 for Notes plug-in development. I use Notes 8.5 but it should work equally well for Notes 8.0.x clients. Wan’t to develop plug-ins? Well read on and do it on Ubuntu. Notes 8.x runs freakishly fast on Ubuntu. Read on…

Actually this is a cheat post as the steps are almost the same as for doing it on Windows. Most of the stuff has to do with platform differences. My post for doing it on Windows is here. I have updated this guide with steps for Linux. Enjoy!!

Show ‘n Tell Thursday: SWT drag’n’drop in Notes 8.0.x and Notes 8.5 (19 February 2009)


This weeks SnTT post is about adding drag’n’drop of Lotus Sametime buddies in the Notes 8.0.x Standard and Notes 8.5 Standard client in SWT plug-ins. Unfortunately the Sametime API for dragging buddies around changed between Sametime 8.0.0 and Sametime 8.0.1 so you have to take this into account when developing drag’n’drop functionality that works across Notes 8.0.x and Notes 8.5. Read on…

As mentioned in my Drag’n’drop in SWT components post drag’n’drop uses a socalled Transfer classes to signal which types of data a drag source delivers and a drop target accepts. To allow Sametime buddies to dropped on your component you use PersonGroupTransfer class but this class changed package from Sametime 8.0.0 to Sametime 8.0.1… 😦

In Sametime 8.0.0 (Notes 8.0.x) the class is com.ibm.collaboration.realtime.people.PersonGroupTransfer and in Sametime 8.0.1 (Notes 8.5) the class is com.ibm.collaboration.realtime.people.PersonGroupTransfer (do not mind that the Sametime 8.0.0 class is in an “internal” package as it is exported from the plug-in). This means that if you develop a plug-in that needs to run on both Notes 8.0.x and Notes 8.5 you need to factor the drag’n’drop support out into two separate plug-ins and match based on perfect version numbers of the com.ibm.rcp.collaboration.realtime.people.impl plug-in.

It’s a bit cumbersome but it works fine.

Show ‘n Tell Thursday: Easy access to Lotus Connections Profiles translation files (21 August 2008)


This weeks SnTT post is about Lotus Connections and how to more easily get access to and change the translation files for the UI of the Profiles feature.

Configuring which pieces of information are surfaced in the Profiles feature is pretty easy and well documented using the profiles-config.xml file. Changing the label text however is harder and not that easy to do. As it is documented it involves stopping profiles, locating a jar-file, extracting it using WinZip, changing a properties file, repackaging the jar-file, redeploying the jar-file and finally restarting profiles to see the change. This is well and good and acceptable if you only need to change the file once, but chances are that it’s an iterative process and you need to do it multiple times. Wouldn’t it be easier to simply stop profiles, change the file and restart profiles? Well read on to see how.

The labels for the fields (and all the other pieces of text for that matter) in Profiles are stored in property files in a jar-file in the Profiles application. Changing the property files for the appropriate language causes the text to change in the UI after a restart of the Profiles application. This is easy enough but require a lot of repeated steps every time since you have to unpack the jar-file, change the property file and repack the jar-file.

Since Profiles is just another Java web application we can move some of the classes and property files out of the jar-file (in the “lib”-directory) and into the “WEB-INF/classes”-directory. This means that we only have to repack the jar-file once and for all since the property files are now available from the “classes”-directory.

On your Websphere Application Server where the Profiles feature is installed (with Profiles stopped) do the following using a file explorer:

  1. Open the profile directory for the profile you’re using
  2. Open the installedApps directory and the node directory underneath it (chances are that there’s only one node directory)
  3. Open the Profiles.ear directory
  4. Open the peoplepages.war directory
  5. Open the WEB-INF directory
  6. Create a new directory called “classes”, and inside this directory create a com/ibm/peoplepages/webui directory (a total of 4 directories)
  7. Open the lib directory and locate the peoplepages.web.jar file and make a backup copy of this file
  8. Now unzip the jar-file (maybe renaming it to a zip-file first), navigate through the directories to com/ibm/peoplepages/webui and move the resources folder to the “classes/com/ibm/peoplepages/webui”-directory you created above
  9. Navigate back to the extracted jar-file and zip the “com” and “META-INF” directories back up into peoplepages.web.jar and overwrite the peoplepages.web.jar file you located in step 7

Now you should have replaced the original peoplepages.web.jar file with a new one and have a directory containing the resource files.

Now when ever you need to change a label for a field simply locate the label or text you would like to change in the property files underneath WEB-INF/classes/com/ibm/peoplepages/webui/resources and restart Profiles.

Please note that the above probably isn’t supported by IBM… 🙂

Show ‘n Tell Thursday: Cross compiling sidebar plugins for Notes 8.0.x and Notes 8.5 (7 August 2008)


I haven’t done a SnTT in months (actually the last one was back on 24 May 2007) so I guess it’s about time. This week it’s about cross compiling sidebar plugins for Notes 8.5 and Notes 8.0.2. Enjoy…

Since installing Notes 8.5 I have had a lot of trouble developing in Eclipse 3.4 for Notes 8.5 and having the plugins work in Notes 8.0.x as well. The problem showed itself as a NullPointerException when trying to load the plugin Activator and a “Viewpart is null” message in the Notes UI. Looking at the log trace showed a class incompatibility message (“bad major version at offset=6”).

So far I have been screaming my lungs out, developing in Eclipse 3.4 and building the plugins in a virtual machine with Eclipse 3.2 as I couldn’t get plugins to work otherwise. Now I finally found a solution that lets me develop in Eclipse 3.4 and having the plugins work in Notes 8.0.x and Notes 8.5.

The issue is that Eclipse 3.4 configured with Notes 8.5 as a target platform is using Java 6 and that Notes 8.0.x is using Java 5 which causes class format problems. The solution is to set the required execution environment in Eclipse 3.4 which will cause Eclipse to build correctly. Setting the required execution environment (J2SE-1.5) is done in the “Overview”-tab of the MANIFEST.MF editor as shown below.

Using the GUI is of cause just a shorthand for editing the manifest manually. As an alternative you can edit your META-INF/MANIFEST.MF file directly and add the following line:

Bundle-RequiredExecutionEnvironment: J2SE-1.5

Please note that this is not the default value when creating new plugins in Eclipse 3.4 so you’ll have to pay attention and make sure it’s set correctly. This is of cause only necessary if your plugins need to work on Notes 8.0.x as well as Notes 8.5.

Thanks to Pierre Carlson from IBM for pointers on this.

Show ‘n Tell Thursday: Showing a progress bar / joining threads (24 May 2007)


A fellow developer in the developerWorks forum had an issue where he wanted to load a lot of data and needed a progress bar to indicate progress. His problem was that the main thread terminated before his data loading was done and he needed help.

The solution is to use a data loading thread and Thread.join () the thread to wait for it to complete to avoid the main thread from terminating the agent. If you do not join the thread the main thread will terminate and abort the loading. The joining is bolded in the below code.

To test it out try running the below code with and without the l.join() line below commented out and see how the progress bar never reaches the end when the thread isn’t joined.

Also note that I’m extending NotesThread to avoid dealing with threads etc. in Notes and that the code is no where near production quality!

import lotus.domino.*;
import javax.swing.JDialog;
import javax.swing.JProgressBar;

public class JavaAgent extends AgentBase {
   private static int COUNT = 30;

   public void NotesMain() {

      try {
         // initialize
         Session session = this.getSession();
         AgentContext ac = session.getAgentContext();

         // start thread to similate loading
         Loader l = new Loader();
         l.start();
         for (int i=0; i<COUNT; i++) {
            System.out.println("i=" + i + " (" + session.getUserName() + ")");
            Thread.sleep(100);
         }

         // wait for progress thread
         l.join();

      } catch(Exception e) {
         e.printStackTrace();
      }
   }

   public static class ProgressBar {
      private JDialog dialog = null;
      private JProgressBar bar = null;

      public ProgressBar() {
         dialog = new JDialog();
         bar = new JProgressBar(0, COUNT);
         dialog.getContentPane().add(bar);
         dialog.setSize(250, 40);
      }
      public void visible(boolean flag) {
         dialog.setVisible(flag);
      }
      public void update(int i) {
         this.bar.setValue(i);
         this.bar.updateUI();
      }
      public void dispose() {
         if (this.dialog.isVisible()) {
            this.visible(false);
         }
         this.dialog.dispose();
      }
   }

   public static class Loader extends NotesThread {
      private Session session = null;
      private Database db = null;
      private View view = null;

      public Loader() throws NotesException {
         session = NotesFactory.createSession();
         db = session.getDatabase(null, "names.nsf");
         view = db.getView("People");
      }

      public void runNotes() {
         try {
            ProgressBar b = new ProgressBar();
            b.visible(true);

            for (int i=1; i<=COUNT; i++) {
               Document doc = this.view.getNthDocument(i);
               if (null != doc) {
                  System.out.println("Loaded person: " +
                     doc.getItemValueString("Firstname") +
                     " " + doc.getItemValueString("Lastname"));
               }
               b.update(i);
               Thread.sleep(500);
            }
            b.dispose();

         } catch (Exception e) {
            e.printStackTrace();
         }
      }

   }
}

Show ‘n Tell Thursday: The missing link for plugging Notes into you Sametime 7.5 plugin (10 January 2007)


When you develop and run plugins for Sametime 7.5 on Windows or Linux you do not use a standard Java Development Kit (JDK) and standard 1.4.2 JVM. Instead you use a slightly modified version called the JCL Desktop JDK and the J9 JVM. The “slightly modified” means that some features have been removed from the JDK to make it “safe” for the Expeditor framework that Sametime 7.5 runs on.

An unfortunate side-effect of this decision is that you cannot use the Notes/Domino API (that is notes.jar or ncso.jar) without resorting to additional libraries. The reason is that the ever present lotus.domino.NotesException inherits from org.omg.CORBA.UserException which is an exception class that has been removed in the modified runtime class library (for more information about lotus.domino.NotesException see my post called Java in Notes/Domino Explained: NotesException).

Fortunately there is a way to remedy that. The solution is to include the ibmorbapi.jar library (can be found in c:Program FilesNotes7Datadominojava on my laptop) in your plugin alongside notes.jar or ncso.jar. The ibmorbapi.jar library is quite large (around 400kb) but I haven’t yet played around with it to see if you could simply get away with including the org.omg-packages.

Now you know why your plugin fails to compile due to indirectly referenced Corba classes.

Anyways – someone who has the ears of the Sametime development team might want to mention this to them. Apart from that – great product and its a joy to develop plugins for Sametime 7.5! 🙂

Show ‘n Tell Thursday: Removing the slash screen from Sametime 7.5 (5 October 2006)


Since Sametime 7.5 is built upon the Eclipse Rich Client Platform (RCP) you can hack it as such. In Eclipse RCP programs the slash screen is a configurable component which led me to believe it could be removed. And I was right. The below guidelines are for Windows but should be applicable to other platforms as well.

To not display the slash screen at startup do as follows:

  • Open your Windows Explorer and navigate to your Sametime 7.5 installation directory (C:Program FilesIBMSametime 7.5)
  • Open the “configuration” directory
  • Open the config.ini file in your favorite editor
  • Remove the second line of the file (the one starting with “osgi.splashPath”) or comment it out by inserting a #-character at the start of the line
  • Save and close the file

When restarting Sametime the slash screen should be gone.

Happy days! Please note that this approach probably isn’t supported but hey – shouldn’t it be a configurable option in the first place? 😉

Show ‘n Tell Thursday: Don’t rely on the default font-size (28 Sept 2006)


You should be aware of relying on the default font size of the Lotus Notes client when doing richtext programming via LotusScript. I found this out then doing an application that does the following:

  1. Grabs a document with a richtext item.
  2. Makes a copy of the backend document to do a reply-with-history style function.
  3. Remove some items in the backend and bring the document to the UI.
  4. Move focus to the richtext item and add a text like “User did function xyz at 07:41PM on 28 Sept 2006” using the InsertText method.

The problem here is that if the user just wrote an e-mail using the normal e-mail functionality where he ended the e-mail using a larger font, the text you add via LotusScript will be added using this larger font-size.

So when doing richtext programming be sure to always set the font-size or take some counter measure to avoid this behaviour.

Show ‘n Tell Thursday: Do you weigh in at Flyweight? (24 August 2006)


When working with a large number of (simple, similar) objects at once the amount of memory taken up by the objects can be considerable. Consider representing datapoints for a data series for a graph in objects. You might need to hold 2000 datapoints where many might be the same. Instead of wasting memory on a lot of identical objects you can use the Flyweight pattern.

In brief the pattern describes how to converve memory when working with a large number of objects by using a factory to construct objects rather than using the new keyword. By using the factory class you can do some checks before constructing a new object i.e. whether an existing object with the same properties already exists in a pool of already constructed objects. The example normally given, an the example used on Wikipedia, is that of representing a sentence where each letter is represented by an object. Using the Flyweight pattern a sentence will never use more than the 25 letter-objects (when talking ASCII) since there are no more than 25 unique letters. No need to represent each letter in the sentence as unique objects.

The sentence/letter example readily carries over to the graph example mentioned earlier.

Example

Let’s look at a simplified letter/sentence example in more detail. First the Letter class:

package com.lekkimworld.flyweight;

import java.util.HashMap;
import java.util.Map;

public class Letter {
   private static Map letters = new HashMap();
   private static int letter_count = 0;
   private char letter = 0;

   {
      // increment counter
      letter_count++;
   }

   public static Letter getInstance(char c) {
      Character c_obj = new Character(c);
      if (letters.containsKey(c_obj)) {
         // reuse existing object
         return (Letter)letters.get(c_obj);
      } else {
         // create new object
         Letter l = new Letter(c);
         letters.put(c_obj, l);
         return l;
      }
   }

   public static int getLetterCount() {
      return letter_count;
   }

   private Letter(char c) {
      this.letter = c;
   }

   public char getLetter() {
      return this.letter;
   }
}

…and then the Sentence class:

package com.lekkimworld.flyweight;

import java.util.LinkedList;
import java.util.List;

public class Sentence {
   private List letters = new LinkedList();

   public Sentence(String s) {
      for (int i=0; i<s.length(); i++) {
         letters.add(Letter.getInstance(s.charAt(i)));
      }
      System.out.println("Constructed sentence - used " + Letter.getLetterCount() +
            " instead of " + s.length() + " objects.");
   }

   public static void main(String[] args) {
      new Sentence("In the flyweight pattern, the data has no pointers " +
      	"to the data type methods, because these would consume too much space. " +
      	"Instead, the subroutines are called directly. In some cases, flyweight " +
      	"inheritance is performed by "shift-in" and "shift-out" data markers " +
      	"as a higher-level operation cycles through an array of flyweight data.");
   }

}

The output of running the example is as follows:

Constructed sentence - used 28 instead of 330 objects.

Here we saved creating 302 objects – imagine if we have been dealing with a long sentence how many object creations we could have spared the JVM and how much memory we saved. The central points are in bold in the Letter class and is the static getInstance (factory) method to create new objects, the private constructor and the Map to hold already created objects.

Conclusion

The Flyweight is a pattern that can save a lot of memory when you start representing everything as objects and the scenarios where it can be used are plentiful. I know the example is a bit simplistic but it demonstrates the point of the Flyweight pattern just fine. Don’t blame the pattern for the lack implementation in the example – blame me… 🙂

Will you weigh in at Flyweight the next time you need to handle many objects?

Further reading

While ideally suited for Java development due to the classes need to implement the pattern (static variables, a Map and normally a list of some kind) it should be possible in LotusScript – maybe using the collection classes from Johan. If you are interested the design patterns I highly suggest the Design Patterns book by GoF (Gang of Four).