Java in Notes/Domino Explained: The difference between a class, an abstract class and an interface


Normal, or concrete, classes in Java can be instantiated using the new keyword. Concrete classes both define the functionality, that is what the class does, and the interface, that is what methods are available for you to call. Most of the classes you write will be concrete classes like the one below.

public class MyConcreteClass {
   public void perform() {
      ...
   }
}

At the other end of the spectrum we have an interface which only defines which methods we can call on it – there is no functionality in there. The interface in the example below specifies that a class implementing the interface will at least have the 4 listed methods. Notice that there is no method bodies (the compiler will enforce this).

public interface Car {
   public void increaseSpeed();
   public void decreaseSpeed();
   public void turnRight();
   public void turnLeft();
}

By creating a class and inserting the keyword “abstract” after the class visibility modifier (public, private, “friendly”) makes the class into an abstract class. An abstract class is somewhere in between an interface and a class, that is a class where some of the functionality is specified but not all. Think of an abstract class as a class with some blanks that needs to be filled in by any, non-abstract, class that extends it. An abstract class cannot be instantiated using the new keyword.

public abstract class MyAbstractClass {
   public class perform() {
      this.doStuff();
   }
   public abstract void doStuff();
}

How do I use an interface?

To use an interface you have your class implement it. Implementing an interface means making sure that the class specifies method bodies for all the methods in the interface. If you do not implement all the methods in the interface the compiler will make you mark the class as abstract.

public class Ford implements Car {
   public void increaseSpeed() {
      ...
   }
   public void decreaseSpeed() {
      ...
   }
   public void turnRight() {
      ...
   }
   public void turnLeft() {
      ...
   }
}

How do I use an abstract class?

An abstact class cannot be instantiated because some of the functionality (for example the doStuff() method in the example above) isn’t implemented. To use the class we need to extend it and implement any missing, abstract, methods.

public class MyClass extends MyAbstractClass {
   public void doStuff() {
      ...
   }
}

So when should I use which?

Well the real answer is it depends…

An abstract class is a good choice when you do most of the programming in the abstract class and leave only one or a couple of methods to sub-classes. An example could be a class that reads data from a file. The abstract class defines the actual reading and processing of the file and concrete sub-classes define how to get the file (from the local disk, via HTTP, via FTP etc.):

public abstract class FileProcessor {
   // declarations
   private File file = null;

   public process() {
      // get file
      this.file = this.getFile();

      // open file
      this.openFile();

      // decrypt file
      this.decryptFile();

      // do other stuff with the file
      ...
      ...
   }
   private void openFile() {
      ...
   }
   private void decryptFile() {
      ...
   }
   private abstract File getFile() throws Exception;
}

public class HttpFileProcessor extends FileProcessor {
   private abstract File getFile() throws Exception {
      // get file via HTTP and return it
      ...
   }
}

public class FtpFileProcessor extends FileProcessor {
   private abstract File getFile() throws Exception {
      // get file via FTP and return it
      ...
   }
}

An interface is really nice when all you need to do it define what methods are available but you want to leave the entire implementation up to the implementer. The interface in the example below only describes that a class implementing the interface knows how to process a Document object. You don’t care how the class does it but you know that you can call the process() method supplying the Document that should be processed.

public interface DocumentProcessor {
   public void process(Document doc) throws Exception;
}

Another really neat thing about interfaces is that a class may implement multiple interfaces whereas it can only extend a single class. This means you can use an interface simply to signal something (for an example of this look at the java.lang.Cloneable interface in the JDK).

public class MyCar implements Car, Cloneable, Serializable {
   ...
}

Re: Helping out a fellow blogger getting the actual bytes of an image resource – a lesson in the intricacies of DXL representation

And there you have it… Ben Langhinrichs of Genii Software, CoexEdit and the Midas RichText LSX fame has posted a comment that explains my findings about the structure of an image resource in DXL.

Thanks Ben.

Joel on Software: The Development Abstraction Layer

As always the posts by Joel Spolsky are insightful, funny and with an edge that makes you keep reading. The newest post (The Development Abstraction Layer) is about why programmers can’t run a business by themselves, but what it takes to make them think they can.

