Bug 22155 - GoogleApiClientBuilder.AddApi(Api, Object) throws Java.Lang.NoSuchMethodError Exception
Summary: GoogleApiClientBuilder.AddApi(Api, Object) throws Java.Lang.NoSuchMethodError...
Status: RESOLVED FIXED
Alias: None
Product: Android
Classification: Xamarin
Component: Bindings ()
Version: 4.14.0
Hardware: Macintosh Mac OS
: Normal normal
Target Milestone: 5.1
Assignee: dean.ellis
URL:
: 24551 ()
Depends on:
Blocks:
 
Reported: 2014-08-17 21:55 UTC by ardadevelioglu@gmail.com
Modified: 2015-03-12 17:51 UTC (History)
12 users (show)

Tags: GoogleApiClientBuilder AddApi NoSuchMethodError
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:
Status:
RESOLVED FIXED

Description ardadevelioglu@gmail.com 2014-08-17 21:55:35 UTC
Problem: GoogleApiClient.AddApi(Api, Object) throws Java.Lang.NoSuchMethodError exception. In Google Android SDK the method is GoogleApiClient.Builder	addApi(Api<? extends Api.ApiOptions.NotRequiredOptions> api)
Comment 1 ardadevelioglu@gmail.com 2014-08-17 21:59:54 UTC
Sorry, accidentally send the bug while typing. Re-writing the description:

Problem: GoogleApiClient.Builder.AddApi(Api, Object) throws Java.Lang.NoSuchMethodError exception. In Google Android SDK the method is GoogleApiClient.Builder.addApi(Api<? extends Api.ApiOptions.NotRequiredOptions> api)
Comment 2 ardadevelioglu@gmail.com 2014-08-17 22:25:20 UTC
Sorry, have no idea what is going on! :/ Final draft:

Problem
========
GoogleApiClientBuilder.AddApi(Api, Object) throws Java.Lang.NoSuchMethodError exception. In Google Android SDK the method is described as <O extends Api.ApiOptions.HasOptions> GoogleApiClient.Builder.addApi(Api<O> api, O options) The thrown exception and repro code is below.
I have Xamarin.GooglePlayServicesKitKat.19.0.0 lib included.
I also tried on Xamarin.Android Beta 4.16.0.12 and Alpha 4.17.0.10, stil repros.
Reference: https://developer.android.com/reference/com/google/android/gms/common/api/GoogleApiClient.Builder.html

Exception
==========
Java.Lang.NoSuchMethodError: no method with name='addApi' signature='(Lcom/google/android/gms/common/api/Api;Ljava/lang/Object;)Lcom/google/android/gms/common/api/GoogleApiClient$Builder;' in class Lcom/google/android/gms/common/api/GoogleApiClient$Builder;
  at Android.Runtime.JNIEnv.GetMethodID (intptr,string,string) [0x00066] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.14-series/8e79d361/source/monodroid/src/Mono.Android/src/Runtime/JNIEnv.g.cs:161
  at at Android.Gms.Common.Apis.GoogleApiClientBuilder.AddApi (Android.Gms.Common.Apis.Api,Java.Lang.Object) <IL 0x00023, 0x000db>
  at castp.ChromecastFragment.DeviceSelected (Android.Gms.Cast.CastDevice) [0x00042] in /Users/ad/Development/Projects/CastP/Solution/CastP.Android/ChromecastFragment.cs:118
  at castp.ChromecastFragment/MyMediaRouterCallback.OnRouteSelected (Android.Support.V7.Media.MediaRouter,Android.Support.V7.Media.MediaRouter/RouteInfo) [0x00029] in /Users/ad/Development/Projects/CastP/Solution/CastP.Android/ChromecastFragment.cs:147
  at at Android.Support.V7.Media.MediaRouter/Callback.n_OnRouteSelected_Landroid_support_v7_media_MediaRouter_Landroid_support_v7_media_MediaRouter_RouteInfo_ (intptr,intptr,intptr,intptr) <IL 0x0001c, 0x00147>
  at at (wrapper dynamic-method) object.6f66f0bb-8fbc-45a5-8dda-3283b6ee3222 (intptr,intptr,intptr,intptr) <IL 0x0001d, 0x0004b>
  at --- End of managed exception stack trace ---
  at java.lang.NoSuchMethodError: no method with name='addApi' signature='(Lcom/google/android/gms/common/api/Api;Ljava/lang/Object;)Lcom/google/android/gms/common/api/GoogleApiClient$Builder;' in class Lcom/google/android/gms/common/api/GoogleApiClient$Builder;
  at at castp.ChromecastFragment_MyMediaRouterCallback.n_onRouteSelected(Native Method)
  at at castp.ChromecastFragment_MyMediaRouterCallback.onRouteSelected(ChromecastFragment_MyMediaRouterCallback.java:36)
  at at android.support.v7.media.MediaRouter$GlobalMediaRouter$CallbackHandler.invokeCallback(MediaRouter.java:2125)
  at at android.support.v7.media.MediaRouter$GlobalMediaRouter$CallbackHandler.handleMessage(MediaRouter.java:2075)
  at at android.os.Handler.dispatchMessage(Handler.java:99)
  at at android.os.Looper.loop(Looper.java:137)
  at at android.app.ActivityThread.main(ActivityThread.java:5103)
  at at java.lang.reflect.Method.invokeNative(Native Method)
  at at java.lang.reflect.Method.invoke(Method.java:525)
  at at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
  at at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
  at at dalvik.system.NativeStart.main(Native Method)


