Bug 5111 - Unable to generate bindings for Google's Guice library
Summary: Unable to generate bindings for Google's Guice library
Alias: None
Product: Android
Classification: Xamarin
Component: General ()
Version: 4.2.x
Hardware: PC Mac OS
: --- normal
Target Milestone: ---
Assignee: Atsushi Eno
Depends on:
Reported: 2012-05-15 23:07 UTC by Greg Shackles
Modified: 2014-03-07 05:31 UTC (History)
3 users (show)

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

Required jar file (2.44 KB, application/octet-stream)
2012-05-17 09:25 UTC, Greg Shackles
build log (90.19 KB, text/plain)
2012-05-20 10:29 UTC, Greg Shackles
Library.jar for Google Map Utility (78.64 KB, application/octet-stream)
2014-03-07 04:53 UTC, ole.kristensen

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 Greg Shackles 2012-05-15 23:07:53 UTC
When trying to generate bindings for the Google Guice library a lot of errors are encountered. It looks like many of them are related to some classes in the library being bound with names starting with a dot. Some examples:


The jar file can be found here: http://google-guice.googlecode.com/files/guice-3.0-no_aop.jar
Comment 1 Atsushi Eno 2012-05-16 14:20:11 UTC
I don't think this class library is "android ready". It misses some classes that are not in android API e.g. javax.inject.Provider (which seems to be JavaEE class):

/home/atsushi/svn/monodroid/tools/msbuild/build/Novell/Xamarin.Android.Bindings.targets: Error: Tool exited with code: 1. Output: Couldn't load class com/google/inject/Provider
Couldn't load class com/google/inject/Scopes$1$1
Couldn't load class com/google/inject/internal/InjectorImpl$4
Couldn't load class com/google/inject/internal/InjectorShell$InjectorFactory
Couldn't load class com/google/inject/internal/InjectorShell$LoggerFactory
Couldn't load class com/google/inject/internal/ProviderMethod
Couldn't load class com/google/inject/internal/ProviderMethodsModule$LogProvider
Couldn't load class com/google/inject/internal/ProviderToInternalFactoryAdapter
Couldn't load class com/google/inject/spi/ProviderLookup$1
Couldn't load class com/google/inject/spi/ProviderWithDependencies
Couldn't load class com/google/inject/spi/ProviderWithExtensionVisitor
Couldn't load class com/google/inject/util/Providers$1
Couldn't load class com/google/inject/util/Providers$2
Couldn't load class com/google/inject/util/Providers$3
Exception in thread "main" java.lang.NoClassDefFoundError: javax/inject/Provider
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
	at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
	at java.lang.Class.getDeclaredMethods0(Native Method)
	at java.lang.Class.privateGetDeclaredMethods(Class.java:2427)
	at java.lang.Class.getDeclaredMethods(Class.java:1791)
	at jar2xml.JavaClass.appendToDocument(JavaClass.java:466)
	at jar2xml.JavaPackage.appendToDocument(JavaPackage.java:66)
	at jar2xml.Start.main(Start.java:157)
Caused by: java.lang.ClassNotFoundException: javax.inject.Provider
	at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
	... 17 more

Were you using this jar file exactly? I don't think it's going to work on Android. At least we cannot support what is not covered directly or indirectly in Android API.
Comment 2 Greg Shackles 2012-05-17 09:25:15 UTC
Created attachment 1903 [details]
Required jar file

Sorry, I forgot to include javax.inject.jar which is required by Guice.
Comment 3 Atsushi Eno 2012-05-18 04:43:42 UTC
Thanks, reopening.

The issue I noticed with related to this guice-3.0-no_aop.jar is that it turned out to contain some "public" class whose name begin with '$'. In our toolchain we replace '$' with dot '.' as it usually express a nested type. I have no idea what kind of sources and compiler or any toolchains could generate such a "broken" class, but we'll have to eliminate those classes away from the API generator.

Apart from the issue itself, this problematic package in the jar can be entirely eliminated as there is no public class. To do so, you can add Metadata.xml that contains one simple line:

  <remove-node path="/api/package[@name='com.google.inject.internal.util']" />
Comment 4 Greg Shackles 2012-05-20 10:29:44 UTC
Created attachment 1925 [details]
build log

