Developing OpenOffice extensions using Java and NetBeans

(short demos at the end)

You can call Sun people slow when it comes to creating an ecosystem of plugins. NetBeans had a platform years ago, but it’s only been a year since it became brain-dead easy to develop on top of it. As the saying goes: better late than never…

Now comes OpenOffice.

Starting with version OpenOffice 2.0.4 (freshly released) which was just released, packaging has evolved (new .oxt extension) and tools (Java for the time being) are now available to help you write code to extend the features of the suite or to interact with a silent instance. If you want to find out more about it, read this.
Also, the last OpenOffice Conference in Lyon had a presentation by Jürgen
Schmidt
on “OpenOffice.org Extensions Infrastructure”. Note that all this applies to StarOffice 8 (Update 4) also.

A couple of weeks back, I needed to write a prototype client to illustrate to end-users the use of a web services protocol (more on that in a later entry). TCP tunnels and technical Swing clients are not what you everyday tool and OpenOffice felt like a better choice. The only problem was the rather bad experience I had a couple of years back trying to get my head around UNO, the IDL language behind (inside) OpenOffice. I briefly tried the Eclipse plugin, but it required too much hand-coding and UNO investment.

I was lucky to test-drive an early version of the NetBeans OpenOffice integration plugin (thank you Steffen and Jürgen!). Here’s how it went:

What I simply wanted to do is provide a UI to the user to be able to send to current document using an optimized, reliable, and secure web services protocol (implemented in my case using GlassFish‘s WSIT). If this document was
in Open Document format, I would show the document metadata (properties) and send them over in the payload together with the document.

I decided on using Java 6 because of all the great desktop improvements (most important to me were look-and-feel fidelity and no more gray rectangle) it provides and because obviously Java now has Web Services in the JDK. So here are the ingredients:

Java 6 SDK (I used build 96)
– OpenOffice 2.0.4 (build 680)
– OpenOffice SDK (same version)
– NetBeans 6 Milestone 3

Java needs to be enabled (this is the default), and OpenOffice should be set to use the proper JRE (this is also where debugging options for the JVM are set) :

Once the OpenOffice NetBeans plugin is installed (get it here),
and the OpenOffice and SDK configured (Tools -> Options
-> Misc.).

NetBeans now has several new project types: client application,
Calc Add-in, UNO component:


You can now develop using Java and Swing (Matisse is yet again a life saver) and build the archive (an .oxt file containing the JAR and XML metadata) or even deploy directly (using a call to the unopkg
binary) to the OpenOffice instance (you’ll need to restart it to test).






setting up UNO environment ...



build UNO idl files
finished

uno-idl-compile:
init:
deps-jar:
jar:
Building jar: D:\\dev\\PRESTOopenoffice\\dist\\PRESTOopenoffice.jar
uno-package:
creating UNO extension package ...
Deleting: D:\\dev\\PRESTOopenoffice\\dist\\PRESTOopenoffice.oxt
Building zip: D:\\dev\\PRESTOopenoffice\\dist\\PRESTOopenoffice.oxt
Copying 1 file to D:\\dev\\PRESTOopenoffice\\dist
uno-deploy:
deploying UNO
extension package ...


T:/OpenOffice.org2.0\\program\\unopkg add -f D:\\dev\\PRESTOopenoffice\\dist\\PRESTOopenoffice.oxt
BUILD SUCCESSFUL (total time: 3 seconds)

Installing the extension can also be done manually using the Package Manager from the Tools menu (which is how your users would use it). Note that you can deploy this extension into previous versions of OpenOffice (2.0.x) or StarOffice 8 by changing the extension from .oxt to .uno.pkg.

A Calc Add-In project looks like this:

I will not go into all the details of these files. All I can say is that I happy I don't have to know most of what they do and why they exist.
The CalcAddins.xcu file is key to registering your extension in the OpenOffice UI : a menu item, a toolbar, etc... All this can be conditional and internationalized. The uno-extension-manifest.xml file is very similar to the JAR manifest and points to all the resources needed by the extension (including to file described above and all the Java code).

Once set up, you'll have code completion for com.sun.star.\* classes.

Debug
It really felt strange the first time I crashed OpenOffice. I started looking for a stacktrace but couldn't find one. So I ended up setting NetBeans de remote debug the JVM running inside OpenOffice executing my code. To enable debugging, add this line to the Parameters in the above Java options window:
-Xrunjdwp:transport=dt_socket,server=y,address=12999,suspend=n
and use Run -> Attach Debugger in NetBeans (the connector is SocketListen and port is 12999 on localhost). You can't step into OpenOffice code at this point, but this proved to
be very useful.
   