Repro Code
===========
// Info: Calling method with null is enough to repro the bug. The expected way to send a CastClass.CastOptions.Builder.Build() call

            // CastClass.CastOptions.Builder apiOptionsBuilder = CastClass.CastOptions.InvokeBuilder(device, mCastClientListener);

            var builder = new GoogleApiClientBuilder(Activity);
            builder = builder.AddApi(CastClass.Api, null /* apiOptionsBuilder.Build() */);
            builder = builder.AddConnectionCallbacks(this);
            builder = builder.AddOnConnectionFailedListener(this);
            mApiClient = builder.Build();
Comment 4 Atsushi Eno 2014-08-18 05:23:04 UTC
binding generator has fix to generate the fixed GooglePlayServices component.

dalexsoto: the components needs to be regenerated using the fixed version of monodroid (but you might want to wait for it being released).

[master b73666c]
Comment 7 Udham Singh 2014-09-23 09:14:08 UTC
I have checked this issue with XA 4.18.0-32 and I am also getting this issue with XA 4.18.0-32 + XS 5.5.(build 204).

I have implemented the code provided in comment 2 and run the application on android device(Nexus 4 android version 4.4.4) and got the issue.

Screencast  : http://www.screencast.com/t/T6vA4YrQC

Application Output : https://gist.github.com/Udham1/d560a03dac831e37425c

Environment Info :

=== Xamarin Studio ===

Version 5.5 (build 204)
Installation UUID: ce927b2a-2c07-44c5-b186-09cfdafba6dc
Runtime:
	Mono 3.10.0 ((detached/ac51002)
	GTK+ 2.24.23 (Raleigh theme)

	Package version: 310000016

=== Apple Developer Tools ===

Xcode 6.0.1 (6528)
Build 6A317

=== Xamarin.iOS ===

Version: 8.2.0.177 (Business Edition)
Hash: 3b73f2a
Branch: 
Build date: 2014-09-19 00:21:20-0400

=== Xamarin.Mac ===

Version: 1.11.0.1 (Business Edition)

=== Xamarin.Android ===

Version: 4.18.0.32 (Business Edition)
Android SDK: /Users/xamarin76/Desktop/android-sdk-macosx
	Supported Android versions:
		1.6    (API level 4)
		2.1    (API level 7)
		2.2    (API level 8)
		2.3    (API level 10)
		3.0    (API level 11)
		3.1    (API level 12)
		3.2    (API level 13)
		4.0    (API level 14)
		4.0.3  (API level 15)
		4.1    (API level 16)
		4.2    (API level 17)
		4.3    (API level 18)
		4.4    (API level 19)
		4.4.87 (API level 20)
		4.5    (API level 21)
Java SDK: /usr
java version "1.7.0_65"
Java(TM) SE Runtime Environment (build 1.7.0_65-b17)
Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)

