Skip to content

Commit

Permalink
[Java.Interop.BootstrapTasks] Filter out invalid JDKs (#1278)
Browse files Browse the repository at this point in the history
@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.
  • Loading branch information
jonpryor authored Nov 13, 2024
1 parent 2440416 commit 14f94a5
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<LangVersion>11.0</LangVersion>
</PropertyGroup>

<Import Project="..\..\TargetFrameworkDependentValues.props" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml.Linq;
Expand Down Expand Up @@ -46,6 +47,7 @@ public override bool Execute ()
.Where (j => maxVersion != null ? j.Version <= maxVersion : true)
.Where (j => j.IncludePath.Any ());
var jdk = explicitJdks.Concat (defaultJdks)
.Where (j => JdkRunsOnHost (j))
.FirstOrDefault ();

if (jdk == null) {
Expand All @@ -71,6 +73,19 @@ public override bool Execute ()
return !Log.HasLoggedErrors;
}

static bool JdkRunsOnHost (XATInfo jdk)
{
var cputype = RuntimeInformation.ProcessArchitecture;
if (jdk.ReleaseProperties.TryGetValue ("OS_ARCH", out var arch)) {
return (cputype, arch) switch {
(Architecture.Arm64, "aarch64") => true,
(Architecture.X64, "x86_64") => true,
_ => false,
};
}
return true;
}

XATInfo[] GetJdkRoots ()
{
XATInfo jdk = null;
Expand Down

0 comments on commit 14f94a5

Please sign in to comment.