Skip to content

Conversation

@jonpryor
Copy link
Contributor

Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=58303

Background: It is possible for a Java type to have
"aliasing bindings": two or more managed types which claim to bind
the same Java type:

// C#
namespace Android.Runtime {
  [Register ("java/util/HashMap", DoNotRegisterAcw=true)]
  partial class JavaDictionary {
  }
}
namespace Java.Util {
  [Register ("java/util/HashMap", DoNotRegisterAcw=true)]
  partial class HashMap {
  }
}

These can't be realistically forbidden.

Enter a new-to-bind Java type:

// Java
public class Bxc58383 extends java.util.HashMap implements java.util.Map {
}

In order to bind the above Bxc58383 type, generator needs to
determine the appropriate binding type to use for java.util.HashMap.
generator's approach to supporting aliasing types is (largely) to
ignore the problem (almost) entirely: There Can Be Only One™ mapping
from a Java type to a managed type, so generator needs to pick one.
It does so by using the last definition encountered in the assembly.

Consequently, for the above set of C# declarations, when generator
needs to find the managed type which binds java.util.HashMap,
Java.Util.HashMap will be chosen, as it is the last declared type.

Unfortunately, "real life" is a bit more complicated:
Mono.Android.dll is made up of thousands of files, and the order
of types within an assembly is a compiler implementation detail.
As such...the current Mono.Android.dll has JavaDictionary defined
after HashMap:

# output truncated for relevance
$ monodis --typedef bin/Debug/lib/xamarin.android/xbuild-frameworks/MonoAndroid/v7.1/Mono.Android.dll | grep 'Dictionary\|HashMap'
1270: Java.Util.Dictionary (flist=12611, mlist=29569, flags=0x100081, extends=0x20b8)
1287: Java.Util.HashMap (flist=12662, mlist=29806, flags=0x100001, extends=0x1388)
3992: Android.Runtime.JavaDictionary (flist=32135, mlist=85344, flags=0x100001, extends=0x20b8)

Because JavaDictionary is defined after HashMap, and both of
those types have [Register] attributes which declare that they bind
the same Java type, the result is that the binding of Bxc58383 is
horrifically broken:

// C#
partial class Bxc58383 : global::Android.Runtime.JavaDictionary, global::Java.Util.IMap {
}

Unfortunately, JavaDictionary doesn't itself implement IMap, so:

error CS0535: 'Bxc58383' does not implement interface member 'IMap.ContainsKey(Object)'

along with 10 other related errors.

Update the src/Mono.Android build process so that JavaDictionary
and related types will be defined within Mono.Android.dll before
all the generated types. This allows HashMap to be defined last,
allowing Bxc58383 to be bound without error:

# output truncated
$ monodis --typedef bin/Debug/lib/xamarin.android/xbuild-frameworks/MonoAndroid/v7.1/Mono.Android.dll | grep 'Dictionary\|HashMap'
3703: Android.Runtime.JavaDictionary (flist=34089, mlist=78134, flags=0x100001, extends=0x4e08)
4170: Java.Util.Dictionary (flist=39685, mlist=91737, flags=0x100081, extends=0x4e08)
4187: Java.Util.HashMap (flist=39736, mlist=91974, flags=0x100001, extends=0x40d8)

Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=58303

Background: It is possible for a Java type to have
"aliasing bindings": two or more managed types which claim to bind
the same Java type:

	// C#
	namespace Android.Runtime {
	  [Register ("java/util/HashMap", DoNotRegisterAcw=true)]
	  partial class JavaDictionary {
	  }
	}
	namespace Java.Util {
	  [Register ("java/util/HashMap", DoNotRegisterAcw=true)]
	  partial class HashMap {
	  }
	}

These can't be realistically forbidden.

Enter a new-to-bind Java type:

	// Java
	public class Bxc58383 extends java.util.HashMap implements java.util.Map {
	}

In order to bind the above `Bxc58383` type, `generator` needs to
determine the appropriate binding type to use for `java.util.HashMap`.
`generator`'s approach to supporting aliasing types is (largely) to
ignore the problem (almost) entirely: There Can Be Only One™ mapping
from a Java type to a managed type, so `generator` needs to pick one.
It does so by using the *last* definition encountered in the assembly.

Consequently, for the above set of C# declarations, when `generator`
needs to find the managed type which binds `java.util.HashMap`,
`Java.Util.HashMap` will be chosen, as it is the last declared type.

Unfortunately, "real life" is a bit more complicated:
`Mono.Android.dll` is made up of *thousands* of files, and the order
of types within an assembly is a compiler implementation detail.
As such...the current `Mono.Android.dll` has `JavaDictionary` defined
*after* `HashMap`:

	# output truncated for relevance
	$ monodis --typedef bin/Debug/lib/xamarin.android/xbuild-frameworks/MonoAndroid/v7.1/Mono.Android.dll | grep 'Dictionary\|HashMap'
	1270: Java.Util.Dictionary (flist=12611, mlist=29569, flags=0x100081, extends=0x20b8)
	1287: Java.Util.HashMap (flist=12662, mlist=29806, flags=0x100001, extends=0x1388)
	3992: Android.Runtime.JavaDictionary (flist=32135, mlist=85344, flags=0x100001, extends=0x20b8)