=== Build Information ===

Release ID: 505000204
Git revision: 2affa3acc16487d4f8fb5cb33c49e2423469091e
Build date: 2014-09-23 07:14:56-04
Xamarin addins: c31fea2f959659225466adef1c0793a8d7eebcef

=== Operating System ===

Mac OS X 10.9.4
Darwin Xamarin76s-Mac-mini.local 13.3.0 Darwin Kernel Version 13.3.0
    Tue Jun  3 21:27:35 PDT 2014
    root:xnu-2422.110.17~1/RELEASE_X86_64 x86_64
Comment 8 Atsushi Eno 2014-09-24 03:38:03 UTC
You have to use GooglePlayServices component which was built with 4.18 or later. And I have no idea how you can know whether your GPS is built accordingly or not. The component team would know.
Comment 9 Hans Müller 2014-10-02 01:44:38 UTC
Well I don´t get it. This site:

http://developer.xamarin.com/releases/android/xamarin.android_4/xamarin.android_4.18/

 tells me that this bug was solved in the lates build 4.18. I just updated my Visual Studio to use the latest alpha version (4.18.0.32) But I´m still getting the NoSuchMethodErrorException...

Any ideas?
Comment 10 Atsushi Eno 2014-10-03 02:42:43 UTC
Sorry but the situation may be confusing for you. Xamarin.Android 4.18 does not automagically fix the issue for *you*.

Our component team needed 4.18 version of Xamarin.Android to build a valid Google Play Services component.

Until they could build, verify and ship the valid component, it won't be publicly available.
Comment 12 Atsushi Eno 2014-10-06 06:58:03 UTC
Looks like the latest version uncovered another type resolution issue on such types that have some sort of recursive definition (or whatever similarly complicated). I will investigate that too.
Comment 13 Atsushi Eno 2014-10-16 22:18:14 UTC
@Dean: it is the generator bug I was stuck regarding recursive type resolution. I'm just reassigning it to you as I'm stuck with other stuff...
Comment 15 Jon Dick 2014-10-27 12:18:06 UTC
We have a workaround that should make this method functional in the interim.

You can download the assemblies for the temporary workaround here:
https://www.dropbox.com/s/013v2kj1arqeotf/GooglePlayServices-AddApi-Fix.zip?dl=0

This link will go away once we publish a fixed version on NuGet and the
Component store.
Comment 16 Jeremy Kolb 2014-11-20 14:48:31 UTC
Has this been fixed yet?
Comment 17 Jon Dick 2014-11-20 22:22:29 UTC
It's not in NuGet yet, as there were some additional changes google has made to the API. 

They are also releasing yet another update to Google Play Services any day now.  We will focus on getting that bound and out the door quickly instead.  Please use the workaround binary posted here for now.
Comment 18 Dimitar Dobrev 2014-11-22 11:37:00 UTC
I get:

Java.Lang.NoSuchMethodError: no method with name='setCustomDimension' signature='(ILjava/lang/String;)Ljava/lang/Object;' in class Lcom/google/android/gms/analytics/HitBuilders$HitBuilder;

I cannot use the component at all! The libraries from DropBox fail too. When is this going to be fixed?
Comment 19 Dimitar Dobrev 2014-11-22 14:35:48 UTC
The 'setCustomDimension' is, I believe, a bug in your generator (I don't know if it's been fixed). I'll try explaining the problem.

The method is generic, and returns an object of its placeholder type (T). Because of the limitations when wrapping generics, you use Java.Lang.Object:

[Register("setCustomDimension", "(ILjava/lang/String;)Ljava/lang/Object;", "GetSetCustomDimension_ILjava_lang_String_Handler")]
public virtual Object SetCustomDimension(int index, string dimension)
{
	if (HitBuilders.HitBuilder.id_setCustomDimension_ILjava_lang_String_ == IntPtr.Zero)
	{
		HitBuilders.HitBuilder.id_setCustomDimension_ILjava_lang_String_ = JNIEnv.GetMethodID(HitBuilders.HitBuilder.class_ref, "setCustomDimension", "(ILjava/lang/String;)Ljava/lang/Object;");
	}
	...
	if (base.GetType() == this.get_ThresholdType())
	{
		...
	}
	else
	{
		@object = Object.GetObject<Object>(JNIEnv.CallNonvirtualObjectMethod(base.get_Handle(), this.get_ThresholdClass(), JNIEnv.GetMethodID(this.get_ThresholdClass(), "setCustomDimension", "(ILjava/lang/String;)Ljava/lang/Object;"), new JValue[]
		{
			...
		}), 1);
	}
	...
}


However, the T in HitBuilder, as evident by https://developer.android.com/reference/com/google/android/gms/analytics/HitBuilders.HitBuilder.html, also inherits from HitBuilder:

com.google.android.gms.analytics.HitBuilders.HitBuilder<T extends com.google.android.gms.analytics.HitBuilders.HitBuilder>

The actual Java signature apparently uses for the compilation of the placeholder the most derived type it can get, and that is com.google.android.gms.analytics.HitBuilders.HitBuilder rather than Java.Lang.Object. So, using Reflector and ReflexIL, I replaced the occurences of the latter with the former:

[Register("setCustomDimension", "(ILjava/lang/String;)Lcom/google/android/gms/analytics/HitBuilders$HitBuilder;", "GetSetCustomDimension_ILjava_lang_String_Handler")]
public virtual Object SetCustomDimension(int index, string dimension)
{
    ...
    if (id_setCustomDimension_ILjava_lang_String_ == IntPtr.Zero)
    {
        id_setCustomDimension_ILjava_lang_String_ = JNIEnv.GetMethodID(class_ref, "setCustomDimension", "(ILjava/lang/String;)Lcom/google/android/gms/analytics/HitBuilders$HitBuilder;");
    }
    IntPtr ptr = JNIEnv.NewString(dimension);
    if (base.GetType() == this.ThresholdType)
    {
        ...
    }
    else
    {
        ...
        obj2 = Object.GetObject<Object>(JNIEnv.CallNonvirtualObjectMethod(base.Handle, this.ThresholdClass, JNIEnv.GetMethodID(this.ThresholdClass, "setCustomDimension", "(ILjava/lang/String;)Lcom/google/android/gms/analytics/HitBuilders$HitBuilder;"), valueArray2), JniHandleOwnership.TransferLocalRef);
    }
    ...
}

I haven't checked if it works this way yet but it doesn't crash for sure.
Comment 20 Dimitar Dobrev 2014-11-25 08:32:16 UTC
Any comment on my remarks? Should I file a new bug for that?
Comment 21 Jon Dick 2014-11-25 09:27:23 UTC
Thanks Dimitar, this basically sums up that issue.  The generator is generating the methods with the wrong JNI signature.  This is very similar to the last issue.

No need to file a new bug, we are actively working on updating the binding to the latest Google Play Services, as well as fixing this error.

Thanks!
Comment 22 dean.ellis 2014-11-25 11:01:47 UTC
I have managed to replicate this with a test case. It looks like its the nested types which are causing the problem here. I'll start looking at generator to fix this up
Comment 23 Atsushi Eno 2014-11-25 11:10:19 UTC
Yes, comment #19 is the detailed / friendly explanation of my comment #12.
Comment 24 dean.ellis 2014-11-26 17:44:13 UTC
The actual problem turned out to be in the jar2xml tool. It was not correctly emitting the constraints for nested types

