Bug 17642 - Getting exception "Failed to create JavaTypeInfo for class" when building any project using F# Object Expressions
Summary: Getting exception "Failed to create JavaTypeInfo for class" when building any...
Status: ASSIGNED
Alias: None
Product: Android
Classification: Xamarin
Component: General (show other bugs)
Version: 4.10.2
Hardware: PC Windows
: Low normal
Target Milestone: ---
Assignee: Jonathan Pryor
URL:
: 20595 (view as bug list)
Depends on:
Blocks:
 
Reported: 2014-02-06 14:21 UTC by Chris H
Modified: 2017-08-16 10:26 UTC (History)
5 users (show)

See Also:
Tags: XATriaged
Is this bug a regression?: ---
Last known good build:


Attachments

Description Chris H 2014-02-06 14:21:17 UTC
Compiling any object expressions will cause ms build to throw an exception.


MSBuild Error:

C:\Program Files (x86)\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(3,3): Error XA4209: Failed to create JavaTypeInfo for class: <StartupCode$Test-Android>.$TestActivity/get_Adapter@53 due to System.ArgumentException: Illegal characters in path.
   at System.IO.Path.CheckInvalidPathChars(String path, Boolean checkAdditional)
   at System.IO.Path.Combine(String path1, String path2)
   at Xamarin.Android.Tasks.JavaTypeInfo.OpenStream(String outputPath)
   at Xamarin.Android.Tasks.JavaTypeInfo.Generate(String outputPath)
   at Xamarin.Android.Tasks.Generator.GenerateJavaSource(TaskLoggingHelper log, TypeDefinition t, String outputPath, Boolean useSharedRuntime, Boolean hasExportReference) (XA4209) (Wireclub.Android)    

Code to recreate:

member this.Adapter =
        { new BaseAdapter<string>() with

            override this.Count with get () = 0
            override this.Item with get (position:int) = null
            override this.GetItemId position = int64 position
            override this.GetView (position, view, parent) = view
        }

Xamarin Details:

=== Xamarin Studio ===

Version 4.2.2 (build 2)
Installation UUID: 21e94e29-8d3d-4cd8-894b-d6bc87f813bf
Runtime:
	Microsoft .NET 4.0.30319.34003
	GTK+ 2.24.22 theme: MS-Windows
	GTK# (2.12.0.0)

=== Xamarin.Android ===

Version: 4.10.2
Android SDK: 
	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.3   (API level 18)
		4.4   (API level 19)

=== Operating System ===

Windows 6.2.9200.0 (64-bit)
Comment 1 Jonathan Pryor 2014-02-06 15:20:25 UTC
During the build process, "Android Callable Wrappers" (ACWs) are generated for each type that subclasses (directly or indirectly) Java.Lang.Object:

http://docs.xamarin.com/guides/android/advanced_topics/java_integration_overview/android_callable_wrappers/

ACWs are Java source code, generated at build, in which the namespace name becomes the Java package name, and the type name is unchanged. Consequently, the namespace and type names must conform to Java semantics, meaning they need to be valid Java identifiers.

In your F# sample, that is _not_ the case -- "<StartupCode$Test-Android>.$TestActivity/get_Adapter@53" is not a valid Java identifier (nor can it be stored on-disk, as Java requires that the filename match the public class name), which is why you get error XA4209.

In theory, this will be fixed when Bug #16826 is fixed, but that'll be awhile, particularly since such a change would be a semantically breaking change.

For now, Don't Do That. Use explicit types.

*** This bug has been marked as a duplicate of bug 16826 ***
Comment 2 Jonathan Pryor 2014-06-15 12:21:59 UTC
*** Bug 20595 has been marked as a duplicate of this bug. ***
Comment 3 Jonathan Pryor 2014-10-15 21:57:02 UTC
Upon closer inspection, Bug #16826 is not exactly identical to this bug, as Bug #16826 is only correcting the Java package name, and is *not* correcting the Jaava *type* name. This is (currently) a deliberate decision, because managed stack traces will already be more difficult to interpret because the C# namespace is obliterated; at least the *type* name is preserved, so some degree of sanity can be retained.

When it comes to F#, the type name is still not a valid Java identifier -- assuming that `$TestActivity/get_Adapter@53` is the type name -- and thus simply because Bug #16826 is fix does not mean that F# is fully fixed.
Comment 4 Jay 2015-03-25 13:40:17 UTC
To be clear, the type name here is generated -- this does not appear in the source code anywhere.

The construct is an Object Expression, which you could think of as an inline implementation of an interface or abstract class, or a class that just overrides one member of another class.

These are extremely useful in general, and in particular for Xamarin development. For example, instead of creating a new class to inherit something like CameraCaptureSession.StateCallback, one can do it inline and have access to all the local values.

let stateCallback = { new CameraCaptureSession.StateCallback() with
                          override this.OnConfigured session = startPreview session
                          override this.OnConfigureFailed session = toast "Failed" }

This is the class that gets the ugly generated name during compilation. Perhaps the build process could identify and replace those names when building the Java package. I'm not sure about the requirement that the class be in its own file of the same name.

I'd love to see this supported!
Comment 5 Atsushi Eno 2016-09-20 11:16:39 UTC
This is about JCW, not about binding generator.
Comment 6 prashant.vaibhav 2017-08-16 10:26:18 UTC
Any update on this *blocker* bug? I am not able to use F# code library with object expressions in my Xamarin.Android projects due to this! The simple example is listeners for various events in the Android API (e.g. Activity.RegisterReceiver()).

Note You need to log in before you can comment on or make changes to this bug.