Are you able to build the binding after eliminating that package? I still get a bunch of build errors related to missing types after doing so (see attached log file).
Comment 5 Atsushi Eno 2012-05-20 11:24:35 UTC
Ah, not yet (that's part of why it is kept open). I plan to continue investigating the remaining issue next week. Sorry for the inconvenience.
Comment 6 Atsushi Eno 2012-05-21 04:10:50 UTC
After some fixes in type resolution, our internal build don't seem to have unresolved issue exposed in this bug repro anymore. The remaining ones look like:

/home/atsushi/デスクトップ/RoboGuice/RoboGuice/obj/Debug/generated/src/Com.Google.Inject.Internal.BindingBuilder.cs(126,33): error CS0102: The type `Com.Google.Inject.Internal.BindingBuilder' already contains a definition for `cb_to_Lcom_google_inject_Key_'

which sounds like a duplicate for bug #5020.
Comment 7 Atsushi Eno 2012-05-22 06:20:18 UTC
We need some different fix for this bug, apart from the fix for #5020.
Comment 8 Atsushi Eno 2012-05-22 07:50:34 UTC
With further investigation, I have to say Google Guice cannot be supported with our current policy to exclude java.lang.reflect. Here is why.

1) First, there is an issue that the API description generator somehow misses"variance" of the interface implementation in the target library. Com.Google.Inject.Internal.BindingBuilder contains two "To(Key)" methods, where the one that returns IScopedBindingBuilder is invalid (there is another one which returns BindingBuilder, which is valid). There is another such pair "ToProvider(Key)" which falls into the same result.

This can be workarounded by adding a metadata fixup like below:

  <remove-node path="/api/package[@name='com.google.inject.internal.util']" />
  <remove-node path="/api/package[@name='com.google.inject.internal']/
  method[@name='to'][count(parameter) = 1][@return='com.google.inject.binder.ScopedBindingBuilder']" />
  <remove-node path="/api/package[@name='com.google.inject.internal']/
  method[@name='toProvider'][count(parameter) = 1][@return='com.google.inject.binder.ScopedBindingBuilder']" />

We'll have to fix this issue. But there is another problem.

2) There is a bunch of classes that depends on java.lang.reflect classes. Here is an example, IBinder:

/home/atsushi/デスクトップ/RoboGuice/RoboGuice/obj/Debug/generated/src/Com.Google.Inject.IPrivateBinder.cs(77,77): Error CS0234: The type or namespace name `IBinder' does not exist in the namespace `Com.Google.Inject'. Are you missing an assembly reference? (CS0234) (RoboGuice)

This com.google.inject.Binder interface could not be imported, due to these issues (reported in the build output):

Unknown parameter type java.lang.reflect.Constructor<S> found in method ToConstructor in type Com.Google.Inject.Binder.ILinkedBindingBuilder
Unknown parameter type java.lang.reflect.Constructor<S> found in method ToConstructor in type Com.Google.Inject.Binder.ILinkedBindingBuilder
Invalid return type com.google.inject.binder.LinkedBindingBuilder<T> found in method Bind in type Com.Google.Inject.IBinder

com.google.inject.Binder implements com.google.inject.binder.LinkedBindingBuilder. And this LinkedBindingBuilder cannot be generated because one of its method, toConstructor(), references java.lang.reflect.Construtcor which *does not exist* in java.lang.reflect.

In *theory*, we cannot provide an automatic bindings for such an *interface* that we cannot bind *any* of the members, because we cannot generate valid Android Callable Wrapper at app build time (javac rejects the ACW that is only an incomplete implementation).
Comment 10 Atsushi Eno 2012-05-22 07:52:01 UTC
We should add this limitation to our binding troubleshooting document.
Comment 11 ole.kristensen 2014-03-07 04:46:51 UTC
I have generated a similar bugzilla


Does this mean that Google Map Utility cannot be supported by Xamarin binding neither ? :-(
Comment 12 ole.kristensen 2014-03-07 04:53:45 UTC
Created attachment 6255 [details]
Library.jar for Google Map Utility
Comment 13 Atsushi Eno 2014-03-07 05:31:26 UTC