“Management’s primary responsibility to create the illusion that a software company can be run by writing code, because that’s what programmers do. And while it would be great to have programmers who are also great at sales, graphic design, system administration, and cooking, it’s unrealistic. Like teaching a pig to sing, it wastes your time and it annoys the pig.”

As a (self-employed) programmer I can only say: “sad but true…” ๐Ÿ™‚

Re: Re: How are roaming id-files encrypted?

Dear Mr Heisterberg,

Our development team have released the following information about the encryption method of the ID file.
This is the Text which they sent back to me:

“Double encryption is chosen to securely deliver an ID file to the roaming user. It is a client – server interaction, where the Password the client enters is not necessarily the Password it is used to undisclosed the ID file.

This action can only be fulfilled together with the server. For basic concepts please see “Bellovin-Merritt Encrypted Key Exchange protocol”. It is implemented differently but this will give you an Idea what is going on. Diffi Hellman was choose as an encryption algorithm itself.”

I have also to advise you. The only supported configuration for Roaming Users it to upgrade the users via the information in the Administration help guide.
If a problem arose with Roaming Users where the config used was not done as per Admin help ,we would be unable to provide assistance.

Kind Regards,
Xxxxxx Yyyyyyy
Software Engineer – Lotus EMEA Support –

Apart from the fact that the references to the algorithms in the response are erroneous I guess I have to accept the answer. Just for the record – Diffie-Hellman is not an encryption algorithm but an algorithm to securely establish a session key across an unsecure network.

However after another round of clarifying questions with Lotus Support it is clear that any attempt to automate the process of pre-creating the roaming user databases on the server will be totally unsupported by Lotus. The only way is to manually mark users for roaming which leaves some room for improvement I’m afraid though I understand Lotus’ position.

I guess it’s back to the drawing board now to find a way to automate the migration process to roaming as much as possible and find a way to make it as easy for existing users as possible. During my research I did find the a method in the Notes C API (SECAttachIdFileToDB()) that might be of interest to some – the customer I am researching this for will probably not go so far as to do C API development.

To end on a positive note. Enabling roaming for new users isn’t an issue since it’s simply a matter of checking a box in the registration dialog. That’s easy! ๐Ÿ™‚

Further reading:

Possibility to complain about a blog post – interesting twist in “corporate blogging”

The BBC recently launched a consolidated blog effort across the BCC aptly named The BBC Blog Network. While this is interesting in the whole “corporate blogging” discussion I noticed an even more interesting thing while perusing the FAQ. On the BBC Blog Network you have the possibility to complain about a specific comment thus the BBC encourage the readers to help them keep the comments sane, to the point and make sure that the comments follow the house rules.

I think it is an interesting way to keep the discussion flowing freely and to allow different discussions to evolve and thrive. Comments to some blogs might use different language (stronger, profanity etc.) which might be offensive to some but acceptable within certain areas. I think the complain functionality has the possibility of allowing this while protecting users of more general blogs from being offended.

Java in Notes/Domino Explained: Java Collection API for LotusScript programmers


The Java Collection API was introduced in Java 1.2 and is a really nice API for handling dynamic arrays, sets, lists etc. The classes for the Collection API can be found in the java.util package. There is no built-in equivalent to the Collection API in LotusScript.

When coming from to Java from LotusScript the Collection API may be a little overwhelming to get cracking on. To kind of ease into it lets look at how to use the basic parts of the API for do kind of the same stuff in Java as you do in LotusScript.

Note: All the collection classes of the Collection API return references of type java.lang.Object which means that references oftentimes needs to be cast back to the desired type.

Dynamic arrays

In LotusScript you can use the Redim and Redim Preserve keywords to change the dimensions of an array at runtime. This isn’t possible in Java. Instead you can use an ArrayList which is an array-like structure that automatically resizes. If you are coming from Java in Notes/Domino 5.x the ArrayList is like a Vector only a little faster.

LotusScript
Dim my_array() As String
Dim i as Integer
For i=0 To 10
   Redim Preserve my_array(i)
   my_array(i) = "Index: " & i
Next

Java
import java.util.*;

