Skip to content
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

[Java.Interop.BootstrapTasks] Filter out invalid JDKs #1278

Merged
merged 1 commit into from
Nov 13, 2024

Conversation

jonpryor
Copy link
Member

@jonpryor's developer machines are a "weird", with a macOS arm64 box containing the directories:

  • $HOME/android-toolchain/jdk-17
  • $HOME/android-toolchain/jdk-17.x64

Meanwhile, XAPrepareJdkLocations.GetXAPrepareJdks() within dotnet/android-tools looks for all directories matching the glob $HOME/android-toolchains/jdk*, and thus finds both.

For some reason, the JDK that dotnet build -t:Prepare *.sln winds up using by default is the the jdk-17.x64 directory (😱), which cannot be loaded into an arm64 process. This results in errors from dotnet build:

EXEC : error JM4003: jnimarshalmethod-gen: Unable to create Java VM […/dotnet/java-interop/samples/Hello-NativeAOTFromJNI/Hello-NativeAOTFromJNI.csproj]
  System.DllNotFoundException: Unable to load shared library '$HOME/android-toolchain/jdk-17.x64/lib/libjli.dylib' or one of its dependencies. In order to help diagnose loading problems, consider setting the DYLD_PRINT_LIBRARIES environment variable:
  dlopen($HOME/android-toolchain/jdk-17.x64/lib/libjli.dylib, 0x0001): tried: '$HOME/android-toolchain/jdk-17.x64/lib/libjli.dylib' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64e' or 'arm64')), '/System/Volumes/Preboot/Cryptexes/OS/$HOME/android-toolchain/jdk-17.x64/lib/libjli.dylib' (no such file), '$HOME/android-toolchain/jdk-17.x64/lib/libjli.dylib' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64e' or 'arm64'))
     at System.Runtime.InteropServices.NativeLibrary.Load(String libraryPath)
     at Java.Interop.NativeLibraryJvmLibraryHandler.LoadJvmLibrary(String path) in $HOME/Developer/src/dotnet/java-interop/src/Java.Runtime.Environment/Java.Interop/JreRuntime.cs:line 231
     at Java.Interop.JreRuntime.CreateJreVM(JreRuntimeOptions builder) in $HOME/Developer/src/dotnet/java-interop/src/Java.Runtime.Environment/Java.Interop/JreRuntime.cs:line 104
     at Java.Interop.JreRuntime..ctor(JreRuntimeOptions builder) in $HOME/Developer/src/dotnet/java-interop/src/Java.Runtime.Environment/Java.Interop/JreRuntime.cs:line 162
     at Java.Interop.JreRuntimeOptions.CreateJreVM() in $HOME/Developer/src/dotnet/java-interop/src/Java.Runtime.Environment/Java.Interop/JreRuntime.cs:line 66
     at Xamarin.Android.Tools.JniMarshalMethodGenerator.App.CreateJavaVM(String jvmDllPath) in $HOME/Developer/src/dotnet/java-interop/tools/jnimarshalmethod-gen/App.cs:line 302
…
…/dotnet/java-interop/samples/Hello-NativeAOTFromJNI/Hello-NativeAOTFromJNI.targets(44,5):
  error MSB3073: The command ""/usr/local/share/dotnet/dotnet" "…/dotnet/java-interop/bin/Debug-net8.0//jnimarshalmethod-gen.dll" "…/dotnet/java-interop/samples/Hello-NativeAOTFromJNI/bin/Debug/Hello-NativeAOTFromJNI.dll" -v -v --keeptemp -L "…/dotnet/java-interop/samples/Hello-NativeAOTFromJNI/bin/Debug/" "
  exited with code 3. […/dotnet/java-interop/samples/Hello-NativeAOTFromJNI/Hello-NativeAOTFromJNI.csproj]

Instead of doing the "obvious" of removing jdk.x64 or renaming it so it doesn't match the glob jdk*, update
JdkInfo.GetKnownSystemJdkInfos() and JdkInfo.GetSupportedJdkInfos() to filter out JDKs that cannot be loaded into the current process. This nicely filters out jdk-17.x64, allowing dotnet/java-interop to build successfully.

@jonpryor's developer machines are a "weird", with a macOS arm64 box
containing the directories:

  * `$HOME/android-toolchain/jdk-17`
  * `$HOME/android-toolchain/jdk-17.x64`

Meanwhile, `XAPrepareJdkLocations.GetXAPrepareJdks()` within
dotnet/android-tools looks for all directories matching the glob
`$HOME/android-toolchains/jdk*`, and thus finds both.

