[Java example] Using the Interprocess Connection Mechanism

Java, C++, C#, Delphi... - Using the UNO bridges
Post Reply
hol.sten
Volunteer
Posts: 495
Joined: Mon Oct 08, 2007 1:31 am
Location: Hamburg, Germany

[Java example] Using the Interprocess Connection Mechanism

Post by hol.sten »

This post contains a working example of the Interprocess Connection Mechanism and how you get this working in NetBeans 5.5.1:
- Start NetBeans IDE
- Create a new project by calling "File" > "New Project..."
- Right-click with the mouse on the brand new project name and select "Properties" from the context menu
- Select in the Project Properties from Categories the categorie "Libraries" and there the tab "Compile"
- Press the button "Add JAR/Folder" and locate some of OOo's JAR files from OOo's installation directory which is on Windows for example "c:\program files\openoffice.org 2.3\program\classes". Add at least juh.jar, jurt.jar, ridl.jar and unoil.jar. Adding these JAR files exactly here in your Project Properties is very important!
- Create a new class containing the following code:

Code: Select all

package oootest;

import com.sun.star.beans.PropertyValue;
import com.sun.star.beans.XPropertySet;
import com.sun.star.bridge.XUnoUrlResolver;
import com.sun.star.connection.NoConnectException;
import com.sun.star.frame.XComponentLoader;
import com.sun.star.frame.XStorable;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;

public class InterprocessConnectionOdtToPdfQuickAndDirty {
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        String loadUrl="file:///c:/dev/netbeans/oootest/mydoc.odt";
        String storeUrl="file:///c:/dev/netbeans/oootest/mydoc.pdf";

        try {
            // Start OOo
            Runtime.getRuntime().exec("C:\\Program Files\\OpenOffice.org 2.3\\program\\soffice.exe -accept=socket,host=localhost,port=8100;urp");
            Thread.sleep(10000); // Waits 10 seconds, because Runtime.getRuntime().exec("...") does not wait until OOo is really running in Listening Mode
           
            // Connect to OOo and us it
            XComponentContext xLocalContext = com.sun.star.comp.helper.Bootstrap.createInitialComponentContext(null);
            XMultiComponentFactory xLocalServiceManager = xLocalContext.getServiceManager();
            Object urlResolver  = xLocalServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver",xLocalContext);
            XUnoUrlResolver xUnoUrlResolver = (XUnoUrlResolver) UnoRuntime.queryInterface(XUnoUrlResolver.class,urlResolver);

            Object initialObject = xUnoUrlResolver.resolve("uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager");
            XPropertySet xPropertySet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class,initialObject);
            XComponentContext remoteContext = (XComponentContext) UnoRuntime.queryInterface(XComponentContext.class, xPropertySet.getPropertyValue("DefaultContext"));

            XMultiComponentFactory remoteServiceManager = remoteContext.getServiceManager();
            Object desktop = remoteServiceManager.createInstanceWithContext("com.sun.star.frame.Desktop", remoteContext);
            XComponentLoader xcomponentloader = (XComponentLoader) UnoRuntime.queryInterface(XComponentLoader.class,desktop);

            Object objectDocumentToStore = xcomponentloader.loadComponentFromURL(loadUrl, "_blank", 0, new PropertyValue[0]);

            PropertyValue[] conversionProperties = new PropertyValue[1];
            conversionProperties[0] = new PropertyValue();
            conversionProperties[0].Name = "FilterName";
            conversionProperties[0].Value = "writer_pdf_Export";

            XStorable xstorable = (XStorable) UnoRuntime.queryInterface(XStorable.class,objectDocumentToStore);
            xstorable.storeToURL(storeUrl,conversionProperties);
        }
        catch (NoConnectException e) {
            System.out.println("OOo is not responding");
            e.printStackTrace();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            System.exit(0);
        }
    }   
}
Save the class and let it run by calling "Run File" for example.

Besides establishing the connection to OOo the only useful task this code performs is converting a document from ODT to PDF.

Using this code I get the same result I get from running my Bootstrap Connection Mechanism example.

Disadvantages of the Interprocess Connection Mechanism: You must handle starting OOo by yourself and you have some extra code to write.
Advantages of the Interprocess Connection Mechanism: You can move or copy OOo's jar files where ever you want as long as you put them somehow into your classpath and you can add several start parameters to the starting command of OOo like -norestore, -headless or -nofirststartwizard.

Additional advice: Don't put the start command for OOo into the Java code! Use a script or batch file instead and put the name of the script/batch file into a configuration file. Then change the Runtime.getRuntime().exec() line to something like:

Code: Select all

Runtime.getRuntime().exec(getScriptFileNameFromConfig());
By doing it this way, you can use the same Java code on Windows and Linux. All you have to do on a new server is to write a new script/batch file or adjust an existing script/batch file. On Windows you can use something like this:

Code: Select all

@echo off


rem Init start parameters
set OOO_APP="C:\Programme\OpenOffice.org 2.3\program\soffice.exe"
set OOO_PARAM=-headless -norestore
set OOO_SOCKET="-accept=socket,host=localhost,port=8100;urp"


rem Start OpenOffice.org
echo start "OpenOffice.org" %OOO_APP% %OOO_PARAM% %OOO_SOCKET% >>oo.log
start "OpenOffice.org" %OOO_APP% %OOO_PARAM% %OOO_SOCKET% 
Save the batch file as something like "startOOo.bat".

On *nix you can use something like this to start the virtual framebuffer xvfb and then OOo:

Code: Select all

#! /bin/ksh


# Init start parameters
OOo_App=/opt/openoffice.org2.3/program/soffice
OOo_Param="-headless -norestore -display :1.0"
OOo_Socket="-accept=socket,host=localhost,port=8100\;urp;StarOffice.ServiceManager"


# Start the X virtual Frambuffer
/usr/X/bin/Xvfb :1 -screen 0 800x600x16 -fbdir /var/tmp/tempfb &


# Start OpenOffice.org
echo "Start $OOo_App $OOo_Param $OOo_Socket"
$OOo_App $OOo_Param $OOo_Socket 
Save the script as something like "startOOo.sh".

If you want to convert the document into a different format, you have to change the FilterName of the conversionProperties. For example to convert a document to DOC change

Code: Select all

conversionProperties[0].Value = "writer_pdf_Export";
to

Code: Select all

conversionProperties[0].Value = "MS WinWord 6.0";
Or try the filter list, if you need another conversion: http://wiki.services.openoffice.org/wik ... st_OOo_2_1
OOo 3.2.0 on Ubuntu 10.04 • OOo 3.2.1 on Windows 7 64-bit and MS Windows XP
hol.sten
Volunteer
Posts: 495
Joined: Mon Oct 08, 2007 1:31 am
Location: Hamburg, Germany

Change log

Post by hol.sten »

19. Dec 2007: Creation of the Java example
OOo 3.2.0 on Ubuntu 10.04 • OOo 3.2.1 on Windows 7 64-bit and MS Windows XP
Post Reply