Search code examples
javamultithreadinglotus-dominolotusscriptlotus-formula

Multithreading a java agent


A java agent has to upload a file in the background and return the Url of the uploaded file. While uploading, the agent has to report its progress.

I marked the agent to be "Run in background client thread.

I am stuck in the following dilemma:

  • I can run the agent from Lotus Script and pass its parameters in an In-Memory file, but the client actually doesn't run in its own thread. Instead, it blocks the whole client.
  • I can run the agent from a formula, but then I can't pass any parameters!
  • If I use Lotus Script and take care of the threading on my own in Java, my thread doesn't even get started!

I've read that the Notes client doesn't support multithreading. But I can't make the agent RunOnServer because it is accessing a web server available only for the client.

This is related to another question of mine by the way.

Is there any better solution for this?


Solution

  • If you can't make the agent RunOnServer then you can use LS2J instead of agent. Create your own class with threading and use its properties.
    Here is example with custom Java Class and Java Timer:

    import java.util.Timer;
    import java.util.TimerTask;
    
    public class Test
    {
        private boolean _isOver;
        private int _counter;
        private Timer _timer;
        private String _url; 
    
        public Test()
        {
            _timer = new Timer("Timer");
        }
    
        public void Start() //Add parameters here that you want to use in Java
        {
            _counter = 0;
            _isOver = false;
            _url = "";
    
            TimerTask timerTask = new TimerTask()
            {
                public void run()
                {   
                    if (_counter++ == 9)
                    {
                        _isOver = true;
    
                        _timer.cancel();
    
                        _url = "http://stackoverflow.com/";
                    }
                }
            };
    
            _timer.scheduleAtFixedRate(timerTask, 30, 5000);
        }
    
        public int getCounter() { return _counter; }
        public boolean getIsOver() { return _isOver; }
        public String getURL() { return _url; }
    }
    

    In LotusScript add global LS2J variables:

    (Options)
    Uselsx "*javacon"
    Use "MyJavaLibrary"
    
    (Declarations)
    Dim jSession As JavaSession
    Dim jClass As JavaClass
    Dim jObject As JavaObject
    
    Sub Initialize
    
        Set jSession = New JavaSession()
        Set jClass = jSession.GetClass("MyClass")
        Set jObject = jClass.CreateObject
    
    End Sub
    

    To start Java object use (in LotusScript of Button):

    Call jObject.Start() 'Call with parameters that you want to use in Java
    

    To check state and show progress use (in LotusScript of Timer):

    If jObject.getIsOver() Then
        s$ = jObject.getURL()
        'Show results
    Else        
        i% = jObject.getCounter()
        'Show progress
    End If