0

I have a button on an XPage where I want to connect to a remote OpenOffice instance. OpenOffice is started and is listening for a socket connection.

The onclick event of the button runs following SSJS:

    oo = new com.test.OpenOffice();
    oo.init("host=127.0.0.1,port=8107");
    oo.openFile("C:\\TEMP\\Test.odt");

The code raises an excepction jva.lang.IlleagalStateException: NotesContext not initialized for the thread

The exception is raised within the method initof the class OpenOffice.

The relevant parts of the class OpenOffice is the following code:

public class DHOpenOffice implements Serializable {
    private static final long serialVersionUID = -7443191805456329135L;
    private XComponentContext xRemoteContext;
    private XMultiComponentFactory xMCF;
    private XTextDocument oTextDocument;

    public DHOpenOffice() {
        xRemoteContext = null;
        xMCF = null;
        oTextDocument = null;
    }   

    public void init(String hostAdr) throws java.lang.Exception {
        xRemoteContext = null;

        XComponentContext xLocalContext = Bootstrap.createInitialComponentContext(null);
        XUnoUrlResolver xUrlResolver = UnoUrlResolver.create(xLocalContext);

        String sConnect = "uno:socket," + hostAdr + ",tcpNoDelay=0;urp;StarOffice.ServiceManager";

        Object context = xUrlResolver.resolve(sConnect);
        xRemoteContext = UnoRuntime.queryInterface(XComponentContext.class, context);  
        xMCF = xRemoteContext.getServiceManager();  
    }

The code line Object context = xUrlResolver.resolve(sConnect); is the one that raises the exception.

Why is this happing? What is the reason for this exception and how can I resolve the situation?

N.B.: The class code runs smoothly in a standalone application. The error occurs only when the code is started by a SSJS code.

Detlef Birkholz
  • 441
  • 2
  • 11

2 Answers2

0

It looks like a threading issue. There are a number of things you can go and try:

  • Wrap the whole interaction into a custom class and use it from a managed bean instead of calling it from SSJS
  • Make sure not to hand over any Notes objects into the custom class, only your own
  • Check if the Open Document Toolkit would be sufficient to do the operations you are interested in, so you don't need to run OO

let us know how it goes

Update
Try to get outside the standard XPages cycle. One way is to deploy a custom plug-in servlet:

 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;

public class OpenOfficeServlet extends HttpServlet {
   // Your code goes here
}

You need to get the plugin.xml right:

<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
   <extension point="org.eclipse.equinox.http.registry.servlets">
         <servlet alias="/ooproxy" class="com.yourcompany.OpenOfficeServlet" />
   </extension>
</plugin>

Then you could e.g. post a JSON structure or a serializable Java object to the servlet with the data and process it there (async if necessary). You deploy such a plug-in using the updatesite.nsf

stwissel
  • 20,110
  • 6
  • 54
  • 101
  • I've put the class DHOpenOffice into a managed bean and called the methods of the managed bean. The result is the same: an exception stating NotesContext not initialized. No Notes objects are handed over. The ODFToolkit is no option because it is missing some functions I must use. Maybe this information is helping to track down the problem: the exceptions is raised in the thread "MessageDispatcher" – Detlef Birkholz Mar 10 '14 at 13:45
  • The OO Java package uses threads that interfere with the XPages lifecycle. It seems you need to separate that further. I found that an XPages servlet or an XPages custom Rest service did not inherit the session/context so you could succeed there. Not pretty – stwissel Mar 10 '14 at 18:05
  • Bypass the XPages lifecycle using a servlet run in a plug-in. – stwissel Mar 12 '14 at 14:05
  • I'll give the servlet a try and will report how it is going. – Detlef Birkholz Mar 15 '14 at 17:25
  • I've create the servlet and deployed it to the server. Everythins is fine until I instantiate my custom class to connect to OO. The constructor is simply initializing some class properties. But calling the constructor results in a HTTP 500 error. In the error log I can find the follwing `java.lang.NoClassDefFoundError: com.sun.star.connection.NoConnectException`. Any hints what's going wrong? – Detlef Birkholz Mar 21 '14 at 08:58
  • Are the classes inside your plugin – stwissel Mar 21 '14 at 10:57
0

Thanks to the answer of @stwissel I was able to solve the problem (he pointed me to the right direction).

I could solve the problem with a simple OSGI plug-in. The servlet approach solved the problem, too, but for me the OSGI plug-in was easier to use.

So these are the steps to create the plug-in

  • start a new plugin project
  • copy the open office jar files into the project and include them into the build path
  • copy the custom class that uses the UNO API into the plug-in
  • create a feature project for the plugin
  • create an update site
  • deploy the plugin via an update site

The following site where also quite helpfull:

Detlef Birkholz
  • 441
  • 2
  • 11