-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Java.Interop] Optional "Standalone" Build Config (#1049)
Context: 16e1ecd Context: 312fbf4 It occurs to me that it would be easier for "external" developers to use `Java.Interop.dll` if it didn't require building and distributing any native libraries. Furthermore, as of commit 312fbf4 (C#9 function pointer backend), it's *plausible* to make that work. Let's do so. Add a new `$(Standalone)` "configuration" property to `src\Java.Interop\Java.Interop.csproj`; when True, the `FEATURE_JNIENVIRONMENT_JI_FUNCTION_POINTERS` compiler define is set instead of the `FEATURE_JNIENVIRONMENT_JI_PINVOKES` define. This enables `JniEnvironment` to use C#9 function pointers instead of P/Invokes to invoke the `JNIEnv` function pointers. % dotnet build src/Java.Interop/Java.Interop.csproj -p:Standalone=True % ikdasm src/Java.Interop/obj/Debug/net7.0/Java.Interop.dll | grep pinvoke # no matches # If `-p:Standalone=True` isn't set, then there are 188 matches. Update `Java.Interop.dll` to compile when `FEATURE_JNIENVIRONMENT_JI_FUNCTION_POINTERS` is set. !!ABI BREAK!! `[Obsolete]` the method `JniRuntime.GetAvailableInvocationPointers()`. In retrospect this never should have been exposed at this level of the stack, and its existence was responsible for "really really bizarre" .NET Android [app crashes][0] (due to static constructor orderings) when *sometimes* `JniRuntime.Current` wasn't set "early enough": D Mono : AOT: FOUND method Java.Interop.JniRuntime:GetAvailableInvocationPointers () [0x78e4da7960 - 0x78e4da7a7c 0x78e4de6840] D Mono : AOT: FOUND method Java.Interop.JniRuntime:GetCreatedJavaVMs (intptr[],int,int&) [0x78e4ddd2b0 - 0x78e4ddd300 0x78e4de6bcd] D Mono : AOT: NOT FOUND: Java.Interop.NativeMethods:java_interop_jvm_list (intptr[],int,int&). F monodroid-assembly: Internal p/invoke symbol 'java-interop @ java_interop_jvm_list' (hash: 0x58c48fc8b89cb484) not found in compile-time map. *Nobody* should be using this method, largely given that only Xamarin.Android and .NET Android apps currently use `Java.Interop.dll`, and neither use `JniRuntime.GetAvailableInvocationPointers()`. Furthermore, it *can't* work on Android, as Android doesn't provide a public [`JNI_GetCreatedJavaVMs()`][1] symbol. Update `build-tools/jnienv-gen` so that a `JniNativeMethods` class is created which contains "human usable" ways to invoke `JNIEnv` function pointers. (Nobody wants to copy the expression `(*((JNIEnv**)env))->ExceptionClear(env)` more than once, ever. `JniNativeMethods.ExceptionClear(env)` is much nicer to write.) Update `samples/Hello-Core` so that it sets `Standalone=True`. Verification: After building `samples/Hello-Core`, the contained `Java.Interop.dll` doesn't contain any `pinvokeimpl` methods: % dotnet build samples/Hello-Core % ikdasm samples/Hello-Core/bin/Debug/Java.Interop.dll | grep pinvoke # no matches TODO: I also attempted to reduce the number of P/Invokes in `Java.Runtime.Environment.dll`, with the hope that when *not* using MonoVM it could be used without a native `java-interop` library. This used [`System.Runtime.InteropServices.NativeLibrary`][2] to load `JniRuntime.CreationOptions.JvmLibraryPath` and invoke the `JNI_CreateJavaVM()` and `JNI_GetCreatedJavaVMs()` exports. Unfortunately, this new backend crashes inexplicably when using `dotnet test`. The backend can now be selected by setting the `JI_LOADER_TYPE` environment variable to one of: * `native-library`: the `NativeLibrary` backened, or * `java-interop`: the previous `java-interop` native lib backend. This allows testing to work and CI to succeed: % dotnet test bin/TestDebug-net7.0/Java.Interop-Tests.dll # all good while allowing us to separately explore why it crashes: % JI_LOADER_TYPE=native-library dotnet test bin/TestDebug-net7.0/Java.Interop-Tests.dll … # jonp: LoadJvmLibrary(…/libjli.dylib)=9056174496 # jonp: JNI_CreateJavaVM=4561133901; JNI_GetCreatedJavaVMs=4561133970 # jonp: executing JNI_CreateJavaVM=10fdd614d Error occurred during initialization of VM Could not reserve enough space in CodeHeap 'non-nmethods' (2496K) The active test run was aborted. Reason: Test host process crashed Test Run Aborted with error System.Exception: One or more errors occurred. ---> System.Exception: Unable to read beyond the end of the stream. at System.IO.BinaryReader.Read7BitEncodedInt() at System.IO.BinaryReader.ReadString() at Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.LengthPrefixCommunicationChannel.NotifyDataAvailable() at Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.TcpClientExtensions.MessageLoopAsync(TcpClient client, ICommunicationChannel channel, Action`1 errorHandler, CancellationToken cancellationToken) --- End of inner exception stack trace ---. [0]: https://discord.com/channels/732297728826277939/732297837953679412/979054761603125319 [1]: https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/invocation.html#JNI_GetCreatedJavaVMs [2]: https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.nativelibrary?view=net-7.0
- Loading branch information
Showing
12 changed files
with
1,799 additions
and
374 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.