La solution que j'ai trouvé nécessite d'attaquer OOo par un socket et non par le Desktop.
Voici le code d'ouverture et de fermeture d'à peu près tout ce dont on peux avoir besoin (enfin je pense que ca suffit dans la majorité des cas).
Code : Tout sélectionner
/*
* Created on 23 avr. 2006
*
* To change the template for this generated file go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
package fr.sigma.openoffice.connection;
import com.sun.star.beans.XPropertySet;
import com.sun.star.bridge.XBridge;
import com.sun.star.bridge.XBridgeFactory;
import com.sun.star.comp.helper.Bootstrap;
import com.sun.star.connection.XConnection;
import com.sun.star.connection.XConnector;
import com.sun.star.frame.XComponentLoader;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
/**
* @author vince
* Création d'une connexion à OOo afin d'avoir le composant
* XBridge et de pouvoir le fermer une fois les traitements effectués.
*
* Sans ceci, la connexion ne se libère pas et OOo prend plus de ressources que
* nécessaire.
*
*/
public class OOoConnectionOpenOffice
{
private XMultiComponentFactory mxMCF;
private XComponentContext mxComponentContext;
private XMultiServiceFactory mxMSF;
private XBridge bridge = null;
private XComponentLoader officeComponentLoader;
public static final String DEFAULT_CONNECTION_STRING = "socket,host=localhost,port=8200";
/**
* Ouvre la connexion avec OOo en construisant les composants suivants :
* XMultiComponentFactory mxMCF; XComponentContext mxComponentContext;
* XMultiServiceFactory mxMSF; XBridge bridge; qui serve au reste de
* l'application à interagir avec OOo.
*
*/
public void openConnectionOpenOffice()
{
try
{
// Création du context initial avec OOo
mxComponentContext = Bootstrap.createInitialComponentContext(null);
if (mxComponentContext == null)
System.out.println("mxComponentContext is null");
// Création de l'objet de type Connector permettant de créer une
// connection entre java et OOo
Object x = mxComponentContext.getServiceManager().createInstanceWithContext("com.sun.star.connection.Connector", mxComponentContext);
XConnector xConnector = (XConnector) UnoRuntime.queryInterface(XConnector.class, x);
// Création de la connection entre java et OOo
XConnection connection = xConnector.connect(DEFAULT_CONNECTION_STRING);
if (connection == null)
System.out.println("Connection is null");
// Création du bridge, étape très importante pour pouvoir
// fermer OOo sans avoir à faire un system.exit();
// Le bridge est créé suivant la connection connection et le
// protocol de discussion urp
x = mxComponentContext.getServiceManager().createInstanceWithContext("com.sun.star.bridge.BridgeFactory", mxComponentContext);
XBridgeFactory xBridgeFactory = (XBridgeFactory) UnoRuntime.queryInterface(XBridgeFactory.class, x);
if (xBridgeFactory == null)
System.out.println("bridge factoriy is null");
// this is the bridge that you will dispose
bridge = xBridgeFactory.createBridge("", "urp", connection, null);
// Création de la XMultiComponentFactory qui permettra d'avoir
// aux services tels que le mailmerge
XComponent xComponent = (XComponent) UnoRuntime.queryInterface(XComponent.class, bridge);
if (bridge == null)
System.out.println("Bridge null");
// get the remote instance
x = bridge.getInstance("StarOffice.ServiceManager");
// Query the initial object for its main factory interface
mxMCF = (XMultiComponentFactory) UnoRuntime.queryInterface(XMultiComponentFactory.class, x);
// retrieve the component context (it's not yet exported from the
// office)
// Query for the XPropertySet interface.
XPropertySet xProperySet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, mxMCF);
// Get the default context from the office server.
Object oDefaultContext = xProperySet.getPropertyValue("DefaultContext");
// Query for the interface XComponentContext.
mxComponentContext = (XComponentContext) UnoRuntime.queryInterface(XComponentContext.class, oDefaultContext);
mxMCF = mxComponentContext.getServiceManager();
// now create the desktop service
// NOTE: use the office component context here !
Object oDesktop = mxMCF.createInstanceWithContext(
"com.sun.star.frame.Desktop", mxComponentContext );
officeComponentLoader = ( XComponentLoader )
UnoRuntime.queryInterface( XComponentLoader.class, oDesktop );
// Query for an XMultiServiceFactory instance from the global
// service manager
if (mxMSF == null)
{
mxMSF = (XMultiServiceFactory) UnoRuntime.queryInterface(XMultiServiceFactory.class, mxMCF);
}
}
catch (Exception exception)
{
System.err.println(exception);
}
}
/**
* Ferme la connection à OOo en créant un composant à partir du bridge et en
* appelant la méthode dispose() dessus. Une fois ce composant fermé, OOo
* peut se fermer normalement et la jvm se termine.
*/
public void closeConnectionOpenOffice()
{
XComponent xcomponent = (XComponent) UnoRuntime.queryInterface(XComponent.class, bridge);
// Closing the bridge
xcomponent.dispose();
}
}
Le secret de ce code est en fait dans le bridge qui représente le fameux MessageDispatcher Thread qui ne se ferme pas
Starm