For some reason, the JDK that `dotnet build -t:Prepare *.sln` winds
up using by default is the the `jdk-17.x64` directory (😱), which
cannot be loaded into an arm64 process.  This results in errors from
`dotnet build`:

	EXEC : error JM4003: jnimarshalmethod-gen: Unable to create Java VM […/dotnet/java-interop/samples/Hello-NativeAOTFromJNI/Hello-NativeAOTFromJNI.csproj]
	  System.DllNotFoundException: Unable to load shared library '$HOME/android-toolchain/jdk-17.x64/lib/libjli.dylib' or one of its dependencies. In order to help diagnose loading problems, consider setting the DYLD_PRINT_LIBRARIES environment variable:
	  dlopen($HOME/android-toolchain/jdk-17.x64/lib/libjli.dylib, 0x0001): tried: '$HOME/android-toolchain/jdk-17.x64/lib/libjli.dylib' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64e' or 'arm64')), '/System/Volumes/Preboot/Cryptexes/OS/$HOME/android-toolchain/jdk-17.x64/lib/libjli.dylib' (no such file), '$HOME/android-toolchain/jdk-17.x64/lib/libjli.dylib' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64e' or 'arm64'))
	     at System.Runtime.InteropServices.NativeLibrary.Load(String libraryPath)
	     at Java.Interop.NativeLibraryJvmLibraryHandler.LoadJvmLibrary(String path) in $HOME/Developer/src/dotnet/java-interop/src/Java.Runtime.Environment/Java.Interop/JreRuntime.cs:line 231
	     at Java.Interop.JreRuntime.CreateJreVM(JreRuntimeOptions builder) in $HOME/Developer/src/dotnet/java-interop/src/Java.Runtime.Environment/Java.Interop/JreRuntime.cs:line 104
	     at Java.Interop.JreRuntime..ctor(JreRuntimeOptions builder) in $HOME/Developer/src/dotnet/java-interop/src/Java.Runtime.Environment/Java.Interop/JreRuntime.cs:line 162
	     at Java.Interop.JreRuntimeOptions.CreateJreVM() in $HOME/Developer/src/dotnet/java-interop/src/Java.Runtime.Environment/Java.Interop/JreRuntime.cs:line 66
	     at Xamarin.Android.Tools.JniMarshalMethodGenerator.App.CreateJavaVM(String jvmDllPath) in $HOME/Developer/src/dotnet/java-interop/tools/jnimarshalmethod-gen/App.cs:line 302
	…
	…/dotnet/java-interop/samples/Hello-NativeAOTFromJNI/Hello-NativeAOTFromJNI.targets(44,5):
	  error MSB3073: The command ""/usr/local/share/dotnet/dotnet" "…/dotnet/java-interop/bin/Debug-net8.0//jnimarshalmethod-gen.dll" "…/dotnet/java-interop/samples/Hello-NativeAOTFromJNI/bin/Debug/Hello-NativeAOTFromJNI.dll" -v -v --keeptemp -L "…/dotnet/java-interop/samples/Hello-NativeAOTFromJNI/bin/Debug/" "
	  exited with code 3. […/dotnet/java-interop/samples/Hello-NativeAOTFromJNI/Hello-NativeAOTFromJNI.csproj]

Instead of doing the "obvious" of removing `jdk.x64` or renaming it
so it doesn't match the glob `jdk*`, update
`JdkInfo.GetKnownSystemJdkInfos()` and `JdkInfo.GetSupportedJdkInfos()`
to filter out JDKs that cannot be loaded into the current process.
This nicely filters out `jdk-17.x64`, allowing dotnet/java-interop
to build successfully.
@jonpryor jonpryor merged commit 14f94a5 into main Nov 13, 2024
4 checks passed
@jonpryor jonpryor deleted the dev/jonp/jonp-filter-jdks-for-host branch November 13, 2024 18:10
jonpryor pushed a commit to dotnet/android that referenced this pull request Dec 6, 2024
Fixes: dotnet/java-interop#1258

Changes: dotnet/java-interop@2440416...2d48efe

  * dotnet/java-interop@2d48efe7: [build] `main` *conceptually* targets .NET 10 (dotnet/java-interop#1283)
  * dotnet/java-interop@356485ee: [generator] Remove `JNINativeWrapper.CreateDelegate` from bindings (dotnet/java-interop#1275)
  * dotnet/java-interop@14f94a57: [Java.Interop.BootstrapTasks] Filter out invalid JDKs (dotnet/java-interop#1278)

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
@github-actions github-actions bot locked and limited conversation to collaborators Dec 14, 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.

2 participants