Getting started with the OpenOffice.org API part III : starting OpenOffice.org with jars not in the OOo install dir

36

One of the first things OOo developers learn is to make sure the juh.jar, jurt.jar, ridl.jar, sandbox.jar and unoil.jar files should be on the classpath and should be in the original directory they were installed in while installing OOo. On a Windows machine, this directory is C:\Program Files\OpenOffice.org 2.0\program and on Debian Linux this is /usr//lib/openoffice/program. Using the hints in this oooforum entry I was able to get OpenOffice.org started with those five jar files loaded from an entirely different location on my hard disk. Want to know how? Read on…

....

When OpenOffice.org is installed on Windows, the jar files are included as well. Unfortunately, not the sources for those jars. Fortunately, the OOo install on Debian does include them, so I was able to extract the Bootstrap.java source file and have a look at it. In the said entry on oooforums, manutudescends hints about these lines of code in the bootstrap() method in Bootstrap.java

String sOffice = System.getProperty( &quot;os.name&quot; ).startsWith( &quot;Windows&quot; ) ? &quot;soffice.exe&quot; : &quot;soffice&quot;;<br />File fOffice = NativeLibraryLoader.getResource(Bootstrap.class.getClassLoader(), sOffice);

Basically, these lines say "Hava a look at the OS this person is running and get me the name of the OOo executable. Then have a look at the location of the Bootstrap.class file on the OS and get the File that represents the OOo executable". This explains why the juh.jar file, which is the one containing the Bootstrap class, needs to be in the same location as the OOo executable! If it’s not, this method won’t be able to find the executable by looking at the location of the Bootstrap class. In the oooforum entry manutudescends also explains how to get around this "feature" of OOo. Simply replace the ClassLoader gotten from the Bootstrap class with your own and you’re done.

So, this is how it can be done. First you make sure you can create a bootstrap method that takes a custom classloader. The simplest way is to copy the bootstrap method code as well as the code for the createInitialComponentContext, the insertBasicFactories and the pipe methods. A slightly more complex way is to subclass Bootstrap and copy the bootstrap code to that class so you can modify it. Please note that the insertBasicFactories and the pipe methods are declared private so you need to copy them anyway. Just decide what you want, your mileage may vary.

Next, modify the signature of the bootstrap method to

public static final XComponentContext bootstrap(URLClassLoader loader)

This will ensure that we will be able to pass on our own URLClassLoader instance. In order to use that instance, modify this line

File fOffice = NativeLibraryLoader.getResource(Bootstrap.class.getClassLoader(), sOffice);

to

File fOffice = NativeLibraryLoader.getResource(loader, sOffice);

and the method is done.

The final thing to take care of is the URLClassLoader instance. The ONLY reason the five jars need to be in the same directory is to find the OOo executable. So, it would be enough to only have the juh.jar file in the same directory. Finding the OOo executable is done by looking for the executable on the ClassLoader path(s) gotten from the Bootstrap class, so it suffices to only have the path to the OOo executable in a ClassLoader instance. Hence, create a URLClassLoader like this

URL[] jarList = new URL[] {<br />&nbsp;&nbsp;&nbsp; new File(ooBaseDirectory).toURL()<br />};<br />URLClassLoader loader = new URLClassLoader(jarList);<br />

and pass it on to the bootloader method like this

XComponentContext xContext = (XComponentContext)bootstrap(loader);

and OOo will start without a complaint Smiley
As for the value of the ooBaseDirectory, this should be a String representation of the path to the directory holding the soffice.exe (or soffice) executable. On windows, this line will do

String ooBaseDirectory = &quot;C:\\Program Files\\OpenOffice.org 2.0\\program&quot;;

while on Debian Linux this should be

String ooBaseDirectory = &quot;/usr/lib/openoffice/program&quot;;

but this String can be retrieved from a configuration file, a database or something else. No need to hard code it, just make sure the users of your app set it in the correct location before they start your app.

