-
Notifications
You must be signed in to change notification settings - Fork 534
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Mono.Android-Tests] Run Java.Interop tests as well. #3393
Conversation
c23af2a
to
fa2171c
Compare
Context: dotnet/android#3393 Allow the Java.Interop unit tests to be consumed by Xamarin.Android. In particular, this means: * "Proper" exceptions such as `Java.Lang.ClassNotFoundException` are thrown, not "based" `JavaException` types. * `Xamarin.Android.NUnitLite.dll` doesn't provide `[OneTimeSetUpAttribute]`/etc., so use `[TestFixtureSetUpAttribute]` instead. * Xamarin.Android doesn't currently support `Java.Interop.MarshalMemberBuilder`, so any tests which require it will not work. "Hide" those behind `#if !NO_MARSHAL_MEMBER_BUILDER_SUPPORT`.
8c8cc97
to
461407d
Compare
/azp run |
Azure Pipelines successfully started running 1 pipeline(s). |
98f08c1
to
9cb69cc
Compare
4c8a6e9
to
6f26867
Compare
6f26867
to
3828d57
Compare
<_BuildStatusFiles Include="$(XamarinAndroidSourcePath)bin\Test$(Configuration)\*.projitems" /> | ||
<_BuildStatusFiles Include="$(XamarinAndroidSourcePath)bin\Test$(Configuration)\*.cmake" /> | ||
<_BuildStatusFiles Include="$(XamarinAndroidSourcePath)bin\Test$(Configuration)\*.targets" /> | ||
<_BuildStatusFiles Include="$(XamarinAndroidSourcePath)external\Java.Interop\bin\Build$(Configuration)\*.props" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might not need the .targets, .projitems, or .props, since binlog files contain all the MSBuild sources at build time. You can view them easily on Windows with http://msbuildlog.com, and maybe unzip can get access to them on Mac?
/azp run |
Pull request contains merge conflicts. |
a12eff2
to
cd5a4f0
Compare
We actually finished running all the tests! ...and many tests fail (which is to be expected). For example, Mono.Android_Tests, Java.InteropTests.JniValueMarshaler_object_ContractTests.SpecificTypesAreUsed / Release:
This strongly suggests that Something Is Wrong, as we should be adding |
This is not quite right; we should not be adding No, the problem happens when |
Context: dotnet/android#3393 Context: https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=3247796&view=ms.vss-test-web.build-test-results-tab&runId=9790200&resultId=100160&paneView=debug In attempting to get Xamarin.Android to run the full compliement of Java.Interop unit tests, there is one set of tests which are still failing: the `JavaPrimitiveArrayContract.Constructor_Exceptions()` tests fail because the *linker* is executed, and the linker is removing the constructors which `Constructor_Exceptions()` relies on. Make `JavaPrimitiveArrayContract` linker-safe, and instead of using `System.Type.GetConstructor()` to get the constructor, introduce new `abstract` methods on `JavaPrimitiveArrayContract.CreateCollection()` which create instances of the appropriate type, using the appropriate constructor. This is more "linker friendly", as the linker can "see" that the constructors are used, which in turn should allow the tests to pass.
The unit test failures such as Mono.Android_Tests, Java.InteropTests.JavaBooleanArrayContractTests.JavaPrimitiveArrayContract`2.Constructor_Exceptions / Release should be addressed by: dotnet/java-interop#521 |
#521) Context: dotnet/android#3393 Context: https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=3247796&view=ms.vss-test-web.build-test-results-tab&runId=9790200&resultId=100160&paneView=debug In attempting to get Xamarin.Android to run the full compliement of Java.Interop unit tests, there is one set of tests which are still failing: the `JavaPrimitiveArrayContract.Constructor_Exceptions()` tests fail because the *linker* is executed, and the linker is removing the constructors which `Constructor_Exceptions()` relies on. Make `JavaPrimitiveArrayContract` linker-safe, and instead of using `System.Type.GetConstructor()` to get the constructor, introduce new `abstract` methods on `JavaPrimitiveArrayContract.CreateCollection()` which create instances of the appropriate type, using the appropriate constructor. This is more "linker friendly", as the linker can "see" that the constructors are used, which in turn should allow the tests to pass.
Context: dotnet/java-interop#454 Context: xamarin/monodroid@e318861e Context: dotnet@7d32ef3e6 Context: dotnet@1a2eb95 When use of `Java.Interop.dll` was originally added in xamarin/monodroid@e318861e, it didn't implement the "full" `JniRuntime` abstraction, which meant that until dotnet/android@1a2eb953, trying to instantiate a `JavaInt32Array` instance would result in a `NotImplementedException`, because `Android.Runtime.AndroidValueManager.AddPeer()` threw a `NotImplementedException`. Commit dotnet/android@1a2eb953 removed the exception but didn't *implement* `JniRuntime.JniValueManager.AddPeer()`, meaning even though a `JavaInt32Array` could be *instantiated*, it wouldn't *work* "properly", e.g. `JniRuntime.JniValueManager.PeekPeer()` wouldn't *find* the `JavaInt32Array` when given the same handle. This in turn "happened" because `Mono.Android-Tests.dll` never *executed* the unit tests for `Java.Interop.dll`, which it *couldn't* do, because it didn't fully support the semantics. Add the `Java.Interop.dll` unit tests to `Mono.Android-Tests.dll`, and fix `Mono.Android.dll` and company so that they can actually *pass*: * Add a new `Java.Interop-Tests.csproj` project to "host" the Java.Interop unit tests in a MonoAndroid-profile project. * Add `java-interop.jar` to the `javac` command line generated by `Jar.targets`, so that e.g. `com.xamarin.java_interop.ManagedPeer` can be used. * Update `Mono.Android.dll` so that the Java.Interop unit tests work. This includes "migrating" the (jobject => instance) mapping previously accessible via `Java.Lang.Object.GetObject<T>()` into `Android.Runtime.AndroidValueManager`. * `AndroidRuntime.GetExceptionForThrowable()` will now "unwrap" a `Java.Interop.JavaProxyThrowable` instance. * `AndroidTypeManager.GetSimpleReferences()` can't use `JNIEnv.GetJniName()` because that always returns `java/lang/Object`, even if a type can't be found, which breaks several Java.Interop unit tests. Use `JNIEnv.monodroid_typemap_managed_to_java()` instead. * `AndroidTypeManager.RegisterNativeMembers()` will now invoke `JniRuntime.JniTypeManager.RegisterNativeMembers()` when `methods` is empty, so that classes can handle their own registration. This was needed so that `Java.InteropTests.CallVirtualFromConstructorDerived` could actually be properly instantiated and participate in tests. * `Java.Interop.TypeManager.CreateProxy()` now supports Java.Interop-style `(ref JniObjectReference, JniObjectReferenceOptions)` constructors. * `Java.Interop.JavaObject` and `Java.Interop.JavaException` are now bridgeable types, and can participate in GC's. This means that e.g. `JavaInt32Array` instances won't be prematurely collected. TODO: * `Java.Lang.Object` should be updated to inherit from `Java.Interop.JavaObject` * `Java.Lang.Throwable` should be updated to inherit from `Java.Interop.JavaException` * `generator` needs to be updated to begin *avoiding* the `JNIEnv` methods, so that non-`Java.Lang.*`-inheriting types can be used.
Context: https://xamarinhq.slack.com/archives/C03CEGRUW/p1568076852178100 Using `$(MSBuildExtensionsPath)` didn't work, as it just took the "first" path, which isn't valid, resulting in attempts to use: /Library/Frameworks/Mono.framework/Versions/6.0.0/lib/mono/xbuild/Xamarin/Android/java-interop.jar which does not exist.
Context: https://github.com/xamarin/xamarin-android/pull Trying to build things on Windows fails: ...s\external\Java.Interop\src\Java.Interop\Java.Interop.targets(37,5): error MSB3073: The command """ -source 1.6 -target 1.6 -bootclasspath "" -d "obj\Debug\netstandard2.0\ji-classes" java\com\xamarin\java_interop\internal\JavaProxyObject.java java\com\xamarin\java_interop\internal\JavaProxyThrowable.java java\com\xamarin\java_interop\GCUserPeerable.java java\com\xamarin\java_interop\ManagedPeer.java" exited with code 9009. The problem is that `javac` isn't being used. Why? To help answer *that* question, it would be handy to have `bin/TestRelease/msbuild-build-tests.binlog`... which isn't uploaded. Update `reuslt-packaging.targets` so that we actually capture the `bin/Test$(Configuration)` files. Question: should this be in the build zip, or the tests zip? However, this does introduce a hypothesis: the build order! Xamarin.Android-Tests.sln -> Mono.Android-Tests.csproj Java.Interop-Tests.csproj Java.Interop.csproj `Java.Interop.csproj` is not in `Xamarin.Android-Tests.sln`, and thus it *appears* to be building it in the *Debug* configuration, while it should be using the *Release* configuration, so that it can find `external/Java.Interop/bin/BuildRelease/JdkInfo.props` (which is generated as part of build prep). This would explain why `$(JavaCPath)` isn't set! However, this in turn suggests a *different* issue: Insert @jonathanpeppers' PR for re-doing the build system, which we might need first. ...plus an equivalent in Java.Interop! We need to entirely separate tests from non-tests, for various reasons (TODO: lookup commit & msbuild file sharing & ....!) Java.Interop will need to follow suite, which in turn means that `Java.Interop-Tests.csproj` MUST NOT reference `Java.Interop.csproj`. Removing that "connection point" should allow things to work sanely.
To test the hypothesis in 3828d57, add `Java.Interop.csproj` to `Xamarin.Android-Tests.sln`. This will hopefully *prevent* `Java.Interop.csproj` from being built in the deug configuration, which in turn should allow Windows to *build*.
Context: https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=3232168&view=logs&j=8556562a-ae5f-5bd1-7c4d-bf1af4b6f1e1&t=5076e147-fc66-561e-6c69-3aa777afefc5 The unit tests are failing go build: /Users/runner/runners/2.160.0/work/1/s/external/Java.Interop/src/Java.Interop/Tests/Interop-Tests.projitems(11,3): error MSB4019: The imported project "/Users/runner/runners/2.160.0/work/1/s/external/Java.Interop/bin/BuildRelease/JdkInfo.props" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk. The problem is that for the "APK Instrumentation - macOS" job doesn't create `external/Java.Interop/bin/BuildRelease/JdkInfo.props`. Add a new `Step_PrepareExternalJavaInterop` step which creates `JdkInfo.props`, which should allow things to build. Move the previous `JdkInfo.props` generation logic out of `Step_PrepareExternal`, so that the `xaprepare -s:Required` can just build the required Java.Interop bits, and not "lots".
It finally built and started running tests! https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=3239656&view=logs&s=859b8d9a-8fd6-5a5c-6f5e-f84f1990894e&j=8556562a-ae5f-5bd1-7c4d-bf1af4b6f1e1 It crashes! #00 pc 001eb93c /data/app/Mono.Android_Tests-kS0jLDcPe9huyCD5kHs-cQ==/lib/x86/libmonosgen-2.0.so (mono_field_get_value+60) That's all the stack trace we get. :-( Hypothesis -- because I don't want to try building locally, ugh -- is that our types are missing required fields. Looking at `Mono.Android_Tests-Signed.apk`, and this hypothesis appears to be correct: `Java.Interop.JavaObject` lacks `refs_added` and `weak_handle` fields, while `Java.Lang.Object` contains them. Update src/monodroid to assert that the required fields exist, so that we can at minimum get a better error message. Update Xamarin.Android.Build.Tasks so that we add a linker XML file to explicitly preserve the required fields within JavaObject & JavaException.
Context: https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=3243746&view=results Now we have a decent error message! F monodroid: The type `Java.Lang.Throwable` is missing required instance fields! handle=0xd221e690 handle_type=0xd221e6b0 refs_added=0xd221e6c0 weak_handle=0x0 `Java.Lang.Throwable.weak_handle` isn't preserved! I'm not sure why it was (presumably?) previously preserved -- perhaps it wasn't! this needs verification -- but to address this fatal error and see if we can actually complete things, treat `Java.Lang.Object` and `Java.Lang.Throwable` the same way we treat `Java.Interop.JavaObject` and `Java.Interop.JavaException`.
Context: https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=3243934&view=ms.vss-test-web.build-test-results-tab&runId=9758256&resultId=100726&paneView=debug The tests are now able to build and run without crashing! Yay! Unfortunately many tests fail, e.g. Java.Lang.ClassNotFoundException : com.xamarin.java_interop.internal.JavaProxyObject Huh? Turns out that `Mono.Android-Tests` is using `$(AndroidLinkTool)`=r8, which links more Java code, which caused `com.xamarin.java_interop.internal.JavaProxyObject` and other types to be linked away! Oops! Update `proguard_xamarin.cfg` so that the `com.xamarin.java_interop.**` types are preserved. Add a new `src/Mono.Android/Test/proguard.cfg` file so that the Java types required by the unit tests are also preserved.
Context: https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=3261114&view=logs&j=65486226-8c87-5153-e73a-d57909d6ac16&t=0c4ab8a2-b502-54b1-2c2d-58f1af7b0279 The Designer tests failed! System.NotSupportedException: Cannot create instance of type 'Android.Runtime.UncaughtExceptionHandler': no Java peer type found. at Java.Interop.JniPeerMembers+JniInstanceMethods..ctor (System.Type declaringType) [0x00046] in <9cb9a310e5034526b407c7688775bf95>:0 at Java.Interop.JniPeerMembers+JniInstanceMethods.GetConstructorsForType (System.Type declaringType) [0x00031] in <9cb9a310e5034526b407c7688775bf95>:0 at Java.Interop.JniPeerMembers+JniInstanceMethods.StartCreateInstance (System.String constructorSignature, System.Type declaringType, Java.Interop.JniArgumentValue* parameters) [0x00038] in <9cb9a310e5034526b407c7688775bf95>:0 at Java.Lang.Object..ctor () [0x0001f] in /Users/runner/runners/2.160.1/work/1/s/src/Mono.Android/obj/Release/android-28/mcw/Java.Lang.Object.cs:30 at Android.Runtime.UncaughtExceptionHandler..ctor (Java.Lang.Thread+IUncaughtExceptionHandler defaultHandler) [0x00000] in /Users/runner/runners/2.160.1/work/1/s/src/Mono.Android/Android.Runtime/UncaughtExceptionHandler.cs:14 at Android.Runtime.JNIEnv.Initialize (Android.Runtime.JnienvInitializeArgs* args) [0x00159] in /Users/runner/runners/2.160.1/work/1/s/src/Mono.Android/Android.Runtime/JNIEnv.cs:156 ...which was rather odd. Why couldn't the Java peer type be found? The answer is that `AndroidRuntime.GetSimpleReferences()` *used to* call `JNIEnv.GetJniName(Type)`, which in turn would call `JavaNativeTypeManager.ToJniName(Type)`, which was really only useful on Desktop environments. The "updated" `AndroidRuntime.GetSimpleReferences()` stopped calling `JNIEnv.GetJniName()`, in order to fix one of the Java.Interop unit tests, which also meant that it stopped calling `JavaNativeTypeManager.ToJniName()`. This is why `UncaughtExceptionHandler` could not be found. When on desktop, continue calling `JavaNativeTypeManager.ToJniName()`.
Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object at Java.Interop.JniEnvironmentInfo..ctor () at Java.Interop.JniEnvironment+<>c.<.cctor>b__35_0 () at System.Threading.ThreadLocal`1[T].GetValueSlow () at System.Threading.ThreadLocal`1[T].get_Value () at Java.Interop.JniEnvironment.get_CurrentInfo () at Java.Interop.JniEnvironment.get_Runtime () at Java.Lang.Object.Finalize () Finalization order is indeterminate, and when the process is shutting down it's entirely plausible that a `Java.Lang.Object` instance will be finalized *after* the `JniRuntime` instance has been finalized (as `JniRuntime.Dispose()` will "dispose" all known `JniEnvironment` instances), at which point things will Faill Horribly. Update the `Java.Lang.Object` and `Java.Lang.Throwable` finalizers so that `JniEnvironment.Runtime` is not accessed when `Environment.HasShutdownStarted` is true.
dotnet/java-interop@dec2e390 changed how unit tests are structured and removed the shared projects which were previously used.
Context: dotnet/java-interop#538 Should fix the `JNI DETECTED ERROR IN APPLICATION` crash which was preventing the unit tests from completing successfully.
dotnet/java-interop#538 was merged, so d80020f is no longer necessary.
Context: https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=3315048&view=logs&jobId=96fd57f5-f69e-53c7-3d47-f67e6cf9b93e&j=8556562a-ae5f-5bd1-7c4d-bf1af4b6f1e1&t=5076e147-fc66-561e-6c69-3aa777afefc5 dotnet/java-interop@76d6e6dc removed Mono.Linq.Expressions as a submodule and replaced it with a NuGet package. Remove the `Mono.Linq.Expressions.csproj` references and replace with a `@(PackageReference)`. This change will hopefully allow tests to build now: Java.Interop/tests/Java.Interop-Tests/Java.Interop/JniValueMarshalerContractTests.cs(10,12): error CS0234: The type or namespace name 'Linq' does not exist in the namespace 'Mono' (are you missing an assembly reference?)
Context: https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=3317420&view=logs&jobId=cac0e8d3-0ef5-5d2b-b57e-e8fde7204df3&j=8556562a-ae5f-5bd1-7c4d-bf1af4b6f1e1&t=5076e147-fc66-561e-6c69-3aa777afefc5 Remember the "Remove Mono.Linq.Expressions" commit? The fix didn't fix things; we're still failing in the same way: .../Xamarin.Android.Common.targets(1694,2): error XA2002: Can not resolve reference: `Mono.Linq.Expressions`, referenced by `Java.Interop-Tests`. Please add a NuGet package or assembly reference for `Mono.Linq.Expressions`, or remove the reference to `Java.Interop-Tests`. Why? Because by moving to `@(PackageReference)`, we're now reliant on NuGet, and [NuGet Restore is failing][0] (?!) /Library/Frameworks/Mono.framework/Versions/Current/Commands/mono /Users/runner/hostedtoolcache/NuGet/5.4.0/x64/nuget.exe restore /Users/runner/runners/2.162.0/work/1/s/Xamarin.Android-Tests.sln -Verbosity Detailed -NonInteractive -ConfigFile /Users/runner/runners/2.162.0/work/1/Nuget/tempNuGet_3317420.config NuGet Version: 5.4.0.6315 MSBuild auto-detection: using msbuild version '15.0' from '/Library/Frameworks/Mono.framework/Versions/6.8.0/lib/mono/msbuild/15.0/bin'. Use option -MSBuildVersion to force nuget to use a specific version of MSBuild. MSBuild P2P timeout [ms]: 228000 /Library/Frameworks/Mono.framework/Versions/Current/Commands/msbuild "/var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/NuGetScratch/m9ak7i1i.nw0.nugetinputs.targets" /t:GenerateRestoreGraphFile /nologo /nr:false /v:q /p:NuGetRestoreTargets="/var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/NuGetScratch/6znzw9b3.kvw.nugetrestore.targets" /p:RestoreUseCustomAfterTargets="True" /p:RestoreTaskAssemblyFile="/Users/runner/hostedtoolcache/NuGet/5.4.0/x64/nuget.exe" /p:RestoreSolutionDirectory="/Users/runner/runners/2.162.0/work/1/s/" /p:RestoreConfigFile="/Users/runner/runners/2.162.0/work/1/Nuget/tempNuGet_3317420.config" /p:SolutionDir="/Users/runner/runners/2.162.0/work/1/s/" /p:SolutionName="Xamarin.Android-Tests" /p:RestoreBuildInParallel="False" /p:RestoreUseSkipNonexistentTargets="False" /Users/runner/runners/2.162.0/work/1/s/tests/BCL-Tests/Xamarin.Android.Bcl-Tests/Xamarin.Android.Bcl-Tests.targets(9,3): error MSB4019: The imported project "/Users/runner/runners/2.162.0/work/1/s/bin/Debug/bcl-tests/ProfileAssemblies.projitems" was not found. Confirm that the expression in the Import declaration "../../../bin/Debug/bcl-tests/ProfileAssemblies.projitems" is correct, and that the file exists on disk. [/Users/runner/runners/2.162.0/work/1/s/tests/BCL-Tests/Xamarin.Android.Bcl-Tests/Xamarin.Android.Bcl-Tests.csproj] /Users/runner/runners/2.162.0/work/1/s/build-tools/scripts/XAVersionInfo.targets(9,3): error MSB4019: The imported project "/Users/runner/runners/2.162.0/work/1/s/bin/BuildDebug/MonoGitHash.props" was not found. Confirm that the expression in the Import declaration "../../bin/BuildDebug/MonoGitHash.props" is correct, and that the file exists on disk. [/Users/runner/runners/2.162.0/work/1/s/build-tools/timing/timing.csproj] Of interest is the MSB4019 error...which is ignored, as the overall AzDO step is green. Best I can easily figure, `Java.Interop-Tests.csproj` is failing to build because it can't find `Mono.Linq.Expressions`: .../Xamarin.Android.Common.targets(1694,2): error XA2002: Can not resolve reference: `Mono.Linq.Expressions`, referenced by `Java.Interop-Tests`. Please add a NuGet package or assembly reference for `Mono.Linq.Expressions`, or remove the reference to `Java.Interop-Tests`. [/Users/runner/runners/2.162.0/work/1/s/src/Mono.Android/Test/Mono.Android-Tests.csproj] ...and it can't find `Mono.Linq.Expressions`, presumably, because the NuGet restore process didn't fully complete. Square this circle by adding a `/t:Restore` invocation as part of the `Mono.Android-Tests` invocation, so that (hopefully) the `Mono.Linq.Expressions` NuGet package will be installed & used. [0]: https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=3317420&view=logs&jobId=cac0e8d3-0ef5-5d2b-b57e-e8fde7204df3&j=8556562a-ae5f-5bd1-7c4d-bf1af4b6f1e1&t=b9294726-b793-5321-dfc7-34d7e8d44bdd
Attempting to use `@(PackageReference)` for `Mono.Linq.Expressions` continues to fail, even after PR dotnet#3995. Looking at the `msbuild Xamarin.Android /t:Prepare` output [^0], I see that there is a `nuget restore Xamarin.Android-Tests.sln`, and it does not always, and it restores numerous NuGet packages...but not Mono.Linq.Expressions. In the interest of any form of progress, use the "legacy" `packages.config`-style nuget reference, and see if that changes anything. [^0]: https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=3318737&view=logs&j=cac0e8d3-0ef5-5d2b-b57e-e8fde7204df3&t=b0ec5c6c-f5a1-5ebf-2068-57a5c78a6a85
Context: https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=3328422&view=logs&j=8556562a-ae5f-5bd1-7c4d-bf1af4b6f1e1&t=edd3bdba-6ec4-5961-ea81-8c75bc7c9371 The build failed: .../src/Mono.Android/Test/Xamarin.Android.RuntimeTests/TestInstrumentation.cs(24,39): error CS0234: The type or namespace name 'JavaInterop_Tests_Reference' does not exist in the namespace 'Java.InteropTests' (are you missing an assembly reference?) Add an appropriate `@(ProjectReference)`.
This is for consistency with `Mono.Android-Tests.csproj`; see also: 4bb4b2e
See also the "Preserve required types" commit. `Mono.Android_TestMultiDex` and `Mono.Android_TestsAppBundle` are failing because they can't resolve some Java types: Java.Lang.ClassNotFoundException : com.xamarin.interop.CallVirtualFromConstructorDerived at Java.Interop.JniEnvironment+Types.FindClass (System.String classname) at Java.Interop.JniType..ctor (System.String classname) at Java.Interop.JniType.GetCachedJniType (Java.Interop.JniType& cachedType, System.String classname) at Java.Interop.JniPeerMembers.get_JniPeerType () at Java.Interop.JniPeerMembers+JniStaticMethods.GetMethodInfo (System.String encodedMember) at Java.Interop.JniPeerMembers+JniStaticMethods.InvokeObjectMethod (System.String encodedMember, Java.Interop.JniArgumentValue* parameters) at Java.InteropTests.CallVirtualFromConstructorDerived.NewInstance (System.Int32 value) at Java.InteropTests.InvokeVirtualFromConstructorTests.ActivationConstructor () at (wrapper managed-to-native) System.Reflection.RuntimeMethodInfo.InternalInvoke(System.Reflection.RuntimeMethodInfo,object,object[],System.Exception&) at System.Reflection.RuntimeMethodInfo.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) --- End of managed Java.Lang.ClassNotFoundException stack trace --- java.lang.ClassNotFoundException: com.xamarin.interop.CallVirtualFromConstructorDerived at crc64f295cabbf85394f5.TestSuiteInstrumentation.n_onStart(Native Method) at crc64f295cabbf85394f5.TestSuiteInstrumentation.onStart(Unknown Source:0) at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2189) Add a `@(ProguardConfiguration)` entry to the appropriate projects so that these required types are preserved.
99fc831
to
21c2a18
Compare
Context: https://github.com/xamarin/monodroid/commit/e318861e
Context: 7d32ef3
Context: 1a2eb95
When use of
Java.Interop.dll
was originally added inxamarin/monodroid@e318861e, it didn't implement the "full"
Java.Interop.JniRuntime
abstraction, which meant that untilcommit 1a2eb95, trying to instantiate a
JavaInt32Array
instancewould result in a
NotImplementedException
, because ofAndroid.Runtime.AndroidValueManager.AddPeer()
.Commit 1a2eb95 removed the exception but didn't implement
JniRuntime.JniValueManager.AddPeer()
, meaning even though aJavaInt32Array
could be instantiated, it wouldn't work"properly", e.g.
JniRuntime.JniValueManager.PeekPeer()
wouldn'tfind the
JavaInt32Array
instance when given the same handle.This in turn "happened" because
Mono.Android-Tests.dll
neverexecuted the unit tests for
Java.Interop.dll
, which it couldn'tdo, because it didn't fully support the semantics.
Add the
Java.Interop.dll
unit tests toMono.Android-Tests.dll
, andfix
Mono.Android.dll
and company so that they can actually pass:Add a new
Java.Interop-Tests.csproj
project to "host" theJava.Interop unit tests in a MonoAndroid-profile project.
Add
java-interop.jar
to thejavac
command line generated byJar.targets
, so that e.g.com.xamarin.java_interop.ManagedPeer
can be used.
Update
Mono.Android.dll
so that the Java.Interop unit testswork. This includes "migrating" the (jobject => instance) mapping
previously accessible via
Java.Lang.Object.GetObject<T>()
intoAndroid.Runtime.AndroidValueManager
.AndroidRuntime.GetExceptionForThrowable()
will now "unwrap" aJava.Interop.JavaProxyThrowable
instance.AndroidTypeManager.GetSimpleReferences()
can't useJNIEnv.GetJniName()
on-device because that always returnsjava/lang/Object
, even if a type can't be found, which breaksseveral Java.Interop unit tests. Use
JNIEnv.monodroid_typemap_managed_to_java()
instead.AndroidTypeManager.RegisterNativeMembers()
will now invokeJniRuntime.JniTypeManager.RegisterNativeMembers()
whenmethods
is empty, so that classes can handle their own registration. This
was needed so that
Java.InteropTests.CallVirtualFromConstructorDerived
couldactually be properly instantiated and participate in tests.
Java.Interop.TypeManager.CreateProxy()
now supportsJava.Interop-style
(ref JniObjectReference, JniObjectReferenceOptions)
constructors.
Java.Interop.JavaObject
andJava.Interop.JavaException
are nowbridgeable types, and can participate in GC's.
This means that e.g.
JavaInt32Array
instances won't beprematurely collected.
src/monodroid
will also verify that bridgeable types containthe fields required for use, and provide a better error message
when any fields are missing.
The
Java.Lang.Object
andJava.Lang.Throwable
finalizers mustcheck
Environment.HasShutdownStarted
before usingJniEnvironment.Runtime
, as finalization order is unspecified,so the
JniRuntime
instance may have been finalized first.With the new changes, the size of
Xamarin.Forms_Performance_Integration-Signed.apk
increases by ~4kb.I consider this negligible.
App startup time isn't significantly impacted either: the average of
five
Xamarin.Forms_Performance_Integration
app launches is 706.2mswith these changes, vs. 706.8ms without these changes.
Other Build System Changes:
Set
$(AndroidLinkMode)
=r8 in various projects for consistencywith 4bb4b2e.
Make
Mono.Android-Tests
debuggable in Release config, so thatGREF logs/etc. can be easily extracted from device, if necessary.
Split up
external/Java.Interop
checkout & preparation logic sothat it is usable within unit test environments, which don't
contain a full build tree.
Add some build-time test-related artifacts to
@(_BuildStatusFiles)
so that build-time log files are kept.TODO:
Java.Lang.Object
should be updated to inherit fromJava.Interop.JavaObject
Java.Lang.Throwable
should be updated to inherit fromJava.Interop.JavaException
generator
needs to be updated to begin avoiding theJNIEnv
methods, so that non-
Java.Lang.*
-inheriting types can be used.