« Back to home

JDK 8 JavaScript scripting experiment, with added Domino

Oracle’s new JDK 8.0 includes a new JavaScript engine called Nashorn, designed to support both embedded JavaScript in Java applications, and standalone command-line JavaScript. As well as accessing JavaScript from Java code, you can do the reverse, and access Java classes from JavaScript — just like in IBM Domino XPages. The new scripting features are now a standard part of the JRE.

For now, the command to actually run a script is described by Oracle as “experimental and unsupported”, but I wasn’t going to let that put me off; I immediately wondered how easy it would be to write a command-line script which accessed Domino data, using only JavaScript. The answer: Pretty easy, though there are still some problems to be aware of.

The magic that makes it all possible is provided by CORBA and DIIOP. While CORBA didn’t catch on across the industry and was plagued by horrible implementations, the Domino version makes good on the location transparency promise of CORBA. After a couple of lines of setup code, you can run Java code on your local machine and access Domino exactly as if you were running it on the Domino server.

My sample JavaScript code follows the same process as Java code. Here’s a quick walkthrough.

First of all, I define a Domino convenience object to encapsulate the CORBA setup. It uses the Packages object in Nashorn to load the NotesFactory class from Domino’s Java libraries, storing it in a local variable so it can be used without typing the entire qualified class name each time.

The Nashorn introductory material suggests using a Mozilla Rhino compatibility feature to load Java classes:


I was unable to get this to work. I couldn’t get the JavaImporter class to import lotus.domino either, and also decided I wanted to avoid it because JavaScript in strict mode doesn’t support the use structure which JavaImporter is designed around. If you have any luck with importClass and Domino, I’d be interested to see code.

Anyhow, with the Domino NotesFactory class loaded, the openSession method is defined. When called, it uses NotesFactory.getIOR() to connect via HTTP to the Domino server, and fetch the IOR — which is actually just a text file called http://server.example.com/diiop_ior.txt, where server.example.com is the Domino server hostname. The IOR itself is just a string of ASCII characters that tell CORBA how to interface with the Domino server.

Note that your Domino server needs to have IIOP enabled, and there can be a catch if you have the server locked down to require HTTPS connections: The standard NotesFactory.getIOR() method doesn’t support SSL. So if your Domino server is set to always require SSL, you’ll need to write your own JavaScript method to log in and use HTTPs to fetch the text from the IOR URL as a String.

IOR fetched, NotesFactory is used to obtain a lotus.domino.Session object, which is returned.

Finally, the rest of the Domino object’s code (the initialization code) calls the openSession method just defined, and returns the result.

With the Domino utility object defined, the process of accessing Domino from JavaScript is then simple:

// Get a lotus.domino.Session
sess = Domino.openSession(serverURL, username, password);
// Get a database
db = sess.getDatabase("servername/MYORG", "some/db.nsf");

and so on. It’s exactly like XPages SSJS, except there you’d use DominoUtils.getCurrentSession() to get the existing session object instead of opening a new one via CORBA.

The only other thing to note is that you need both Notes.jar and NCSO.jar from your server to be added to the CLASSPATH for your Java environment when the script is run. I did this using the -cp argument to the jrunscript command, which works just like it does when using the java command to run a Java program.

So, what is this good for? I can think of a few possibilities.

First of all, it means I can build and test JavaScript code for XPages outside of the Domino Designer. Since I run Linux, and the Domino Designer is a legacy Windows-only application, that’s a big win for me.

A second use case is one-off scripts to process data. I often need to clean up a batch of documents in some way, and I’d much rather write the code to do so in JavaScript than in either Java or LotusScript.