Bug 15542 - Android template throws "Java.Lang.CloneNotSupportedException: Class doesn't implement Cloneable" on API 10 Emulator
Summary: Android template throws "Java.Lang.CloneNotSupportedException: Class doesn't ...
Alias: None
Product: Android
Classification: Xamarin
Component: General ()
Version: 4.10.0.x
Hardware: All All
: High critical
Target Milestone: 4.10.1 (VS2013)
Assignee: Jonathan Pryor
: 15829 15879 ()
Depends on:
Reported: 2013-10-21 09:31 UTC by Atin
Modified: 2013-11-05 11:57 UTC (History)
6 users (show)

Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description Atin 2013-10-21 09:31:34 UTC
Steps to reproduce:
1 Open XS.
2 Create a MFA template
3 Debug or run the application
4 Deploy application on API 10 Emulator

Actual result:
Observe that application throws "Java.Lang.CloneNotSupportedException: Class doesn't implement Cloneable". However application run successfully on above API-10 Emulator like Api-15, Api-17, Api-18

Screen cast:  http://screencast.com/t/PiqmRUBSYf0a

Supplement info: 
Android log: https://gist.github.com/atin360/1f1e014ac4042b2601a0
Application output: https://gist.github.com/atin360/6cf9fa35967dfc9cdb70

Expected result:
Application should run successfully on API 10 Emulator.

