Bug 25516 - Classes not found using Metadata
Summary: Classes not found using Metadata
Alias: None
Product: Android
Classification: Xamarin
Component: General ()
Version: 4.18.1
Hardware: PC Mac OS
: --- normal
Target Milestone: ---
Assignee: Jonathan Pryor
Depends on:
Reported: 2014-12-18 17:55 UTC by Cody Beyer (MSFT)
Modified: 2015-02-12 21:34 UTC (History)
2 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 Cody Beyer (MSFT) 2014-12-18 17:55:51 UTC
### Description

Attempting to use metadata to call a class fails with Java.Lang.NoSuchMethodError 

### Test Case


### Steps to Reproduce

1. Open linked test case
2. Run in Simulator (JellyBean used for testing)
3. Wait for unhandled exception 

### Expected Results

Program loads classes based upon the metadata contained within

### Actual results

Application crashes with below error

### Error

>Java.Lang.NoSuchMethodError: tv.ouya.console.api.OuyaInputMapper.init
>  at at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () <IL 0x00011, 0x00047>
>  at Android.Runtime.JNIEnv.CallNonvirtualVoidMethod (intptr,intptr,intptr,Android.Runtime.JValue[]) [0x00084] in >/Users/builder/data/lanes/monodroid-mlion-monodroid-4.20->series/ba9bbbdd/source/monodroid/src/Mono.Android/src/Runtime/JNIEnv.g.cs:896
>  at Android.Runtime.JNIEnv.FinishCreateInstance (intptr,intptr,intptr,Android.Runtime.JValue[]) [0x0000b] in >/Users/builder/data/lanes/monodroid-mlion-monodroid-4.20->series/ba9bbbdd/source/monodroid/src/Mono.Android/src/Runtime/JNIEnv.cs:288
>  at TV.Ouya.Sdk.OuyaInputView..ctor (Android.Content.Context) [0x00121] in >/Users/codybeyer/Downloads/InputView/XamarinOuyaPlugin/obj/Debug/generated/src/TV.Ouya.Sdk.OuyaInputView.cs:165
>  at InputView.MainActivity.OnCreate (Android.OS.Bundle) [0x000c8] in /Users/codybeyer/Downloads/InputView/MainActivity.cs:49
>  at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_ (intptr,intptr,intptr) [0x00011] in >/Users/builder/data/lanes/monodroid-mlion-monodroid-4.20-series/ba9bbbdd/source/monodroid/src/Mono.Android/platforms/android->16/src/generated/Android.App.Activity.cs:2089
>  at at (wrapper dynamic-method) object.c4a38f5f-4785-4642-9916-baf88013a4ad (intptr,intptr,intptr) <IL 0x00017, 0x0001f>
>  at --- End of managed exception stack trace ---
>  at java.lang.NoSuchMethodError: tv.ouya.console.api.OuyaInputMapper.init
>  at at tv.ouya.sdk.OuyaInputView.init(OuyaInputView.java:77)
>  at at tv.ouya.sdk.OuyaInputView.<init>(OuyaInputView.java:58)
>  at at inputview.MainActivity.n_onCreate(Native Method)
>  at at inputview.MainActivity.onCreate(MainActivity.java:28)
>  at at android.app.Activity.performCreate(Activity.java:5008)
>  at at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
>  at at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
>  at at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
>  at at android.app.ActivityThread.access$600(ActivityThread.java:130)
>  at at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
>  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:4745)
>  at at java.lang.reflect.Method.invokeNative(Native Method)
>  at at java.lang.reflect.Method.invoke(Method.java:511)
>  at at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
>  at at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
>  at at dalvik.system.NativeStart.main(Native Method)

### Version

=== Xamarin Studio ===

Version 5.5.4 (build 15)
Installation UUID: 3e4348fa-e0b3-46a4-8426-58f27e19159e
	Mono 3.10.0 ((detached/92c4884)
	GTK+ 2.24.23 (Raleigh theme)

	Package version: 310000031

=== Apple Developer Tools ===

Xcode 6.1.1 (6611)
Build 6A2008a

=== Xamarin.iOS ===

Version: (Business Edition)
Hash: 7244769
Build date: 2014-12-11 14:54:30-0500

=== Xamarin.Android ===

Version: (Business Edition)
Android SDK: /Users/codybeyer/Library/Developer/Xamarin/android-sdk-macosx
	Supported Android versions:
		2.1    (API level 7)
		2.2    (API level 8)
		2.3    (API level 10)
		3.1    (API level 12)
		4.0    (API level 14)
		4.0.3  (API level 15)
		4.1    (API level 16)
		4.2    (API level 17)
		4.4    (API level 19)
		4.4.87 (API level 20)
		5.0    (API level 21)
Java SDK: /usr
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)

=== Xamarin.Mac ===

Version: (Business Edition)

=== Build Information ===

Release ID: 505040015
Git revision: f93940a35458a18052f1a25e106e62ca970d9c40
Build date: 2014-11-19 15:32:41-05
Xamarin addins: dc23cbd91a3a0e1d326328e1229e86c942a49ec8

=== Operating System ===

Mac OS X 10.10.1
Darwin Codys-MBP.lan 14.0.0 Darwin Kernel Version 14.0.0
    Fri Sep 19 00:26:44 PDT 2014
    root:xnu-2782.1.97~2/RELEASE_X86_64 x86_64
Comment 2 Jonathan Pryor 2014-12-18 21:56:37 UTC
XamarinOuyaPlugin.jar is mis-compiled. (I don't know how they mis-compiled it, but they mis-compiled it.)

Firstly, when I run it on Android 5.0 on a Nexus 5, I get a slightly better error message:

> I/MonoDroid(10384): java.lang.NoSuchMethodError: No static method init(Landroid/app/Activity;)V in class Ltv/ouya/console/api/OuyaInputMapper; or its super classes (declaration of 'tv.ouya.console.api.OuyaInputMapper' appears in /data/app/InputView.InputView-1/base.apk)

Note the *specifics*: it's looking for OuyaInputMapper.init(Activity), and it can't find it.

Specifically, if we disassemble:

> $ javap -c -s -private -classpath XamarinOuyaPlugin/Jars/XamarinOuyaPlugin.jar tv/ouya/sdk/OuyaInputView | grep InputMap
>      106: invokestatic  #20                 // Method tv/ouya/console/api/OuyaInputMapper.init:(Landroid/app/Activity;)V
>       14: invokestatic  #25                 // Method tv/ouya/console/api/OuyaInputMapper.shutdown:(Landroid/app/Activity;)V
>       14: invokestatic  #27                 // Method tv/ouya/console/api/OuyaInputMapper.shouldHandleInputEvent:(Landroid/view/InputEvent;)Z
>       22: invokestatic  #28                 // Method tv/ouya/console/api/OuyaInputMapper.dispatchGenericMotionEvent:(Landroid/app/Activity;Landroid/view/MotionEvent;)Z
>       14: invokestatic  #27                 // Method tv/ouya/console/api/OuyaInputMapper.shouldHandleInputEvent:(Landroid/view/InputEvent;)Z
>       22: invokestatic  #30                 // Method tv/ouya/console/api/OuyaInputMapper.dispatchKeyEvent:(Landroid/app/Activity;Landroid/view/KeyEvent;)Z

OuyaInputView wants an OuyaInputMapper.initActivity) method.

What does OuyaInputMapper actually provide?

> $ javap -classpath XamarinOuyaPlugin/Jars/ouya-sdk.jar tv/ouya/console/api/OuyaInputMapper | grep init
>   public static void init(android.content.Context);

What's °actually* present is an OuyaInputMapper.init(Context) method. Context != Activity, so Android can't find the specified method, and thus raises the NoSuchMethodError.

The fix is to build XamarinOuyaPlugin.jar against the same ouya-sdk.jar as is being bundled with the app, so that the types are consistent and Android doesn't complain loudly.
Comment 3 Timothy A. Graupmann 2015-02-12 19:01:53 UTC
Thanks as always Jonathan.

The project builds the JAR using Gradle from the folder:

The terminal command builds the JAR:
gradlew clean build copyJar

And all I needed to do is rebuild the JAR after updating the ouya-sdk.jar.

As you discovered the JAR was previously built for a different version of the ouya-sdk.jar causing the mismatch.

I'll be sure to double-check that in the future.

Moral of the story, when you wrap a JAR with Xamarin be sure to make sure that JAR and it's references are up to date.

If you see a signature mismatch and begin to lose your sanity repeat the above step...

Thanks again Jonathan.

~Tim Graupmann
Comment 4 Timothy A. Graupmann 2015-02-12 21:34:27 UTC
I added the working version to github.