Bistro!
Alexis Moussine-Pouchkine's Weblog
public enum Topic { Java, GlassFish, Tools, Sun, InFrenchInZeText, SDPY }

20061020 vendredi octobre 20, 2006

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.


( oct. 20 2006, 01:44:04 AM CEST ) Permalink Comments [13]

Trackback URL: http://blogs.sun.com/alexismp/entry/developing_openoffice_extensions_using_java
Comments:

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".

Posted by Rhawi Dantas on mars 15, 2007 at 12:52 AM CET #

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".

Posted by Rhawi Dantas on mars 15, 2007 at 12:54 AM CET #

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.

Posted by Juergen Schmidt on mars 15, 2007 at 01:43 PM CET #

good

Posted by 122.169.21.222 on août 19, 2007 at 09:19 AM CEST #

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?

Posted by javadev on février 07, 2008 at 07:04 PM CET #

I understand the developers are working on the NetBeans 6 version. See: http://blogs.sun.com/GullFOSS/entry/oo_org_netbeans_plugin_will

Posted by Alexis MP on février 07, 2008 at 08:26 PM CET #

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 ?

Posted by Tanith on mars 10, 2008 at 02:58 PM CET #

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

Posted by Alexis MP on mars 10, 2008 at 03:03 PM CET #

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 ...

Posted by Juergen Schmidt on mars 10, 2008 at 03:25 PM CET #

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 ?

Posted by Tanith on mars 10, 2008 at 05:31 PM CET #

Make sure you start OOo from the command-line to see the standard output.

Posted by Alexis MP on mars 11, 2008 at 12:16 AM CET #

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 ?

Posted by Tanith on mars 11, 2008 at 10:27 AM CET #

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();
}

Posted by Tanith on mars 11, 2008 at 11:27 AM CET #

Post a Comment:

Name:
E-Mail:
URL:

Your Comment:

HTML Syntax: NOT allowed

Join us at CommunityOne
ALT DESCR
Tags
Links