- juh.jar
- jurt.jar
- officebean.jar
- ridl.jar
- unoil.jar
I created another module with a single TopComponent, and add this snippet:
private OOoBean oo;
@Override
public void componentOpened() {
try {
add(oo = new OOoBean());
oo.loadFromURL("private:factory/swriter", null);
oo.aquireSystemWindow();
} catch (Exception ex) {
Exceptions.printStackTrace(ex);
}
}
But, this will NOT work... If you try to run it, an exception will be thrown, because OOo libs (.DLL/.SO) will not be found. They only exists in OOo install folder, and are automagically found by OOo classes - only if they aren't moved from the "classes" folder in OOo installation.
The workaround is a couple of classes in OOo SDK and The Ultimate Blackmagic(TM) - patent pending:
- Grab odk / source / com / sun / star / lib / loader from OOo's CVS and add it to integration module.
- Add unowinreg.dll to Windows Path (if you are on Linux, skip this step).
- Alter Loader.java and add this after line 205 (after "UnoInfo" call):
vec.add(new File(fClassesDir, "officebean.jar").toURL());
This part of the magick adds "officebean" to classpath. Here lies OOoBean, and is optional if you are only using UNO interfaces. Other JARs are correctly listed by UnoInfo. - Now, the ugliest part of the evil potion: create a Facade. Using OOoBean directly will lead to some ugly ClassLoader conflicts. I've no time to fix this, but the following works:
public static Container buildOOoBean() {
return (Container) Loader.getCustomLoader().
loadClass("com.sun.star.comp.beans.OOoBean").
newInstance();
}
public static void showOOoBean(Container oo) {
Class c = oo.getClass().
getClassLoader().
loadClass("com.sun.star.beans.PropertyValue");
Class ca = Array.newInstance(c, 0).getClass();
Method m = oo.getClass().
getMethod("loadFromURL", String.class, ca);
m.invoke(oo, "private:factory/swriter", null);
oo.getClass().
getMethod("aquireSystemWindow").invoke(oo);
} - Back to the TC, I use "buildOOoBean" in ComponentOpened and "showOOoBean" AFTER the component is shown (does not work otherwise).
Yes, it is the purest evilness, but works (with some bugs):
This level of indirection is mandatory, because client module's ClassLoader is different than integration module's. If I do "OOoBean oo = new OOoBean()", the declaration and instantiation will try to use the JARs bundled. Since they don't lie on OOo install folder, the libraries will not be found. If I use "oo = (OOoBean) Loader.getCustomLoader().getClass("...").newInstance()", the "OOoBean" class from declaration will NOT be the same as the class instantiated. If you ever worked with JavaEE 4 and JSF/Struts/etc, you know that same classes from different ClassLoaders throws ClassCastException.
OOo works really well with Java, but NetBeans ClassLoader is "self-contained" (i.e. your bundled application must include EVERYTHING you use). This is a very nice architecture, but does not help if you if you need to interface with external applications.