Fixed in jar2xml/master/f4bed128fc
Comment 25 Dimitar Dobrev 2014-11-26 17:47:32 UTC
Dean, excellent news! When can we expect the regenerated bindings to be uploaded to the Xamarin Component Store?
Comment 26 Jon Dick 2014-11-27 11:53:28 UTC
There will be an update next week!
Comment 27 Dimitar Dobrev 2014-11-29 06:10:18 UTC
Jon, this is great news.
Furthermore, I believe this bug was the cause for https://bugzilla.xamarin.com/show_bug.cgi?id=24753 and https://bugzilla.xamarin.com/show_bug.cgi?id=24551 so those should now be fixed as well.
Comment 28 dean.ellis 2014-11-29 06:31:09 UTC
*** Bug 24551 has been marked as a duplicate of this bug. ***
Comment 29 Dimitar Dobrev 2014-12-16 18:24:19 UTC
Jon, I can see the newer Google Play Services component has been updated in NuGet: https://www.nuget.org/packages/Xamarin.GooglePlayServices/. However, we need to support Android 2.3.7, so could you please update the Froyo component (https://www.nuget.org/packages/Xamarin.GooglePlayServicesFroyo/) as well?
Comment 30 Dimitar Dobrev 2015-03-08 12:42:32 UTC
Hi all,

I am wrapping Google Play Services myself because I hit the DEX limit and I need to exclude some modules (https://medium.com/@rotxed/dex-skys-the-limit-no-65k-methods-is-28e6cb40cf71). So I can see that your generator still yields incorrect Java.Lang.Object signatures such as:

			// Metadata.xml XPath method reference: path="/api/package[@name='com.google.android.gms.analytics']/class[@name='HitBuilders.HitBuilder']/method[@name='setCustomDimension' and count(parameter)=2 and parameter[1][@type='int'] and parameter[2][@type='java.lang.String']]"
			[Register ("setCustomDimension", "(ILjava/lang/String;)Ljava/lang/Object;", "GetSetCustomDimension_ILjava_lang_String_Handler")]
			public virtual global::Com.Google.Android.Gms.Analytics.HitBuilders.HitBuilder SetCustomDimension (int p0, string p1)
			{
				if (id_setCustomDimension_ILjava_lang_String_ == IntPtr.Zero)
					id_setCustomDimension_ILjava_lang_String_ = JNIEnv.GetMethodID (class_ref, "setCustomDimension", "(ILjava/lang/String;)Ljava/lang/Object;");
				IntPtr native_p1 = JNIEnv.NewString (p1);

				global::Com.Google.Android.Gms.Analytics.HitBuilders.HitBuilder __ret;
				if (GetType () == ThresholdType)
					__ret = (Java.Lang.Object) global::Java.Lang.Object.GetObject<global::Java.Lang.Object> (JNIEnv.CallObjectMethod  (Handle, id_setCustomDimension_ILjava_lang_String_, new JValue (p0), new JValue (native_p1)), JniHandleOwnership.TransferLocalRef);
				else
					__ret = (Java.Lang.Object) global::Java.Lang.Object.GetObject<global::Java.Lang.Object> (JNIEnv.CallNonvirtualObjectMethod  (Handle, ThresholdClass, JNIEnv.GetMethodID (ThresholdClass, "setCustomDimension", "(ILjava/lang/String;)Ljava/lang/Object;"), new JValue (p0), new JValue (native_p1)), JniHandleOwnership.TransferLocalRef);
				JNIEnv.DeleteLocalRef (native_p1);
				return __ret;
			}

Do I need to recreate my Java binding project for scratch or change some of its settings?
Comment 31 Dimitar Dobrev 2015-03-08 12:44:22 UTC
I use version 3.9.347/4.20.0.37, is this supposed to be fixed there?
Comment 32 Jon Dick 2015-03-08 14:14:12 UTC
This refers to the google play services component and nuget package, neither of which are bundled with xamarin.android.
Comment 33 Dimitar Dobrev 2015-03-08 14:17:13 UTC
I understand, Jon, but I didn't know where to write. Anyway, I need the updated generator for Java bindings, has it been released or not?
Comment 34 Jon Dick 2015-03-08 15:20:55 UTC
I believe this will be released in the next xamarin.android update.