[Mono-bugs] [Bug 658698] System.MissingMethodException: No constructor found for **classname**

bugzilla_noreply at novell.com bugzilla_noreply at novell.com
Fri Dec 10 15:38:40 EST 2010


https://bugzilla.novell.com/show_bug.cgi?id=658698

https://bugzilla.novell.com/show_bug.cgi?id=658698#c2


Jonathan Pryor <jpryor at novell.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jpryor at novell.com

--- Comment #2 from Jonathan Pryor <jpryor at novell.com> 2010-12-10 20:38:39 UTC ---
It would be useful to have an actual sample...

I have a conjecture: it's the GC fault, mostly because we have a separate bug
Mike is fixing that looks similar to this.

Specifically, consider this harmless-looking code:

    instance.Method(new MemoryStream(data));

Previously, the C# wrapper for Method() would be akin to:

    JNIEnv.CallObjectMethod(instance.Handle, new JValue (new InputStreamAdapter
(stream).Handle));

this _looks_ fine...  until a GC hits _after_ the InputStreamAdapter.Handle
property has been accessed, but _before_ JNIEnv.CallObjectMethod() has been
invoked.

Result: there are no managed references to the InputStreamAdapter type, so it's
considered as garbage, and since the handle hasn't been stored in Java yet, the
managed InputStreamAdapter reference isn't kept alive, and thus is collected.

The result is that when the Java-side instance.method() method executes and
invokes a method on the InputStream it was given, it'll re-enter MonoDroid,
MonoDroid will lookup the java handle to find the managed object it corresponds
to, FAIL to find the managed object, and try to (re)create a managed instance.

This promptly fails because InputStreamAdapter doesn't have the (IntPtr)
constructor that is required, and things go titsup shortly afterward.

The fix is to make sure the managed instance is kept alive through the call:

    InputStreamAdapter __a = new InputStreamAdapter(stream);
    JNIEnv.CallObjectMethod(instance.Handle, __a.Handle);
    __a.Dispose();

With all that as background, my CONJECTURE is that your View isn't being
strongly referenced during a method call, and thus is getting prematurely
collected (as it gets collected _before_ the Java code is invoked).

Assuming this conjecture is correct, the only fix is to create strong ref for
the instance to ensure it lives long enough.  The question, then, is where
should the strong ref exists?

 1. Within the MonoDroid-generated wrappers, which is the fix for the above
mentioned InputStreamAdapter issue;
 2. Within developer code.

The answer may well be (2), but if it's (1) we need to know the types and
members involved, i.e. have a full working sample so that we can diagnoe the
issue.

On a related note, I'd like to see your PostDelayed() demo code you mentioned
on IRC yesterday, as that (again) appears to be the same issue, except that
shouldn't be happening as we strongly ref the internal IRunnable instances to
ensure they don't get collected, so something is going badly wrong there.

-- 
Configure bugmail: https://bugzilla.novell.com/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.


More information about the mono-bugs mailing list