ArrayList l = new ArrayList();
for (int i=0; i<11; i++) {
   l.add("Index: " + i);
}

As you can see there is no need to resize the ArrayList in the for-loop.

Lists

LotusScript has the concept of a List which is a key/value datastructure. In Java this kind of collection is called a Map and the most used type is the HashMap. For people coming from Java in Notes/Domino 5.x a HashMap is basically the same as a Hashtable only a wee bit faster.

LotusScript
Dim my_list List As String
my_list("one") = "1"
my_list("two") = "2"

Java
import java.util.*;

HashMap my_map = new HashMap();
my_map.put("one", "1");
my_map.put("two", "2");

Looping an array

All classes of the Collection API implementing the List/Set interface has an iterator() method that returns an Iterator object you can use to loop the collection.

LotusScript
Dim some_array(10) As String
Dim i As Integer
For i=0 To UBound(some_array)
   Print some_array(i)
Next

Java
import java.util.*;

ArrayList l = new ArrayList();
Iterator ite = l.iterator();
while (ite.hasNext()) {
   System.out.println(ite.next());
}
...or the slightly more condensed version I prefer...
ArrayList l = new ArrayList();
for (Iterator ite = l.iterator(); ite.hasNext(); ) {
   System.out.println(ite.next());
}

Looping a List

All classes of the Collection API implementing the Map interface has an keySet() method that returns a Set containing the keys used in the Map. From that Set you use the iterator() method to obtain an Iterator for looping.

LotusScript
Dim my_list List As String
my_list("one") = "1"
my_list("two") = "2"
Forall v In my_list
   Print Listtag(v) + " = " + v
End Forall

Java
import java.util.*;

HashMap my_map = new HashMap();
for (Iterator ite=my_map.keySet().iterator(); ite.hasNext(); ) {
   Object key = ite.next();
   System.out.println(key + " = " + my_map.get(key));
}

As you can see in the Java example the caveat here is to use the my_map.keySet() method to get a Set containing the keys in the Map. From the Set we can get an Iterator that we use to loop the keys of the Map.

Java in Notes/Domino Explained: Handling arrays


Probably the biggest source of fustration for LotusScript programmers moving to Java is the fact that arrays cannot be resized in Java once they have been declared. Where in LotusScript we have the Redim keyword there is no equivalent for Java when talking arrays. If you need resizable arrays you should look into the Java Collection API (see the upcoming post “Java Collection API for LotusScript programmers” for more information on the Collection API).

Note: All references to arrays in Java are objects – also references to arrays of the privitive data types (int, long, char etc.).

As mentioned arrays dimensions are fixed in Java once declared and arrays always start at index 0. Notice how the bound has to be one higher than the number of places you need in the array. To declare a simple array with room for 5 Strings you write:

String[] my_strings = new String[5];
my_strings[0] = "abc";
my_strings[1] = "def";
my_strings[2] = "ghi";
my_strings[3] = "jkl";
my_strings[4] = "mno";

Alternatively you may also separate the declaration of the reference from the actual memory allocation.

String[] my_other_strings = null;
my_other_strings = new String[2];
my_other_strings[0] = "abc";
my_other_strings[1] = "def";

A cool thing with Java arrays is that you can use a more condensed syntax and fill the array as you declare it. It is a great way to avoid manually having to specify the dimensions of the array. The below code produces the same array as above (notice the use of curly braces).

String[] my_strings = {"abc", "def", "ghi", "jkl", "mno"};

This doesn’t just work for Strings but can be equally applied to other types of objects:

Object[] my_objects = {"abc", new java.util.Date(), new java.lang.Object()};

The reference to an array is kind of special in Java since it has a special member variable called length to help in looping the array. The basic construct for looping an array in Java is a for-loop just like in LotusScript. In the Java versions employed by Notes/Domino 7 and below there is no forall type loop.

String[] my_strings = {"abc", "def", "ghi", "jkl", "mno"};
for (int i=0; i<my_strings.length; i++) {
   System.out.println("Index " + i + ": " + my_strings[i]);
}

When working with arrays you really should be using the length member variable when looping arrays. If not you’ll most likely at some point run into the java.lang.ArrayIndexOutOfBoundsException which is an unchecked exception.

