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

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

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( "os.name" ).startsWith( "Windows" ) ? "soffice.exe" : "soffice";
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[] {
    new File(ooBaseDirectory).toURL()
};
URLClassLoader loader = new URLClassLoader(jarList);

and pass it on to the bootloader method like this

XComponentContext xContext = (XComponentContext)bootstrap(loader);

and OOo will start without a complaint
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 = "C:\\Program Files\\OpenOffice.org 2.0\\program";

while on Debian Linux this should be

String ooBaseDirectory = "/usr/lib/openoffice/program";

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.

 

36 Comments

  1. Wouter van Reeven April 1, 2009
  2. martin joseph March 12, 2009
  3. tanalyw February 24, 2009
  4. yanot November 14, 2008
  5. Vishal October 27, 2008
  6. xman September 25, 2008
  7. site admin June 2, 2008
  8. sean May 29, 2008
  9. hol.sten February 3, 2008
  10. Ichbinich February 3, 2008
  11. Wouter van Reeven January 15, 2008
  12. Heiko January 11, 2008
  13. Wouter van Reeven December 27, 2007
  14. Tobias Pires November 29, 2007
  15. Matthias Roscher November 6, 2007
  16. GroverBlue October 31, 2007
  17. Wouter van Reeven September 30, 2007
  18. Polly September 18, 2007
  19. Wouter van Reeven September 14, 2007
  20. Wouter van Reeven September 14, 2007
  21. Polly September 14, 2007
  22. vbms August 22, 2007
  23. vbms August 22, 2007
  24. srinivas June 29, 2007
  25. Sandro April 11, 2007
  26. Chunyun Zhao March 17, 2007
  27. Wouter van Reeven October 31, 2006
  28. frank October 31, 2006
  29. Wouter van Reeven September 21, 2006
  30. Aloizio September 20, 2006
  31. Wouter van Reeven September 11, 2006
  32. Pieter-Jan September 8, 2006
  33. Abhinav August 31, 2006
  34. Wouter van Reeven August 31, 2006
  35. Abhinav August 31, 2006
  36. Inigo August 31, 2006