https://bugs.documentfoundation.org/show_bug.cgi?id=99638

            Bug ID: 99638
           Summary: Attaching listeners makes LibreOffice freeze
           Product: LibreOffice
           Version: 5.1.2.2 release
          Hardware: x86 (IA32)
                OS: Windows (All)
            Status: UNCONFIRMED
          Severity: normal
          Priority: medium
         Component: sdk
          Assignee: libreoffice-bugs@lists.freedesktop.org
          Reporter: lucas.cu...@softexpert.com

I'm using Java UNO API to open documents via LibreOffice. The problem is that
when I try to attach a listener to XTopWindow for example, LibreOffice hangs
forever and I have to kill soffice via task manager. Looks like that when I had
my jar in ${JAVA_INSTALL_PATH}/jre/lib/ext, it worked. As soon as I deleted the
jar and modified my code to add LibreOffice install path to class path at
runtime, it stopped working. I'm using juh-3.2.1.jar, jurt-3.2.1.jar,
ridl-3-2-1.jar and unoil-3.2.1.jar from maven repository. Here is my code:

-------------------------
Main.java
package com.office.test;

import java.io.File;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Properties;

public class Main {
    public static void main(String[] args) {
        Main m = new Main();
        try {
            m.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void start() throws Exception {
        String officePath = "C:\\Program Files (x86)\\LibreOffice 5\\program";
        String filePath = "file:///C:\\Docs\\test.doc";

        URLClassLoader loader = new URLClassLoader(new URL[] { new
File(officePath).toURI().toURL() });
        try {
            addToClassPath(officePath);
        } catch (Exception e) {
            e.printStackTrace();
        }
        Launcher launcher = new Launcher(loader, filePath);
        launcher.start();
    }

    public static void addToClassPath(String s) throws Exception {
        File f = new File(s);
        URL u = f.toURL();
        URLClassLoader urlClassLoader = (URLClassLoader)
ClassLoader.getSystemClassLoader();
        Class urlClass = URLClassLoader.class;
        Method method = urlClass.getDeclaredMethod("addURL", new
Class[]{URL.class});
        method.setAccessible(true);
        method.invoke(urlClassLoader, new Object[]{u});
    }    
}

------------
Launcher.java
package com.office.test;

import java.net.URLClassLoader;
import com.sun.star.awt.XTopWindow;
import com.sun.star.awt.XTopWindowListener;
import com.sun.star.beans.PropertyValue;
import com.sun.star.frame.XComponentLoader;
import com.sun.star.frame.XDesktop;
import com.sun.star.lang.EventObject;
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;

public class Launcher {
    private URLClassLoader loader;
    private String filePath;
    private XComponentContext xContext;
    private XMultiComponentFactory xMCF;
    private XMultiServiceFactory xConfigProvider;
    private XComponent xComponent;
    private XDesktop xDesktop;

    public Launcher(URLClassLoader loader, String filePath) {
        this.loader = loader;
        this.filePath = filePath;
    }

    public void launch() {
        boolean readOnly = false;
        PropertyValue[] props = this.getProperties(readOnly);

        try {
            Bootstrap bootstrap = new Bootstrap();
            this.xContext = bootstrap.bootstrap(loader);
            this.xMCF = this.xContext.getServiceManager();

            final Object configProvider =
this.xMCF.createInstanceWithContext("com.sun.star.configuration.ConfigurationProvider",
this.xContext);
            this.xConfigProvider = (XMultiServiceFactory)
UnoRuntime.queryInterface(XMultiServiceFactory.class, configProvider);

            final Object desktop =
this.xMCF.createInstanceWithContext("com.sun.star.frame.Desktop",
this.xContext);
            this.xDesktop = (XDesktop)
UnoRuntime.queryInterface(XDesktop.class, desktop);

            final XComponentLoader xComponentLoader = (XComponentLoader)
UnoRuntime.queryInterface(XComponentLoader.class, desktop);
            this.xComponent = xComponentLoader.loadComponentFromURL(filePath,
"_default", 0, props);

            XTopWindow topWindow = (XTopWindow)
UnoRuntime.queryInterface(XTopWindow.class,
this.xDesktop.getCurrentFrame().getContainerWindow());
            topWindow.addTopWindowListener(new XTopWindowListener() {
                @Override
                public void disposing(EventObject arg0) {
                }

                @Override
                public void windowOpened(EventObject arg0) {
                }

                @Override
                public void windowNormalized(EventObject arg0) {
                }

                @Override
                public void windowMinimized(EventObject arg0) {
                }

                @Override
                public void windowDeactivated(EventObject arg0) {
                    System.out.println("deac");
                }

                @Override
                public void windowClosing(EventObject arg0) {
                }

                @Override
                public void windowClosed(EventObject arg0) {
                }

                @Override
                public void windowActivated(EventObject arg0) {
                    System.out.println("act");
                }
            });
        } catch (final Exception e) {
            e.printStackTrace();
        }
    }

    private PropertyValue[] getProperties(boolean readOnly) {
        PropertyValue[] props = new PropertyValue[1];        
        props[0] = new PropertyValue();
        props[0].Name = "ReadOnly";
        props[0].Value = new Boolean(readOnly);        
        return props;
    }       
}

------------
Bootstrap.java
package com.office.test;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Random;

import com.sun.star.bridge.UnoUrlResolver;
import com.sun.star.bridge.XUnoUrlResolver;
import com.sun.star.comp.helper.BootstrapException;
import com.sun.star.comp.helper.ComponentContext;
import com.sun.star.comp.helper.ComponentContextEntry;
import com.sun.star.comp.loader.JavaLoader;
import com.sun.star.comp.servicemanager.ServiceManager;
import com.sun.star.container.XSet;
import com.sun.star.lang.XInitialization;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.lib.util.NativeLibraryLoader;
import com.sun.star.loader.XImplementationLoader;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;

public class Bootstrap {
    @SuppressWarnings({"unchecked", "rawtypes"})
    public XComponentContext createInitialComponentContext(Hashtable hashtable)
throws Exception {
        ServiceManager xServiceManager = new ServiceManager();
        XImplementationLoader xImpLoader = (XImplementationLoader)
UnoRuntime.queryInterface(XImplementationLoader.class, new JavaLoader());
        XInitialization xInit = (XInitialization)
UnoRuntime.queryInterface(XInitialization.class, xImpLoader);
        Object[] args = new Object [] { xServiceManager };
        xInit.initialize( args );

        if (hashtable == null) {
            hashtable = new Hashtable<String,Object>(1);
        }

        hashtable.put("/singletons/com.sun.star.lang.theServiceManager", new
ComponentContextEntry( null, xServiceManager ));
        XComponentContext xContext = new ComponentContext(hashtable, null);

        XSet xSet = (XSet) UnoRuntime.queryInterface( XSet.class,
xServiceManager );
        insertBasicFactories( xSet, xImpLoader );

        return xContext;
    }

    private void insertBasicFactories(final XSet xset, final
XImplementationLoader ximplementationloader) throws Exception {
       
xset.insert(ximplementationloader.activate("com.sun.star.comp.loader.JavaLoader",
null, null, null));
       
xset.insert(ximplementationloader.activate("com.sun.star.comp.urlresolver.UrlResolver",
null, null, null));
       
xset.insert(ximplementationloader.activate("com.sun.star.comp.bridgefactory.BridgeFactory",
null, null, null));
       
xset.insert(ximplementationloader.activate("com.sun.star.comp.connections.Connector",
null, null, null));
       
xset.insert(ximplementationloader.activate("com.sun.star.comp.connections.Acceptor",
null, null, null));
    }

    public final XComponentContext bootstrap(URLClassLoader loader) throws
Exception {
        XComponentContext xcomponentcontext = null;
        try {
            final XComponentContext xcomponentcontext1 =
this.createInitialComponentContext(null);
            if (xcomponentcontext1 == null) {
                throw new BootstrapException("no local component context!");
            }

            final String s =
System.getProperty("os.name").startsWith("Windows") ? "soffice.exe" :
"soffice";
            final File officeExecutable =
NativeLibraryLoader.getResource(Bootstrap.class.getClassLoader(), s);
            if (officeExecutable == null) {
                throw new BootstrapException("no office executable found!");
            }

            final String unoName = this.getUnoName();
            List<String> officeArguments =
this.getOfficeArguments(officeExecutable, loader, unoName);

            Runtime.getRuntime().exec(officeArguments.toArray(new
String[officeArguments.size()]));

            final XMultiComponentFactory xmulticomponentfactory =
xcomponentcontext1.getServiceManager();
            if (xmulticomponentfactory == null) {
                throw new BootstrapException("no initial service manager!");
            }

            final XUnoUrlResolver xunourlresolver =
UnoUrlResolver.create(xcomponentcontext1);
            final String unoConnection = this.getUnoConnectionUrl(unoName);

            do {
                try {
                    Object obj = xunourlresolver.resolve(unoConnection);
                    xcomponentcontext = (XComponentContext)
UnoRuntime.queryInterface(com.sun.star.uno.XComponentContext.class, obj);
                    break;
                } catch (final Exception noconnectexception) {                  
                    Thread.currentThread();
                    Thread.sleep(1000L);
                }
            } while (true);
        } catch (Exception e) {
            throw e;
        } 

        return xcomponentcontext;
    }

    private List<String> getOfficeArguments(File officeExecutable,
URLClassLoader loader, String unoName) {
        List<String> arguments = new ArrayList<String>();
        arguments.add(officeExecutable.getPath());
        arguments.add("-nologo");
        arguments.add("-nodefault");
        arguments.add("-norestore");
        arguments.add("-nocrashreport");
        arguments.add("-nolockcheck");
        arguments.add("-nofirststartwizard");
        arguments.add("-accept=pipe,name=" + unoName + ";urp;");
        arguments.add("--nologo");
        arguments.add("--nodefault");
        arguments.add("--norestore");
        arguments.add("--nocrashreport");
        arguments.add("--nolockcheck");
        arguments.add("--nofirststartwizard");
        arguments.add("--accept=pipe,name=" + unoName + ";urp;");
        return arguments;
    }

    private String getUnoName() {
        return "uno" + Long.toString(new Random().nextLong() &
0x7fffffffffffffffL);
    }

    private String getUnoConnectionUrl(String unoName) {
         return "uno:pipe,name=" + unoName +
";urp;StarOffice.ComponentContext";
    }

}

-- 
You are receiving this mail because:
You are the assignee for the bug.
_______________________________________________
Libreoffice-bugs mailing list
Libreoffice-bugs@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-bugs

Reply via email to