Java in Notes/Domino Explained: The story on recycle()


As with everything what you see is typically only the tip of the iceberg. This is also true for the Java objects for Notes/Domino since they are only thin wrappers around the underlying, more heavyweight, C++ objects. Since the Java garbage collector has no knowledge of this, all classes in the Notes/Domino API inherit a method called recycle() from the lotus.domino.Base class. The purpose of this method is to explictly tell the C++ object to free any memory it is using. A part from freeing its own memory, the object will also call recycle() on any object that it created. This means that calling recycle() on a database object will also recycle() a view object obtained opened through it.

If you do not realize that calling recycle() will cascade down through the object hierarchy like this you’re going to experience some “interesting” exceptions and unexpected behaviour at runtime.

It is important to note that the only reason for calling recycle() is to release memory while the agent (or other Java program) is running.

If your agent only does a small piece of work it’s probably not worth the effort of calling recycle() since people normally get into a lot more trouble calling recycle() than what they actually accomplish. My recommendation is to recycle document objects when you loop a document collection or view and otherwise not spend time thinking of recycle() unless you start experiencing java.lang.OutOfMemoryError errors.

To recycle() documents while looping a document collection or view you can use a loop-construct like the one below:

DocumentCollection dc = agentContext.getUnprocessedDocuments();
Document doc = dc.getFirstDocument();
Document docTemp = null;
while (null != doc) {
   // do stuff with the document

   // get next document into docTemp
   docTemp = dc.getNextDocument(doc);

   // recycle doc
   doc.recycle();

   // transfer reference to keep loop going
   doc = docTemp;
}

Update: As mentioned on this comment recycling is more important in servlets than in agents. When I post on servlets I’ll give some more pointers.

Java in Notes/Domino Explained: Stack, heap and references


Memory-wise a program running on a computer uses two discrete pieces of memory – the stack and the heap. The stack is a small(er) piece of memory specific to the method being executed. The heap is much larger and may be shared between programs. No need to worry about the implementation details more than this.

When you instantiate an object in Java you are actually allocating two pieces of memory – one on the stack and one on the heap. The memory of the stack is used to store a reference and the memory on the heap is used to store the actual object. The primitive datatypes (int, long, char etc.) are only stored on the stack.

Have you ever been debugging a Java agent using System.out.println and seen something like “java.lang.Object@bbcab38” show up in the Java debug console? What you are seeing is actually the memory address of the object and not the object itself. This happens because there is no toString() method in the object so the JVM prints out the memory address since that’s the last resort to show something unique about the object.

The below figure shows that’s on the stack and the what’s on the heap from the perspective of the simple agent shown below running in Notes/Domino. Notice how the declared int only exists on the stack.

import lotus.domino.*;

public class JavaAgent extends AgentBase {
   public void NotesMain() {
      try {
         Session session = getSession();
         AgentContext agentContext = session.getAgentContext();
         int count=20;

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

Of cause the above picture isn’t totally accurate since it doesn’t show all the objects created and references held by the objects on the heap but you get the picture. The lotus.domino.Database pointed to by the lotus.domino.AgentContext object is the current database, that is agentContext.getCurrentDatabase().

By reference vs. by value

In Java you only have direct access to what’s on the stack which means that what you manipulate in your agents are the references (i.e. on the stack) and not the objects themselves. This means that you in Java always program by reference and not by value. In fact there is no equivalent of the ByVal keyword in LotusScript. If you need to work on a copy of an object (i.e. ByVal) you’ll need to copy the object yourself – in Java-speak this is called cloning the object.

Java in Notes/Domino Explained: Tricks in the Java Debug Console


The Java Debug Console is found under FileToolsShow Java Debug Console in the menu and this is where the output of System.out and System.err goes. There are a number of secret keyboard commands you can use to show various information. Below is a listing of these commands.

Note: The cursor has to be in the output field (the big one on the top) for the commands to work.

Key Description
p Print a list of the system properties (an enumeration of System.getProperties()
d Toggle debug info.
m Show memory information
g Run garbage collection
h Show help (list commands)
f Finalize objects in queue
v Show Java version information
0-9 Set applet error level