Tips
- I'm no UNO/OpenOffice expert, so I relied on OO-Snippets (to get the current document path in my case).
- If you really want to mess with .xcu files, make sure NetBeans recognizes them as XML: Tools ->Options ->Advanced ->IDE Configuration ->System ->Object Types ->XML Objects.
- Make sure the .oxt file contains all the Java code you need including libraries (hack the uno-package ANT target if necessary and make sure the manifest has an appropriate entry to reference the library jars relatively using Class-Path:). If you're really in hacking mode, drop library jars in the jre/lib/ext folder.
- If you're crashing OpenOffice all too often, try disabling the auto recovery.
- Looking for standard output: simply start OpenOffice from the command line.

And finally, the small demos :


Using the module in NetBeans.

 Installing and using the extension in OpenOffice.

Hopefully this will give you ideas of what can be achieved with OpenOffice and a little bit of Java coding.
I have a few ideas myself, let's see if can find the time to implement.

Advertisements

Author: alexismp

Google Developer Relations in Paris.

17 thoughts on “Developing OpenOffice extensions using Java and NetBeans”

  1. Hello,
    I’m trying to develop an extension to OpenOffice.
    Everything went smooth until the time that I’ve tried to deploy a library called swingx-ws to have https form based connection with a server.
    When I’m trying to “Deploy Office Extension” I get the following error message:
    ERROR: Error binding package: vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE/uno_packages/4.tmp_/GoogleDocs.oxt/swingx-ws.jar
    ERROR: Error binding package: vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE/uno_packages/5.tmp_/GoogleDocs.oxt/swingx-ws.jar
    ERROR: (com.sun.star.uno.RuntimeException) { { Message = “[jni_uno bridge error] UNO calling Java method writeRegistryInfo: non-UNO exception occurred: java.lang.NoClassDefFoundError: org/jdesktop/http/Session\\X000ajava stack trace:\\X000ajava.lang.NoClassDefFoundError: org/jdesktop/http/Session\\X000d\\X000a\\X0009at java.lang.Class.getDeclaredMethods0(Native Method)\\X000d\\X000a\\X0009at java.lang.Class.privateGetDeclaredMethods(Class.java:2427)\\X000d\\X000a\\X0009at java.lang.Class.getMethod0(Class.java:2670)\\X000d\\X000a\\X0009at java.lang.Class.getMethod (Class.java:1603)\\X000d\\X000a\\X0009at com.sun.star.comp.loader.JavaLoader.writeRegistryInfo(JavaLoader.java:448)\\X000d\\X000a”, Context = (com.sun.star.uno.XInterface) @0 } }
    I saw your tip to append the classpath into the uno-extension-manifest.xml so I added the following line:
    <manifest:file-entry manifest:media-type=”application/vnd.sun.star.uno-component;type=Java”
    manifest:full-path=” swingx-ws.jar”/>
    I’m using:
    NetBeans 5.5
    NetBeans Office Plugin 0.7
    OpenOffice 2.1
    OpenOffice SDK 2.1
    Sun JDK 1.6
    ps. I tried to put the jar specified inside the “jre/ext” folder of my JDK from which my OpenOffrice runs but still no lucky with it.
    It deploys the extension but I OpenOffice insists in crashing every time I click in the “Top Level Menu”.

  2. Hello,
    I’m trying to develop an extension to OpenOffice.
    Everything went smooth until the time that I’ve tried to deploy a library called swingx-ws to have https form based connection with a server.
    When I’m trying to “Deploy Office Extension” I get the following error message:
    ERROR: Error binding package: vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE/uno_packages/4.tmp_/GoogleDocs.oxt/swingx-ws.jar
    ERROR: Error binding package: vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE/uno_packages/5.tmp_/GoogleDocs.oxt/swingx-ws.jar
    ERROR: (com.sun.star.uno.RuntimeException) { { Message = “[jni_uno bridge error] UNO calling Java method writeRegistryInfo: non-UNO exception occurred: java.lang.NoClassDefFoundError: org/jdesktop/http/Session\\X000ajava stack trace:\\X000ajava.lang.NoClassDefFoundError: org/jdesktop/http/Session\\X000d\\X000a\\X0009at java.lang.Class.getDeclaredMethods0(Native Method)\\X000d\\X000a\\X0009at java.lang.Class.privateGetDeclaredMethods(Class.java:2427)\\X000d\\X000a\\X0009at java.lang.Class.getMethod0(Class.java:2670)\\X000d\\X000a\\X0009at java.lang.Class.getMethod (Class.java:1603)\\X000d\\X000a\\X0009at com.sun.star.comp.loader.JavaLoader.writeRegistryInfo(JavaLoader.java:448)\\X000d\\X000a”, Context = (com.sun.star.uno.XInterface) @0 } }
    I also tried adding the following line:
    <manifest:file-entry manifest:media-type=”application/vnd.sun.star.uno-component;type=Java”
    manifest:full-path=” swingx-ws.jar”/>
    I’m using:
    NetBeans 5.5
    NetBeans Office Plugin 0.7
    OpenOffice 2.1
    OpenOffice SDK 2.1
    Sun JDK 1.6
    ps. I tried to put the jar specified inside the “jre/ext” folder of my JDK from which my OpenOffrice runs but still no lucky with it.
    It deploys the extension but I OpenOffice insists in crashing every time I click in the “Top Level Menu”.

  3. Hi Rhawi, i assume that your own extension depends on the swingx-ws.jar, right? If yes, you don’t have to specify this jar file in the package manifest. Simply put the swingx-ws.jar file together with your own jar file in the oxt package and insert a dependency in the jar manifest of your own extension jar. I know that it is currently a little bit tricky, but i promise that we will improve the ant scripts for our office extension projects. Anyway today you have to do it by hand. Insert “Class-Path: swingx-ws.jar” (a relative path to the swingx-ws.jar from your own jar file) in the manifest if both jars are in the same directory. The easiest way is to manipulate the ant target in build-uno.xml directly. As mentioned before the ant scripts/targets need some redesign.
    I hope that helps, please let me know.

  4. I’m really looking for something like this.
    This post is old, and the plug-in doesn’t seem to support NetBeans 6. Any possibility that this will be updated?

  5. Hi, I’m interested in making OOo extension in java, using a java developpement software. Personaly i used Eclipse to do some stuff, but i wonder if, using Netbeans i could do an OOo extension including externals packages.
    Is it possible ?

  6. I started off with Eclipse when NetBeans had nothing to offer. Moving to NetBeans made all the difference. Not sure about external packages though.

  7. you can find the plugin in the Beta Update center for NB 6. The project is active and we will provide future releases with further improvements and smoother integration in NB. The current version has still the issue that i have described in my blog entry but it works and you can use it. Stay tuned for more …

  8. Heu… i’ve try to use Netbeans in order to make a component which just print ‘Helloworld’ … and i failed…
    Is there a tuto explaining how to begin ?

  9. Hi ! I started to manage myself with netbeans, the last problem is when i want to access to the current text’s document.
    I dispose of 2 objects :
    – XComponentContext m_xContext
    – and a XFrame m_xFrame
    How can i access to the text with those object ?

  10. Ok i found it !
    to others i post the solution :
    XMultiComponentFactory xmcf = m_xContext.getServiceManager();
    Object desktop;
    try {
    desktop = xmcf.createInstanceWithContext("com.sun.star.frame.Desktop", m_xContext);
    XDesktop xDesktop = (XDesktop) UnoRuntime.queryInterface(XDesktop.class, desktop);
    XComponent document = xDesktop.getCurrentComponent();
    XTextDocument xTextDoc = (XTextDocument) UnoRuntime.queryInterface(XTextDocument.class, document);
    XText xTxt = xTextDoc.getText();
    XTextRange xTextRange = xTxt.getEnd();
    xTextRange.setString(result);
    }
    catch(Exception e){
    System.out.println("dispatch Exception : " + e.getMessage());
    e.printStackTrace();
    }

  11. To anyone reading this,
    I’m developing an Open Office plug-in for my senior project class. I used the Addon feature through the Netbeans Open Office plug-in to get a menu in Open Office, but I can’t put any code behind it. The code skeleton is not generating. Can someone help me or point me in the right direction? I would really like to graduate…
    Open Office & SDK: 2.4
    JDK: 6
    Netbeans: Tried 5.5 and 6.1

  12. To anyone rrading this,
    We are trying to create a grammar checker(interrogative sentences in Filipino) in Open Office using netbeans. Can anyone help me on how to insert code in Open Office using netbeans? Thank you very much.
    Godspeed!!!

  13. jerome, i’d like to stay close to Sun projects, so rather than using Eclipse with Felix, is there a combination that includes Felix (or another implementation of OSGi), Netbeans and Glassfish?

Comments are closed.