As for the current bootstrap method, I can understand why the OOo developers chose to do it like this. This will ensure that, given the correct location of the jar files, the OOo executable can ALWAYS be found. But it would be nice to have a way to set the location ourselves, so I will file an RFE for this.

Share.

About Author

36 Comments

  1. Wouter van Reeven on

    Hi all, I will take this article offline later this week. The reason is that this article is much outdated and there are great possibilities to achieve what’s described here using the OpenOffice.org plugin for NetBeans. I suggest you start using that.

    Thanks, Wouter

  2. martin joseph on

    hai Wouter van Reeven,

    First of let me thank u once again for spending a lot of your time for helping others
    on such a topic where finding good documentation is so hard. I had previously read the
    part ii of your article series where u helped me to insert bookmarks using open office.org api

    So … straight to my problem then . I did everything as u have said in this article .But my program
    runs into an exception or something at the line

    Object context = xUrlResolver.resolve( sConnect );

    i think this is the same error that InchBinich was referring to …

    could you help me rectify this …

    i will tell u what i did till now

    i subclassed Bootstrap class
    and copied in the methods u had said ie (bootstrap method, createInitialComponentContext, insertBasicFactories,pipe methods) .I then changed the few lines of code u had said

    Then i used the FirstUnoContact class shown in the developers guide .
    In this class i specified the ooobase directory as u had said …

    I am using windows xp os , open office org 2.4, netbeans 6.5

    I had copied the 5 jar files u mentioned into a new folder and added them into my project in netbeans

    Had i done something wrong .. or missed out on something ..

    Hoping u will respond to my query ,
    martin joseph

  3. Hi,

    i tried the suggestion given above. However, it hanged when trying to resovle s2 in the bootstrap method. any idea?
    thanks

  4. Hello all,
    I spent nearly whole day trying to implement this stuff. Finally I got the same problem like described @vishal, @vbms, @srinivas, …
    “java.lang.UnsatisfiedLinkError: com.sun.star.lib.connections.pipe.PipeConnection.createJNI(Ljava/lang/String;) etc.” (Windows XP and Solaris 10)
    I read this article and discussion several times without success, but finally the following command (executed on Solaris) solved my problem:
    “LD_LIBRARY_PATH=/opt/csw/OpenOffice.org/program:$LD_LIBRARY_PATH java -jar myapplication.jar”
    Hope it help to all other who have this problem (I hope this will fix this problem on Windows as well, but now I’m exhausted – I’ll test it tomorrow).

  5. Hi,

    I am using Solaris SPARC & trying to open word document using open office API. I did everything mentioned in your article/forum. But I am getting following error.

    Exception in thread “main” java.lang.UnsatisfiedLinkError: createJNI
    at com.sun.star.lib.connections.pipe.PipeConnection.createJNI(Native Method)
    at com.sun.star.lib.connections.pipe.PipeConnection.(PipeConnection.java:137)
    at com.sun.star.lib.connections.pipe.pipeConnector.connect(pipeConnector.java:145)
    at com.sun.star.comp.connections.Connector.connect(Connector.java:146)
    at com.sun.star.comp.urlresolver.UrlResolver$_UrlResolver.resolve(UrlResolver.java:133)
    at DocumentHandling.Bootstrap.bootstrap(Bootstrap.java:154)

    Can you let me know if Need solaris specific jar files? if yes from where can I download them?

  6. Hi, I also spent half a day w/o any result. I try to create an Eclipse plug-in which shall create/modify a document. I always get an exception (BootstrapException: no office executable found!) when I call Bootstrap.bootstrap(). I added all jars from OOo/program/classes into the build-path which is actually defined in the MANIFEST.MF file. I added the path hard-coded (this is another thing I have to solve), e.g. “external:D:/Program Files/OpenOffice.org 2.4/program/classes/juh.jar”.
    BTW, I first created a simple Java app which includes all jars directly and that worked. But it does not work with the Eclipse plug-in.
    Any hints?
    Thanks.

  7. Hi Sean,

    Sorry, I have no experience with this at all. AFAIK you’ll need the OfficeBean for this. For more info, see

    the OOo OfficeBean

    HTH, Wouter

    P.S. This article has become obsolete now that there is a VERY GOOD OOo plugin for NetBeans. Please go and check it out!!!

  8. Dear Wouter van Reeven and readers,
    Thank you for your invaluable information. I have now managed to build and run one of examples supplied with the openoffice sdk. Without your help, it would have been looking very ugly.
    They certainly don’t know how to make something easy to learn.
    However, now I am trying to embed the writer in a normal java app, as a JFrame or so (rather than magically invoke oo writer application as a whole), and I have come a little stuck.
    The example they so kindly provided (file:///usr/lib/openoffice/sdk/examples/java/EmbedDocument/EmbeddedObject) seems to provide an example JFrame object which can be used…
    but no example on how to use it. In fact, hardly a kind comment at all in the code, and none describing arguments to functions etc. Not very nice.
    Has anyone managed to do this properly?
    What I have managed to get running so far only looks like an ugly Textpane .. with no proper colours, no menu, no buttons… no mouse listener .. no copy and paste…
    I hardly think it is working at all….. So I have obviously done something wrong. But finding good documentation and examples on this … i am finding difficult. Or maybe i am just not a very good google searcher?
    Can anyone help me?
    All I want to achieve is this:
    1. an open office window looking JFrame, with full menu and buttons and font selector etc. (no fancy changes, removing this, adding that)
    2. implement a drag and drop listener on this ooJFrame, so that I can tailor the content dragged from one java component to this OO Component.
    (i know how to do this in a normal java context…. is it the same in this circumstance?)

    any pointers? Please!!!??!

  9. Hello Ichbinich, today I made the following observations, trying to get the above Bootstrap modifications working: First observation: Putting the JAR files juh.jar, jurt.jar, ridl.jar and unoil.jar into a directory outside OOo’s installation directory and modifying Bootstrap.java as written above does not suffice. My application terminated after executing “xUrlResolver.resolve(sConnect);”, too. Second observation: To get the modifications working is possible by using one of the following alternatives: 1) Put the ooBaseDirectory into the CLASSPATH. 2) Add -Djava.library.path=”C:/Programme/OpenOffice.org 2.3/program” to the VM options (I got this idea from here: http://www.oooforum.org/forum/viewtopic.phtml?t=40263 (mnasato explained the caveat of the pipe)). 3) Use juh.jar from the classes directory of ooBaseDirectory. 4) Use ridl.jar from the classes directory of ooBaseDirectory. 5) Don’t use a pipe at all and use a socket connection (change the -accept option to “-accept=socket,host=localhost,port=8100;urp;” and the connection string to “uno:socket,host=localhost,port=8100;urp;StarOffice.ComponentContext”). Using 1) OR 2) OR 3) OR 4) OR 5) does suffice. It is not necessary to combine several alternatives to get the modifications above working. My environment is OOo 2.3.1, Java 6 Update 4, NetBeans 6.0, Windows XP.

  10. Hey.

    After resolving all the errors by putting all the import things to the bootstrap I dont get an error in all my classes.

    But when I now try to start the main class, the programm just terminates. I backtraced this with printStreams and the problem seems to be in this line:

    267 Object context = xUrlResolver.resolve( sConnect );

    in the bootstrap class. Something seems to be wrong with that line. Can you please give a hint how to solve this problem?
    Thanks!

  11. Wouter van Reeven on

    Hi Heiko, we had a discussion about your problem via email. It turns out that you should make NetBeans NOT include the jar files in the lib dir of the project and that the project can be ran outside of NetBeans through the command ‘java -cp {OOo}\program\classes;dist\Test1.jar FirstUnoContact [input arguments]’. Greets, Wouter

  12. Hi. You delivered a very good example of keeping and publishing solutions to common problems. Thank you for that. Unfortunately, I ran into the same problems as polly and srinivas. I started by “clicking together” some of the example files from the api.openoffice web page in NetBeans 6.0 under WinXP and used the building script from their “FirstUnoContact” example. In the debugger it works fine, but deploying doesn’t. It also doesn’t work to copy the .jar files to the OOo\program folder or specifying their location as classpath. I’m stuck.
    But I read about a NetBeans integration package for the OpenOfficeSDK in their wiki. It should solve the issue. Still, it is not available for NetBeans 6. So I keep gnawing on my keyboard.
    If you think you could give some more hints I can give a very detailed description of my configuration. I’m desperate to resolve this problem because the opportunities of using OOo in this way are so great.
    Bye, Heiko

  13. Wouter van Reeven on

    Hi Tobias,

    Sorry it took such a long time for me to reply to you. Please read my blog entry again. You need to copy the Bootstrap class code to a new class of your own and then modify the code in that class. If you have a look at the bootstrap method in the Bootstrap class you’ll see how to proceed and what to return.

    HTH, Wouter

  14. This link explains: http://technology.amis.nl/blog/?p=1284
    But I do not understand well ! :(

    I did this :

    private static String sOffice = System.getProperty(“os.name”).startsWith(“Windows”) ? “soffice.exe” : “soffice”;
    File fOffice = NativeLibraryLoader.getResource(Bootstrap.class.getClassLoader(), sOffice);

    public static final XComponentContext bootstrap(URLClassLoader loader){
    File fOffice = NativeLibraryLoader.getResource(loader, sOffice);
    return ????;
    }

    What do I have to do to continue ???

  15. Matthias Roscher on

    Hi, at first i will thank you for this, next I want catch some Events from OpenOffice , e.g. the close-event. Have you an Idea how i can realize that? thanks for your effort. Matthias

  16. Everything works when adding the following to “Classpath Prefix:”

    C:\OOo\Office_2_3\program
    C:\OOo\Office_2_3\program\classes\juh.jar
    C:\OOo\Office_2_3\program\classes\jurt.jar
    C:\OOo\Office_2_3\program\classes\jut.jar
    C:\OOo\Office_2_3\program\classes\ridl.jar
    C:\OOo\Office_2_3\program\classes\unoil.jar
    C:\OOo\Office_2_3\program\classes\officebean.jar
    C:\OOo\Office_2_3\program\classes

  17. Wouter van Reeven on

    Hi Polly,

    Can you please tell me where you copied the dll to? As far as I know, the classes dir holding the dll should be on the classpath. In this classes dir there is a win dir that contains the dll. I think you should make sure that this win dir is on the classpath. Can you tell me if that helps?

    Wouter

  18. Thanks Wouter,yes I’m under windows.Even copying the dll nothing changes.When I call the original bootstrap method in a standalone application it’s all ok.But I need to use it inside a servlet.I made sure my server (tomcat) access directly the original jars under OO directory.Unfortunately I keep getting the “not office executable found” exc. when using the original jar and the “Unsatisfied link error” exc. using my modified juh.jar.

  19. Wouter van Reeven on

    @srinivas & polly On what operating systemn do you get these errors? I bet on windows. If so, please make sure the classes\win directory containing the unowinreg.dll library is copied to the directory that ooBaseDirectory points to as well. Please let me know if this solves your problem.

  20. Wouter van Reeven on

    @vmbs In the introduction of this article I state that putting those 5 jars on your classpath is the defacto way of getting the OOo API to work correctly. This article just tells you how to make the OOo API work in case you don’t know beforehand where those jars are, i.e. when you cannot put them on your classpath.

  21. Hi,
    I’m getting exactly the same exception: java.lang.UnsatisfiedLinkError: com.sun.star.lib.connections.pipe.PipeConnection.createJNI(Ljava/lang/String;)I
    Adding OO paths to my classpath was the first thing I’ve tried,even before editing the source.And it didn’t work.
    What exactly did you add and where?
    back to the code editing solution does anyone know how to go over the UnsatisfiedLinkError exception?Adding the path like Wouter suggested didn’t work.
    Thanks!

  22. i dont beleve this iv spent all day reading this article and trying to get it to work then i found out that its totaly unnesisery … instead of editing openoffice source … just add the folder to the java classpath … this is not amusing

  23. im getting this error 2 i have done whats said above … this is exact errorrr i get
    Exception in thread “main” java.lang.UnsatisfiedLinkError: com.sun.star.lib.connections.pipe.PipeConnection.createJNI(Ljava/lang/String;)I
    at com.sun.star.lib.connections.pipe.PipeConnection.createJNI(Native Method)
    at com.sun.star.lib.connections.pipe.PipeConnection.(PipeConnection.java:137)
    at com.sun.star.lib.connections.pipe.pipeConnector.connect(pipeConnector.java:145)
    at com.sun.star.comp.connections.Connector.connect(Connector.java:146)
    at com.sun.star.comp.urlresolver.UrlResolver$_UrlResolver.resolve(UrlResolver.java:133)
    at rev.BootstrapUtil.bootstrap2(BootstrapUtil.java:56)
    at rev.UnoContext.createDocument(UnoContext.java:43)
    at rev.TestCreateTableAndInsert.go(TestCreateTableAndInsert.java:34)
    at rev.t_main.main(t_main.java:17)
    what was that about just having to add something to your java classpath i have tryed everything i can think of…. thnx for this article at least there is a way that sould work

  24. hi iam getting the

    java.lang.UnsatisfiedLinkError: createJNI
    com.sun.star.lib.connections.pipe.PipeConnection.createJNI(Native Method)
    com.sun.star.lib.connections.pipe.PipeConnection.(PipeConnection.java:137)
    com.sun.star.lib.connections.pipe.pipeConnector.connect(pipeConnector.java:145)
    com.sun.star.comp.connections.Connector.connect(Connector.java:146)
    com.sun.star.comp.urlresolver.UrlResolver$_UrlResolver.resolve(UrlResolver.java:133)
    comerce.Readods.bootstrap(Readods.java:88)
    comerce.Readods.getOdsdata(Readods.java:150)

    please help me out

  25. Need to know how to integrate an external spellchecker into OpenOffice.
    I do not want to create new .dic files. I need to integrate an existing one, responding to OO API calls.

    Any help is appreciated.

  26. Chunyun Zhao on

    Interesting, why would you take all this pain just to add /usr/lib/openoffice/program to the classpath so that Bootstrap could find soffice executable? Add it to your java classpath should do the trick!

  27. Wouter van Reeven on

    Hi Frank,

    Yes you can connect to a remote OpenOffice. First you need to make sure that OpenOffice is started on the server in such a way that it will listen to a TCP port. Next you need to make sure that you have a local connection to the remotely running OpenOffice. you can find all the details about it here

    http://api.openoffice.org/docs/DevelopersGuide/ProfUNO/ProfUNO.xhtml#1_3_UNO_Concepts

    Please note that running OOo remotely will also create all documents remotely! So in order to get the documents to the client you’ll need to make them available, e.g. via HTTP or FTP or so.

    Greets, Wouter

  28. Can we try to connect to a remote server?I think if we can connect a remote openOFFICE server, maybe we need not install openoffice in client.

  29. Wouter van Reeven on

    Hi Aloizio,

    The original code can be downloaded from the OpenOffice.org website. It’s Open Source, remember?
    When you get the “no office executable found” error, this ususally means that the juh.jar file is not in the same directory as the soffice(.exe) executable, so please make sure this is the case. If this doens’t help, or if you are unable to make sure of this, please add the path to the directory holding the soffice(.exe) executable to your PATH variable (under Windows) or your LD_LIBRARY_PATH variable (under *nix).

    HTH, Wouter

  30. Hi Pieter-Jan,

    How Can I modify the signature of the bootstrap method? Where Can I find the original code? I always get the message “no office executable found’.

  31. Wouter van Reeven on

    Hi Pieter-Jan,

    This error occurs when the bootstrap method calls “pipe( p.getInputStream(), System.out, “CO< ” );” which depends on platform specific libraries. These libraries can be made available by putting the directory containing the soffice(.exe) executable on the java.library.path variable. This can be done under Windows by including the directory holding the executable to the PATH variable. On Linux and Unix this directory should be added to the LD_LIBRARY_PATH variable for the user running the application. Please make sure this is documented when you want to distribute your application through Java Web Start else noone will be able to run your application!

    HTH, Wouter

  32. hi,

    leaving the jar files in the OpenOffice directory was not an option for me (ultimately the application will be deployed using java webstart).
    i’ve tried your solution and i’v managed to patch the Bootstrap class and bypass the “no executable found” error.
    I’ve got another exception now though :

    Exception in thread “main” java.lang.UnsatisfiedLinkError: createJNI
    at com.sun.star.lib.connections.pipe.PipeConnection.createJNI(Native Method)
    at com.sun.star.lib.connections.pipe.PipeConnection.(PipeConnection.java:137)
    at com.sun.star.lib.connections.pipe.pipeConnector.connect(pipeConnector.java:145)
    at com.sun.star.comp.connections.Connector.connect(Connector.java:146)
    at com.sun.star.comp.urlresolver.UrlResolver$_UrlResolver.resolve(UrlResolver.java:133)
    at be.profitplus.client.MyBootstrap.bootstrap(MyBootstrap.java:391)

    Did you encounter this problem already ? And maybe did you find a solution ?

    Thanks a lot for your article!

    PJ

  33. Wouter van Reeven on

    Hi,

    Thank you for your kind words concerning my articles. Whenever you want to connect to OOo you’ll need it, either locally or on a server. This means that your client will always need OOo, no matter what. So please make sure to mention OOo as one of the prerequisites for your application :-)

    I have no experience with the OOo spellchecker yet so I am unable to help you at this moment. When I have some time I might dig into it and write an article about it.

    Greets, Wouter

  34. hi,

    Thanks for the reply and it is a best open office api startup help i have found on the internet.

    i have the program for the hello world working. the reason i wanted to go through all this is that i wanted to use the Lingustics2 for spellchecking. I am working on a project and i wanted to use openoffice spellcheck instead of the microsoft office.

    the reason i was trying to copy the jar files was that i did not want to attach the complete open office with the project file. I simply wanted the core files for office and the spellcheck files.

    To make the helloworld what i did is the following. first i copied the core jar files in the project folder called lib. and then compliled my program.
    Later i changed the classpath and added the path where the office is installed. Then tried to run the program it said that there are error and if i want to continue and i continued(because the error is that the additional entry in the classpath is pointing to a directory and not to a jar or zip file) but if u ignore the error then it starts running.

    This does not solve what i want to do as still i need the client to have the open office installed before he can use the program.

    I later intended to build a dll out of the open office following the tutorial
    http://www.oooforum.org/forum/viewtopic.phtml?t=32906

    All i need is the spellchecker gui of the open office .. i now know how i can use the api methods where i can use the different spellchecker methods but that means i need to make a front end gui myself with all the code, unlike office where i can invoke just the spellchecker GUI. Could you please help in telling me how i can use the spellchecker gui of openoffice in java or c/c++.

    Thankyou
    Abhinav Mohan

  35. Thank you for this – very useful!

    Another point worth mentioning is that the Bootstrap class is licensed under the LGPL – so if you create your own modified version of it, then that version has to be licensed under the LGPL too. This is only an issue if you’re distributing your code.