Because `JavaDictionary` is defined *after* `HashMap`, and both of
those types have `[Register]` attributes which declare that they bind
the *same* Java type, the result is that the binding of `Bxc58383` is
horrifically broken:

	// C#
	partial class Bxc58383 : global::Android.Runtime.JavaDictionary, global::Java.Util.IMap {
	}

Unfortunately, `JavaDictionary` doesn't itself implement `IMap`, so:

	error CS0535: 'Bxc58383' does not implement interface member 'IMap.ContainsKey(Object)'

along with 10 other related errors.

Update the `src/Mono.Android` build process so that `JavaDictionary`
and related types will be defined within `Mono.Android.dll` *before*
all the generated types. This allows `HashMap` to be defined last,
allowing `Bxc58383` to be bound without error:

	# output truncated
	$ monodis --typedef bin/Debug/lib/xamarin.android/xbuild-frameworks/MonoAndroid/v7.1/Mono.Android.dll | grep 'Dictionary\|HashMap'
	3703: Android.Runtime.JavaDictionary (flist=34089, mlist=78134, flags=0x100001, extends=0x4e08)
	4170: Java.Util.Dictionary (flist=39685, mlist=91737, flags=0x100081, extends=0x4e08)
	4187: Java.Util.HashMap (flist=39736, mlist=91974, flags=0x100001, extends=0x40d8)
@dellis1972 dellis1972 merged commit ada479b into dotnet:master Aug 11, 2017
jonpryor added a commit that referenced this pull request Aug 11, 2017
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=58303

Background: It is possible for a Java type to have
"aliasing bindings": two or more managed types which claim to bind
the same Java type:

	// C#
	namespace Android.Runtime {
	  [Register ("java/util/HashMap", DoNotRegisterAcw=true)]
	  partial class JavaDictionary {
	  }
	}
	namespace Java.Util {
	  [Register ("java/util/HashMap", DoNotRegisterAcw=true)]
	  partial class HashMap {
	  }
	}

These can't be realistically forbidden.

Enter a new-to-bind Java type:

	// Java
	public class Bxc58383 extends java.util.HashMap implements java.util.Map {
	}

In order to bind the above `Bxc58383` type, `generator` needs to
determine the appropriate binding type to use for `java.util.HashMap`.
`generator`'s approach to supporting aliasing types is (largely) to
ignore the problem (almost) entirely: There Can Be Only One™ mapping
from a Java type to a managed type, so `generator` needs to pick one.
It does so by using the *last* definition encountered in the assembly.

Consequently, for the above set of C# declarations, when `generator`
needs to find the managed type which binds `java.util.HashMap`,
`Java.Util.HashMap` will be chosen, as it is the last declared type.

Unfortunately, "real life" is a bit more complicated:
`Mono.Android.dll` is made up of *thousands* of files, and the order
of types within an assembly is a compiler implementation detail.
As such...the current `Mono.Android.dll` has `JavaDictionary` defined
*after* `HashMap`:

	# output truncated for relevance
	$ monodis --typedef bin/Debug/lib/xamarin.android/xbuild-frameworks/MonoAndroid/v7.1/Mono.Android.dll | grep 'Dictionary\|HashMap'
	1270: Java.Util.Dictionary (flist=12611, mlist=29569, flags=0x100081, extends=0x20b8)
	1287: Java.Util.HashMap (flist=12662, mlist=29806, flags=0x100001, extends=0x1388)
	3992: Android.Runtime.JavaDictionary (flist=32135, mlist=85344, flags=0x100001, extends=0x20b8)

Because `JavaDictionary` is defined *after* `HashMap`, and both of
those types have `[Register]` attributes which declare that they bind
the *same* Java type, the result is that the binding of `Bxc58383` is
horrifically broken:

	// C#
	partial class Bxc58383 : global::Android.Runtime.JavaDictionary, global::Java.Util.IMap {
	}

Unfortunately, `JavaDictionary` doesn't itself implement `IMap`, so:

	error CS0535: 'Bxc58383' does not implement interface member 'IMap.ContainsKey(Object)'

along with 10 other related errors.

Update the `src/Mono.Android` build process so that `JavaDictionary`
and related types will be defined within `Mono.Android.dll` *before*
all the generated types. This allows `HashMap` to be defined last,
allowing `Bxc58383` to be bound without error:

	# output truncated
	$ monodis --typedef bin/Debug/lib/xamarin.android/xbuild-frameworks/MonoAndroid/v7.1/Mono.Android.dll | grep 'Dictionary\|HashMap'
	3703: Android.Runtime.JavaDictionary (flist=34089, mlist=78134, flags=0x100001, extends=0x4e08)
	4170: Java.Util.Dictionary (flist=39685, mlist=91737, flags=0x100081, extends=0x4e08)
	4187: Java.Util.HashMap (flist=39736, mlist=91974, flags=0x100001, extends=0x40d8)
