Bug 99638 - Attaching listeners makes LibreOffice freeze
Summary: Attaching listeners makes LibreOffice freeze
Status: RESOLVED INSUFFICIENTDATA
Alias: None
Product: LibreOffice
Classification: Unclassified
Component: sdk (show other bugs)
Version:
(earliest affected)
5.1.2.2 release
Hardware: x86 (IA32) Windows (All)
: medium normal
Assignee: Not Assigned
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-05-02 20:38 UTC by Lucas da Cunha
Modified: 2018-01-29 10:35 UTC (History)
2 users (show)

See Also:
Crash report or crash signature:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Lucas da Cunha 2016-05-02 20:38:31 UTC
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";
    }
    
}
Comment 1 Buovjaga 2016-05-13 06:41:13 UTC
Could you try to get a trace https://wiki.documentfoundation.org/How_to_get_a_backtrace_with_WinDbg
maybe !analyze -v -hang
Comment 2 Xisco Faulí 2017-06-19 12:14:12 UTC Comment hidden (obsolete)
Comment 3 QA Administrators 2018-01-02 10:14:20 UTC Comment hidden (obsolete)
Comment 4 QA Administrators 2018-01-29 10:35:19 UTC
Dear Bug Submitter,

Please read this message in its entirety before proceeding.

Your bug report is being closed as INSUFFICIENTDATA due to inactivity and
a lack of information which is needed in order to accurately
reproduce and confirm the problem. We encourage you to retest
your bug against the latest release. If the issue is still
present in the latest stable release, we need the following
information (please ignore any that you've already provided):

a) Provide details of your system including your operating
   system and the latest version of LibreOffice that you have
   confirmed the bug to be present

b) Provide easy to reproduce steps – the simpler the better

c) Provide any test case(s) which will help us confirm the problem

d) Provide screenshots of the problem if you think it might help

e) Read all comments and provide any requested information

Once all of this is done, please set the bug back to UNCONFIRMED
and we will attempt to reproduce the issue. Please do not:

a) respond via email 

b) update the version field in the bug or any of the other details
   on the top section of our bug tracker

Warm Regards,
QA Team

MassPing-NeedInfo-20180129