Environment info:
Mac Lion 10.7.5 
Windows 8
XS 4.1.7(build 1537)- dbd1c0e5959a2e590aefa16357c85f5514f56e6e
MFA 4.10.01004
Mono 3.2.4 ((no/f163333)

Regression status: REGRESSION, This is working fine with stable MFA 4.8.3-15
Comment 1 Peter Collins 2013-10-21 12:52:28 UTC
I'm able to reproduce this, here's some more logcat information:

OSX 10.9 (Mavericks GM Seed)
Mono 3.2.3 ((no/8d3b4b7)
XS 4.0.13
XA 4.10.1-4 / 25ee86bf
Samsung Galaxy Mini v2.3.4
Comment 2 Jonathan Pryor 2013-10-22 21:48:30 UTC
@Peter: Can you wrap the relevant code within a try/catch and print the stacktrace with Console.WriteLine()? That should show more of the stack.
Comment 3 Peter Collins 2013-10-28 16:35:58 UTC
I was able to reproduce with the latest from 4.10.1 lane (287c5d96)

caught and printed the exception here:
Comment 4 Peter Collins 2013-10-28 16:36:40 UTC
Make that https://gist.github.com/pjcollins/d8c26b91d668d96f0858
Comment 5 Jonathan Pryor 2013-10-28 17:07:12 UTC
For some reason, Activity.OnCreate() is calling Object.clone():

> W/System.err(  613): java.lang.CloneNotSupportedException: Class doesn't implement Cloneable
> W/System.err(  613):    at java.lang.Object.clone(Object.java:155)
> W/System.err(  613):    at scratch.bxc15542.MainActivity.n_onCreate(Native Method)
> W/System.err(  613):    at scratch.bxc15542.MainActivity.onCreate(MainActivity.java:28)
> W/System.err(  613):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
> W/System.err(  613):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
> W/System.err(  613):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
> W/System.err(  613):    at android.app.ActivityThread.access$1500(ActivityThread.java:117)
> W/System.err(  613):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
> W/System.err(  613):    at android.os.Handler.dispatchMessage(Handler.java:99)
> W/System.err(  613):    at android.os.Looper.loop(Looper.java:123)
> W/System.err(  613):    at android.app.ActivityThread.main(ActivityThread.java:3683)
> W/System.err(  613):    at java.lang.reflect.Method.invokeNative(Native Method)
> W/System.err(  613):    at java.lang.reflect.Method.invoke(Method.java:507)
> W/System.err(  613):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
> W/System.err(  613):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)

This makes no sense at all. :-(
Comment 6 Jonathan Pryor 2013-10-28 21:19:16 UTC
I have a repro:

	Log.Info ("*jonp*", "#Getting class...");
	var grefC = JNIEnv.FindClass ("mono/android/view/View_OnClickListenerImplementor");
	Log.Info ("*jonp*", "grefC=0x{0}", grefC.ToString ("x"));
	var lrefI = JNIEnv.CreateInstance (grefC, "()V");
	Log.Info ("*jonp*", "NewObject=0x{0}", lrefI.ToString ("x"));
	JNIEnv.DeleteLocalRef (lrefI);
	lrefI = JNIEnv.AllocObject (grefC);
	Log.Info ("*jonp*", "AllocObject=0x{0}", lrefI.ToString ("x"));
	Log.Info ("*jonp*", "before InvokeConstructor");
	JNIEnv.InvokeConstructor (lrefI, "()V");
	Log.Info ("*jonp*", " after InvokeConstructor");
	JNIEnv.DeleteLocalRef (lrefI);

There are now two ways to create Java instances:

JNIEnv.AllocObject() + JNIEnv.CallVoidMethod()

JNIEnv.NewObject() works, and is what we've always done.

JNIEnv.AllocObject() + JNIEnv.CallVoidMethod() is the new approach introduced with Bug #14999, and apparently API-10 does NOT like this combination.

@PeterC: does this happen on any API-levels _before_ API-10? Or is this just the odd-man out?
Comment 7 Jonathan Pryor 2013-10-28 21:46:39 UTC
Modifying mono/android/view/View_OnClickListenerImplementor so that it does implement Java.Lang.ICloneable _does_ allow the AllocObject()+CallVoidMethod() construction to work.

I'm still trying to figure out _why_ java.lang.Cloneable is required on API-10. Weird bug.
Comment 8 Jonathan Pryor 2013-10-28 22:45:55 UTC
Why? Android bug, of course!


Using JNIEnv.CallNonvirtualVoidMethod() instead of JNIEnv.CallVoidMethod() doesn't make any difference to workaround the Dalvik bug.

Which raises a wonderful question: how to fix this without regressing Bug #14999?

1. Undo Bug #14999's fix, and use some alternate mechanism/hack. We can use JNIEnv.AllocObject()+JNIEnv.CallVoidMethod() when we can drop < API-10 (< API-14?) support. (In...2-4 years?)

2. Modify ACW generation logic so that java.lang.Cloneable is _always_ implemented. This seems incredibly stupid, but it does appear to fix things. (It would need to be _all_ ACWs, as this same issue impacts user code, e.g. `class Demo : Java.Lang.Object {}` and `new Demo()` will blow up.)

I don't like (1). I don't know if (2) will "leak" anywhere, and may need additional checks of some form.
Comment 9 Jonathan Pryor 2013-10-29 21:11:22 UTC
Fixed in master/940136eb and monodroid-4.10.1-branch/33fffb02.

I rejected Comment #8 (1), as it's ebil, and (2) doesn't work (creating a java.lang.String with AllocObject()+CallVoidMethod() results in the same CloneNotSupportedException.

Further investigation (thanks PeterC!) shows that the Dalvik bug was fixed in Honeycomb, so pre-Honeycomb (including API-11) requires the pre-XA 4.10 use of NewObject()/CreateInstance().

Post-Honeycomb, meanwhile, can use AllocObject()+CallVoidMethod(), which has the added semantic cleanup that the (IntPtr, JniHandleOwnership) constructor is now almost never needed (except to subclass Application & Instrumentation). I didn't want to lose this or delay it 2-4 years (or whenever we can drop support for pre-Honeycomb platforms).

The chosen solution is to introduce JNIEnv.StartCreateInstance() and JNIEnv.FinishCreateInstance() method sets.

On Honeycomb+, StartCreateInstance() is AllocObject(), and FinishCreateInstance() is JNIEnv.CallVoidMethod().

Pre-Honeycomb, StartCreateInstance() is NewObject(), and FinishCreateInstance() is a no-op. Pre-Honeycomb thus doesn't get the the semantic cleanup.
Comment 10 Jonathan Pryor 2013-10-30 15:11:53 UTC
*** Bug 15829 has been marked as a duplicate of this bug. ***
Comment 11 Jonathan Pryor 2013-10-31 11:35:45 UTC
*** Bug 15829 has been marked as a duplicate of this bug. ***
Comment 12 Jonathan Pryor 2013-11-01 13:37:30 UTC
*** Bug 15879 has been marked as a duplicate of this bug. ***
Comment 13 Saurabh 2013-11-05 11:57:51 UTC
Today, we have check this issue with latest builds:

Mac and Windows
XS 4.1.13 (build 21)

Now,we are able to deploy android template on API 10 emulator.

Hence, closing this issue.