Calling Java classes from LotusScript
Have you ever wondered how you could call already written and quite useful Java classes in your LotusScript code? To me, this moment was, when I was trying to implement other department’s code into my own. Unfortunately I wasn’t skilled enough in ways of object development, LS2J and googling back then to actually figure out that was possible. I remember thinking: “IBM implemented Java in Lotus Notes, they must have done some adaptor for it.”, but was unable to figure it out. Until couple of years back, when I got a Holy shit! moment, finding this blog post.
But why would I need that?
As you can see from the above examples, you can implement Java functionality to your LotusScript code. This can be good if your Java programming skills aren’t that great or you already have some code in LotusScript and you wish to add functionality. For me, it would do fine in cases where I converted documents in a database to PDF on user request, or when I needed an agent to login user to notes via web in the background, or as I mentioned, when I needed to implement some functionality from other department in my already existing code. Instead, I re-wrote several agents into Java, which in the end didn’t prove to be that bad of a decision, but about that some other day.
But how do I do that?
There is a functionality called LS2J that does exactly that for you. If you will, you can imagine it as an adaptor for LotusScript that allows you to call Java classes. I will give you a small example. It is based on my user login class, although, there is really no code there to log in the user.
First you need to create/obtain a java library that does what you want. I named that library jclass:UserLogin.
public class CUserLogin {
String m_strUsername;
String m_strPassword;
public void Initialize(String strUsername, String strPassword) {
if ((strUsername.length() == 0) || (strPassword.length() == 0)) return;
m_strUsername = strUsername;
m_strPassword = strPassword;
}
public boolean run() {
// add code that will perform auto-login return true;
}
}
Then, I strongly suggest you create a LotusScript library, containing a class that will do actual Java to LotusScript conversion. Why? So you have to do it only once.
My script library called class:UserLogin is depicted below.
Uselsx "*javacon" Use "jclass:UserLogin" Class CUserLogin loginObj As JavaObject Sub New (strUsername As String, strPassword As String) Dim js As New JAVASESSION Dim loginClass As JAVACLASS Set loginClass = js.GetClass ("CUserLogin") Set loginObj = loginClass.CreateObject () Call loginObj.Initialize (strUsername, strPassword) End Sub Function run() As Boolean run = loginObj.run() End Function End Class
And that is it. Now all you have to do, is use this script library in your code. Where you need it. I created a simple agent that will pop-up a window with text depicting login success.
Use "class:UserLogin" Sub Initialize Dim userLogin As CUserLogin Set userLogin = New CUserLogin ("test", "test123") If (userLogin.run()) Then Messagebox "Login succeeded" Else Messagebox "Login failed!" End If End Sub
April 23rd, 2009 at 06:04
I don’t suppose you have any suggestions for how to instantiate a Singleton class that has no public Constructors?
April 23rd, 2009 at 19:24
As a matter of fact, I sort of do. In Part 3 of Design patterns series, I did exactly that. Mind you, you cannot have a private constructor in LotusScript, so what you have to do is create a private class with public constructor, which disables any code but the one in the library to create new class. Then, you don’t have static methods or variables in LotusScript, so what you need to do is a public function that will return instance of singleton class.
April 24th, 2009 at 01:42
Actually, I meant a Java singleton class with private constructors. When I call the CreateObject method from Lotusscript, it chokes because it can’t find a constructor in the Java class.
April 24th, 2009 at 14:49
I doubt you can do that. What you can do, is create your own Java Class that encapsulates mentioned singleton class. Then you can write a LotusScript class that loads that Java class. I know this is a tad awkward, but I don’t really see any other possibility.
July 28th, 2011 at 01:10
Thanks for the tip
very useful for a first time java/lotusScript combination user
September 12th, 2011 at 15:03
Excellent tip, but exactly how is errorhandling performed between Java and LotusScript? If I throw an error in a Javaclass method (lets say the run() function in Your example) – what are populated up to the LotusScript class? When I tried I only succeeded in giving an errormessage to the exception, not any errornumber…
If I throw an Exception in the run(), then the only thing that is populated up the chain is the message that I provide. The errornumber will always be #318. And whats worse is that the error message will be prefixed with “- LS2J Error threw java.lang.Exception”.
Do You have any solution for giving LotusScript the correct errornumber and the correct errormessage?
September 13th, 2011 at 09:57
In my case, you would need to modify my CUserLogin LotusScript class and make js variable a class member and not a local variable. After that, you just modify Run() method of the class with error handling and in that error handling, you call js.getLastJavaError() .
Remodeled CUserLogin class would now look like:
This link describes how to handle LS2J exceptions in detail and much of other LS2J tricks 🙂
March 21st, 2012 at 09:10
how to provide parameters to createObject method
March 21st, 2012 at 21:58
http://publib.boulder.ibm.com/infocenter/domhelp/v8r0/index.jsp?topic=%2Fcom.ibm.designer.domino.main.doc%2FLSAZ_JAVACLASS_CREATEOBJECT_METHOD.html
Google is your friend 🙂