views:

247

answers:

1

I have a small application that generates three different template documents in OOo Writer. When one of the three "generate" buttons is clicked, this is part of the code that is executed (in C#):

// Connect to OOo
if (componentContext == null)
    componentContext = uno.util.Bootstrap.bootstrap();
XMultiServiceFactory multiServiceFactory =
    (XMultiServiceFactory) componentContext.getServiceManager();
XComponentLoader loader = (XComponentLoader)
    multiServiceFactory.createInstance
        ("com.sun.star.frame.Desktop");

// Initialize class members document, text, and cursor
document = (XTextDocument) loader.loadComponentFromURL
    ("private:factory/swriter", "_blank", 0,
     new PropertyValue[0]);
text = document.getText();
cursor = text.createTextCursor();

The following steps cause a crash:

  1. The user generates a document.
  2. The user closes the document (closing OOo).
  3. The user tries to generate another document.

This exception is thrown:

unoidl.com.sun.star.lang.DisposedException: URP-Bridge: disposed(tid=4) Unexpected connection closure

How do I check to make sure the connection is still open before trying to generate another chart? And how do I reconnect if it has been closed?

Edit: More specifically, this is the complete error message:

Marshaling clicked signal
Exception in Gtk# callback delegate
  Note: Applications can use GLib.ExceptionManager.UnhandledException to handle the exception.
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> unoidl.com.sun.star.lang.DisposedException: URP-Bridge: disposed(tid=4) Unexpected connection closure
  at com.sun.star.bridges.mono_uno.UnoInterfaceProxy.ConstructReturnMessage (Any result, System.Object[] args, uno.Typelib.InterfaceMethodTypeDescription* methodTD, IMethodCallMessage callmsg, Any exception) [0x00000] 
  at com.sun.star.bridges.mono_uno.UnoInterfaceProxy.Invoke (IMessage request) [0x00000] 
  at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke (System.Runtime.Remoting.Proxies.RealProxy rp, IMessage msg, System.Exception& exc, System.Object[]& out_args) [0x00000] 
  --- End of inner exception stack trace ---
  at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] 
  at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] 
  at System.Delegate.DynamicInvokeImpl (System.Object[] args) [0x00000] 
  at System.MulticastDelegate.DynamicInvokeImpl (System.Object[] args) [0x00000] 
  at System.Delegate.DynamicInvoke (System.Object[] args) [0x00000] 
  at GLib.Signal.ClosureInvokedCB (System.Object o, GLib.ClosureInvokedArgs args) [0x00000] 
  at GLib.SignalClosure.Invoke (GLib.ClosureInvokedArgs args) [0x00000] 
  at GLib.SignalClosure.MarshalCallback (IntPtr raw_closure, IntPtr return_val, UInt32 n_param_vals, IntPtr param_values, IntPtr invocation_hint, IntPtr marshal_data) [0x00000] 
   at GLib.ExceptionManager.RaiseUnhandledException(System.Exception e, Boolean is_terminal)
   at GLib.SignalClosure.MarshalCallback(IntPtr raw_closure, IntPtr return_val, UInt32 n_param_vals, IntPtr param_values, IntPtr invocation_hint, IntPtr marshal_data)
   at Gtk.Application.gtk_main()
   at Gtk.Application.Run()
   at TestDrive.MainClass.Main(System.String[] args) in /home/matthew/Dropbox/OpenSBS-mono/TestDrive/Main.cs:line 28

The application was terminated by a signal: SIGHUP

If I get rid of the line if (componentContext == null) (i.e., always try to connect, even when we have already connected), I get a stacktrace accompanied by this message:

=================================================================
Got a SIGSEGV while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries 
used by your application.
=================================================================
A: 

This is just a guess. You could use XComponent.addEventListener and listen for the disposing event.

eg:

class App :  XEventListener
{
    private XComponentLoader m_loader;

    private XComponentLoader Loader
    {
        get
        {
            if (m_loader == null)
            {
                m_loader = (XComponentLoader)multiServiceFactory.createInstance("com.sun.star.frame.Desktop");
                XComponent comp = (XComponent)m_loader;
                comp.addEventListener(this);
            }
            return m_loader;
        }
    }

    private void disposing(EventObject Source)
    {
        m_loader = null;
    }
}
Foole
This doesn't seem to work. I get my error on the line when getting the multiServiceFactory, not when getting the loader, but changing your code to adjust for this doesn't seem to help.One interesting thing is that "disposing" doesn't seem to get called for the componentContext, multiServiceFactory, or loader when I close OOo. Only the document calls disposing (and trying to reconnect still gives me the error).Perhaps what's happening is that the connection is never fully closed, and that's what makes bootstrap give the error. Any ideas?
Matthew