[Java] Fermer proprement OOo

Vos meilleures macros et portions de code sont publiées dans cette section.
Aucun support sur une question de programmation ici !

Modérateur : Vilains modOOs

Règles du forum
Aucune question dans cette section !
Celle-ci rassemble les meilleures macros et portions de code. Vous pouvez en revanche commenter ou argumenter le code exposé. Vous pouvez même remercier l'auteur (cela fait toujours plaisir) en indiquant par exemple dans quel cadre ou contexte vous en avez eu l'utilité.
Si vous avez à poster quelque chose, faites-le depuis la section Macros et API et demandez à un modérateur de l'y déplacer.
starm
Membre lOOyal
Membre lOOyal
Messages : 28
Inscription : 20 avr. 2006 21:10

[Java] Fermer proprement OOo

Message par starm »

Pour ceux qui serait interessés, j'ai trouvé la solution pour fermer proprement OpenOffice. Cette question revient souvent sur les forum français et US donc je vous explique la solution.

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();
    }
}
Avec tout ceci vous devriez avoir de quoi fermer normalement votre connection à OOo. Par contre OOo ne se fermera puisqu'il est lancé en tant que serveur, mais en java c'est le seul moyen que j'ai trouvé pour fermer la jvm sans faire un System.exit();

Le secret de ce code est en fait dans le bridge qui représente le fameux MessageDispatcher Thread qui ne se ferme pas

Starm
starm
Membre lOOyal
Membre lOOyal
Messages : 28
Inscription : 20 avr. 2006 21:10

Message par starm »

Pour info au fait on peut retrouver une partie de ce code dans les snippet de openoffice.org :
http://codesnippets.services.openoffice.org/