@awattar
Copy link

awattar commented Jul 18, 2019

@jonpryor this issue seems to be reintroduced some time ago.

$ monodis --typedef /Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v9.0/Mono.Android.dll | grep 'Dictionary\|HashMap'
2336: Android.Provider.UserDictionary (flist=20357, mlist=50783, flags=0x100001, extends=0x5770)
4272: Android.Runtime.JavaDictionary (flist=39239, mlist=88391, flags=0x100001, extends=0x5770)
4273: Android.Runtime.JavaDictionary`2 (flist=39248, mlist=88420, flags=0x100001, extends=0x42c0)
4328: Java.Util.Dictionary (flist=39629, mlist=89967, flags=0x100081, extends=0x5770)
4329: Java.Util.DictionaryInvoker (flist=39637, mlist=89995, flags=0x100000, extends=0x43a0)
4344: Java.Util.HashMap (flist=39676, mlist=90204, flags=0x100001, extends=0x4354)
4353: Java.Util.IdentityHashMap (flist=39763, mlist=90467, flags=0x100001, extends=0x4354)
4413: Java.Util.LinkedHashMap (flist=40372, mlist=91767, flags=0x100001, extends=0x43e0)
4458: Java.Util.WeakHashMap (flist=40636, mlist=93002, flags=0x100001, extends=0x4354)
4654: Java.Util.Concurrent.ConcurrentHashMap (flist=41636, mlist=95798, flags=0x100001, extends=0x4354)
7275: Android.Provider.UserDictionary/Words (flist=56307, mlist=129575, flags=0x100002, extends=0x5770)
8862: Android.Runtime.JavaDictionary/DictionaryEnumerator (flist=62071, mlist=142256, flags=0x100003, extends=0x41)
8863: Android.Runtime.JavaDictionary/<>c__DisplayClass13_0 (flist=62072, mlist=142263, flags=0x100103, extends=0x41)
8864: Android.Runtime.JavaDictionary/<>c__DisplayClass13_1 (flist=62074, mlist=142265, flags=0x100103, extends=0x41)
8865: Android.Runtime.JavaDictionary/<System-Collections-IEnumerable-GetEnumerator>d__38 (flist=62076, mlist=142267, flags=0x100103, extends=0x41)
8866: Android.Runtime.JavaDictionary`2/<>c__DisplayClass4_0 (flist=62080, mlist=142274, flags=0x100103, extends=0x41)
8867: Android.Runtime.JavaDictionary`2/<>c__DisplayClass4_1 (flist=62082, mlist=142276, flags=0x100103, extends=0x41)
8868: Android.Runtime.JavaDictionary`2/<GetEnumerator>d__18 (flist=62084, mlist=142278, flags=0x100103, extends=0x41)
9373: Android.Provider.UserDictionary/Words/InterfaceConsts (flist=64903, mlist=145130, flags=0x100182, extends=0x41)

jonpryor added a commit to jonpryor/xamarin-android that referenced this pull request Oct 20, 2020
Fixes: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1230070

Changes: dotnet/java-interop@b991bb8...da74abd

  * dotnet/java-interop@da74abd2: Bump to mono/LineEditor@3fa0c2eb (dotnet#740)
  * dotnet/java-interop@5fe912ad: Bump to xamarin/xamarin-android-tools/main@26d65d9 (dotnet#741)
  * dotnet/java-interop@9c73dbff: [generator] Output correct formatting for binding warnings (dotnet#737)

Update `create-installers.targets` so that `LineEditor.pdb` is
included in the macOS `.pkg` and Windows `.vsix` installers.
jonpryor added a commit to jonpryor/xamarin-android that referenced this pull request Oct 20, 2020
Fixes: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1230070

Changes: dotnet/java-interop@b991bb8...da74abd

  * dotnet/java-interop@da74abd2: Bump to mono/LineEditor@3fa0c2eb (dotnet#740)
  * dotnet/java-interop@5fe912ad: Bump to xamarin/xamarin-android-tools/main@26d65d9 (dotnet#741)
  * dotnet/java-interop@9c73dbff: [generator] Output correct formatting for binding warnings (dotnet#737)

Update `create-installers.targets` so that `LineEditor.pdb` is
included in the macOS `.pkg` and Windows `.vsix` installers.
jonpryor added a commit that referenced this pull request Oct 21, 2020
Fixes: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1230070

Changes: dotnet/java-interop@b991bb8...da74abd

  * dotnet/java-interop@da74abd2: Bump to mono/LineEditor@3fa0c2eb (#740)
  * dotnet/java-interop@5fe912ad: Bump to xamarin/xamarin-android-tools/main@26d65d9 (#741)
  * dotnet/java-interop@9c73dbff: [generator] Output correct formatting for binding warnings (#737)

Update `create-installers.targets` so that `LineEditor.pdb` is
included in the macOS `.pkg` and Windows `.vsix` installers.
@github-actions github-actions bot locked and limited conversation to collaborators Feb 5, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants