Bug 14104 - Getting exception "Java.Lang.NoClassDefFoundError" after clicking on 'Post Photo' for sample 'Facebook'
Summary: Getting exception "Java.Lang.NoClassDefFoundError" after clicking on 'Post Ph...
Status: VERIFIED FIXED
Alias: None
Product: Android
Classification: Xamarin
Component: Samples ()
Version: 4.8.x
Hardware: PC Mac OS
: --- normal
Target Milestone: ---
Assignee: Atsushi Eno
URL:
Depends on:
Blocks:
 
Reported: 2013-08-20 03:39 UTC by narayanp
Modified: 2013-08-29 12:12 UTC (History)
3 users (show)

Tags:
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:
VERIFIED FIXED

Description narayanp 2013-08-20 03:39:55 UTC
Steps to reproduce this issue:
1. Open android sample 'Facebook'.
2. Debug or run the sample.
3. Logging into Facebook.
4. Click on 'Post Photo'.

Actual result: Application get crashed after clicking on 'Post Photo'.

Expected Result: Application should not crashed.

Supplement info:
logcat info: https://gist.github.com/saurabh360/2cab21b02cd2b95c55aa
Error info: https://gist.github.com/saurabh360/5be37b7b7aa44baebcd8

App info:
Monodroid sample-master/Facebok.

Environment details:
All Mac
X.S 4.0.11(build 7)
Mono 3.2.2
X.Android 4.8.2-54

Regression Status:
This application has never worked before the are already Bug 8497
Comment 1 PJ 2013-08-22 18:24:02 UTC
I can reproduce this. I'm not sure what the updated business priority of the Facebook sample is, we now have our own binding of the SDK, and two bindings in the component store.

Atsushi, the most recent updates to this app are from you from https://github.com/xamarin/monodroid-samples/commit/a96e832cb4534781224be17f4a2bc6698ab12dbc

Can you take a look?
Comment 2 Atsushi Eno 2013-08-26 06:04:07 UTC
After some investigation I figured that this type "hellofacebooksample/HelloFacebookSampleActivity_GraphObjectWithId" is never emitted as a Java interface. I think it is because we thought we don't need any interfaces to be generated.

I tried to generate it by adding [Register] but it did not work. [Export] is only for fields, constructors and methods, so no help either. Maybe we need to extend some Java code generation feature.
Comment 3 Jonathan Pryor 2013-08-26 18:02:39 UTC
Note: quick glance, so I may be missing the obvious or the details.

This looks fishy:

https://github.com/xamarin/monodroid-samples/blob/master/Facebook/HelloFacebookSample/HelloFacebookSampleActivity.cs#L273

Specifically, `Java.Lang.Class.FromType (typeof(GraphObjectWithId))` when GraphObjectWithId is a C# type.

Why is that done (aside from presumable 1:1 port from the Java sample)?

Now, if GraphObjectWithId were a Java.Lang.Object subclass, that would work. Since we don't currently generate .java files for interfaces, it fails (as Atsushi noted).

Which raises a question: what is the use case for generating ACW's for interfaces? Is there one?

Can we instead "fix" the sample so that GraphObjectWithId isn't an interface and instead is a Java.Lang.Object subclass? Or remove the Class.FromType() use? Or...?
Comment 4 Atsushi Eno 2013-08-27 03:39:00 UTC
Note that the code expects "Response" in certain Java interface which is returned by bound Java library. Every Facebook API users likely need to use this sort of stuff. It is indeed fishy, but it is Facebook which is weird and does not specify GraphObjectWithId in the library itself, but that's what currently exists. My impression is that we somehow need to provide way to generate some Java code for interface.
Comment 5 Jonathan Pryor 2013-08-27 09:18:42 UTC
Is there no way to use a class instead of an interface? I'm not sure if Facebook requires an interface (nor am I sure how they'd ensure such a thing short of Java reflection, which sounds insane).

I'm leery about providing ACW support for interfaces because I don't know what all it will imply or entail; will we need to have the *Invoker infrastructure? Would it require Mono.Android.Export.dll? How would any of that get hooked up?

It is not currently clear in my mind what is implied here; I'd rather avoid or delay implementing this if at all possible.

(For example, if you can have an ACW interface definition, then presumably you could have Java code implement that interface via an AndroidJavaSource build action. If you had a Java.Lang.Object/etc. reference to that Java type, you MUST have a *Invoker to do the appropriate JNI-fu so that the Java methods will be invoked. HOW DO WE DO THAT?)
Comment 6 Jonathan Pryor 2013-08-27 12:24:43 UTC
If we try to use a class instead of an interface, things blow up:

> UNHANDLED EXCEPTION: Xamarin.FacebookBinding.FacebookGraphObjectException: Exception of type 'Xamarin.FacebookBinding.FacebookGraphObjectException' was thrown.
> at Android.Runtime.JNIEnv.CallObjectMethod (intptr,intptr,Android.Runtime.JValue[])
> at Xamarin.FacebookBinding.Model.IGraphObjectInvoker.Cast (Java.Lang.Class)
> at HelloFacebookSample.HelloFacebookSampleActivity.ShowPublishResult (
> at HelloFacebookSample.HelloFacebookSampleActivity.<PostPhoto>m__8 (Xamarin.FacebookBinding.Response)
> at HelloFacebookSample.HelloFacebookSampleActivity/RequestCallback.OnCompleted (Xamarin.FacebookBinding.Response)
> at Xamarin.FacebookBinding.Request/ICallbackInvoker.n_OnCompleted_Lcom_facebook_Response_ (intptr,intptr,intptr)
> at (wrapper dynamic-method) object.42867d90-6082-4322-a83c-6c2f35fac840 (intptr,intptr,intptr)
> 
>   --- End of managed exception stack trace ---
> com.facebook.FacebookGraphObjectException: Factory can only wrap interfaces, not class: hellofacebooksample.HelloFacebookSampleActivity_GraphObjectWithId
>     at com.facebook.model.GraphObject$Factory.verifyCanProxyClass(GraphObject.java:232)
>     at com.facebook.model.GraphObject$Factory.createGraphObjectProxy(GraphObject.java:196)
>     at com.facebook.model.GraphObject$Factory.access$000(GraphObject.java:91)
>     at com.facebook.model.GraphObject$Factory$GraphObjectProxy.proxyGraphObjectMethods(GraphObject.java:530)
>     at com.facebook.model.GraphObject$Factory$GraphObjectProxy.invoke(GraphObject.java:470)
>     at $Proxy0.cast(Native Method)
>     at hellofacebooksample.HelloFacebookSampleActivity_RequestCallback.n_onCompleted(Native Method)
>     at hellofacebooksample.HelloFacebookSampleActivity_RequestCallback.onCompleted(HelloFacebookSampleActivity_RequestCallback.java:29)
>     at com.facebook.Request$4.run(Request.java:1240)
>     at android.os.Handler.handleCallback(Handler.java:725)
>     at android.os.Handler.dispatchMessage(Handler.java:92)
>     at android.os.Looper.loop(Looper.java:137)
>     at android.app.ActivityThread.main(ActivityThread.java:5041)
>     at java.lang.reflect.Method.invokeNative(Native Method)
>     at java.lang.reflect.Method.invoke(Method.java:511)
>     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
>     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
>     at dalvik.system.NativeStart.main(Native Method)

Translation: Facebook requires an interface.

I will now start crying.
Comment 7 Jonathan Pryor 2013-08-27 12:31:35 UTC
There are three ways forward here:

1. Implement ACW+interface support. As mentioned in Comment #5, I have no idea what this entails.

2. Use a C#-native Facebook SDK. Google shows this one:

http://facebooksdk.net/

3. Add a AndroidJavaSource file with the Java GraphObjectWithId interface declaration, and hand-bind that in C#.

(1) looks to be a PITA. (2) would be ideal, if it works. (3) would likewise be a PITA, though should be doable now.
Comment 8 Atsushi Eno 2013-08-27 14:59:31 UTC
So far the primary purpose of Facebook binding is to experience Jar binding feature in XA. So, alongside option (2), we still find possibility to use Java-based Facebook SDK via binding.

Yet I agree on comment #5, we'd like to delay or avoid it as it is not simple to achieve.

So far I made a workaround by reflection magic so it should work. [master 89f6112]
Comment 9 Atsushi Eno 2013-08-27 15:00:05 UTC
(Fix is in monodroid-samples.)
Comment 10 Atin 2013-08-29 12:12:33 UTC
Today, we have checked this issue with following builds:
All mac
XS 4.1.9(build 6)
Mono 3.2.2
X.Android 4.8.2-54
App info: monodroid-samples-60ecd1df4a9964cc33a891ee73a0eeffb7fb6daf
Device info: samsung S3 V 4.0.4

Now this issue doesn't exist Application is not get crashed after clicking on 'Post Photo'. Hence marking this as Verified Fixed