diff --git a/build-tools/Java.Interop.BootstrapTasks/Java.Interop.BootstrapTasks.targets b/build-tools/Java.Interop.BootstrapTasks/Java.Interop.BootstrapTasks.targets
index b84077bf8..54db188c7 100644
--- a/build-tools/Java.Interop.BootstrapTasks/Java.Interop.BootstrapTasks.targets
+++ b/build-tools/Java.Interop.BootstrapTasks/Java.Interop.BootstrapTasks.targets
@@ -1,93 +1,5 @@
-
-
- <_MonoInfoLine Include="<Project>" />
- <_MonoInfoLine Include=" <Choose>" />
- <_MonoInfoLine Include=" <When Condition=" %27%24(MonoFrameworkPath)%27 == %27%27 ">" />
- <_MonoInfoLine Include=" <PropertyGroup>" />
- <_MonoInfoLine Include=" <MonoFrameworkPath>$(_MonoFrameworkPath)</MonoFrameworkPath>" />
- <_MonoInfoLine Include=" <MonoLibs >$(_MonoLibs)</MonoLibs>" />
- <_MonoInfoLine Include=" </PropertyGroup>" />
- <_MonoInfoLine Include=" <ItemGroup>" />
- <_MonoInfoLine Include=" <MonoIncludePath Include="$(_MonoIncludePath)" />" />
- <_MonoInfoLine Include=" </ItemGroup>" />
- <_MonoInfoLine Include=" </When>" />
- <_MonoInfoLine Include=" </Choose>" />
- <_MonoInfoLine Include="</Project>" />
-
-
-
-
-
-
-
- <_MonoMkLine Include="JI_MONO_LIB_PATH=$(_MonoLibPath)" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- <_MonoLibPath>$([System.IO.Path]::GetDirectoryName($(_MonoPath)))/../lib/
- <_MonoFrameworkPath>$(_MonoPkgConfigLibdir)/libmonosgen-2.0.so
- <_MonoIncludePath>$(_MonoPkgConfigIncludedir)
- <_MonoLibs>-L "$(_MonoPkgConfigLibdir)" -lmonosgen-2.0
-
-
-
-
-
- <_MonoBase>/Library/Frameworks/Mono.framework/
- <_MonoLibPath>$(_MonoBase)Libraries/
- <_MonoFrameworkPath>$(_MonoLibPath)libmonosgen-2.0.1.dylib
- <_MonoIncludePath>$(_MonoBase)Headers/mono-2.0
- <_MonoLibs>-L "$(_MonoLibPath)" -lmonosgen-2.0
-
-
-
-
- $(OutputPath)$(AssemblyName).jar
+ $(AssemblyName).jar
@@ -32,7 +32,7 @@
@@ -43,8 +43,16 @@
<_JavaManagedBindingDir>$(_JavaIntermediateDir)mcw\
<_JavaJcwClassesDir>$(_JavaIntermediateDir)classes\
<_JavaJcwSourcesDir>$(_JavaIntermediateDir)java\
+ <_JavaOutputJarPath>$(_JavaIntermediateDir)$(JavaOutputJarName)
+
+
+
+
<_JavaCompileForBindingInputs
@@ -169,8 +177,8 @@
@@ -184,7 +192,7 @@
<_Output>-o "$(_JavaJcwSourcesDir)."
<_Libpath>@(_RefAsmDirs->'-L "%(Identity)"', ' ')
-
+
@@ -197,7 +205,7 @@
+ Outputs="$(_JavaOutputJarPath)">
@@ -215,7 +223,11 @@
/>
-
+
+
+
+
+
diff --git a/samples/Hello-Java.Base/Program.cs b/samples/Hello-Java.Base/Program.cs
index 733590374..ea23ff85e 100644
--- a/samples/Hello-Java.Base/Program.cs
+++ b/samples/Hello-Java.Base/Program.cs
@@ -17,16 +17,18 @@ class App
public static void Main (string[] args)
{
- string? jvmPath = global::Java.InteropTests.TestJVM.GetJvmLibraryPath ();
+ var logger = (Action?) null;
+ string? jvmPath = null;
bool createMultipleVMs = false;
bool reportTiming = false;
bool showHelp = false;
+ int verbosity = 0;
var options = new OptionSet () {
"Using the JVM from C#!",
"",
"Options:",
{ "jvm=",
- $"{{PATH}} to JVM to use. Default is:\n {jvmPath}",
+ $"{{PATH}} to JVM to use. Default is:\n{Java.InteropTests.TestJVM.GetJvmLibraryPath (logger)}",
v => jvmPath = v },
{ "m",
"Create multiple Java VMs. This will likely crash.",
@@ -34,6 +36,15 @@ public static void Main (string[] args)
{ "t",
$"Timing; invoke Object.hashCode() {N} times, print average.",
v => reportTiming = v != null },
+ { "v|verbosity:",
+ $"Set console log verbosity to {{LEVEL}}. Default is 0.",
+ (int? v) => {
+ verbosity = v.HasValue ? v.Value : verbosity + 1;
+ if (verbosity > 0) {
+ logger = CreateConsoleLogger ();
+ }
+ }
+ },
{ "h|help",
"Show this message and exit.",
v => showHelp = v != null },
@@ -45,7 +56,7 @@ public static void Main (string[] args)
}
var builder = new JreRuntimeOptions () {
JniAddNativeMethodRegistrationAttributePresent = true,
- JvmLibraryPath = jvmPath,
+ JvmLibraryPath = jvmPath ?? global::Java.InteropTests.TestJVM.GetJvmLibraryPath (logger),
ClassPath = {
Path.Combine (Path.GetDirectoryName (typeof (App).Assembly.Location)!, "Hello-Java.Base.jar"),
},
@@ -70,6 +81,13 @@ public static void Main (string[] args)
CreateJLO ();
}
+ static Action CreateConsoleLogger ()
+ {
+ return (level, message) => {
+ Console.WriteLine ($"# {level}: {message}");
+ };
+ }
+
static void CreateJLO ()
{
var jlo = new MyJLO ();
diff --git a/src/Java.Interop/Java.Interop/JniRuntime.cs b/src/Java.Interop/Java.Interop/JniRuntime.cs
index 5b9f0ed1f..6af5e5c1a 100644
--- a/src/Java.Interop/Java.Interop/JniRuntime.cs
+++ b/src/Java.Interop/Java.Interop/JniRuntime.cs
@@ -445,8 +445,9 @@ public virtual void OnEnterMarshalMethod ()
public virtual void OnUserUnhandledException (ref JniTransition transition, Exception e)
{
transition.SetPendingException (e);
-
+#if NET9_0_OR_GREATER
Debugger.BreakForUserUnhandledException (e);
+#endif // NET9_0_OR_GREATER
}
public virtual void RaisePendingException (Exception pendingException)
diff --git a/src/Java.Runtime.Environment/Java.Interop/JreRuntime.cs b/src/Java.Runtime.Environment/Java.Interop/JreRuntime.cs
index 8da7d8909..dd0912bf4 100644
--- a/src/Java.Runtime.Environment/Java.Interop/JreRuntime.cs
+++ b/src/Java.Runtime.Environment/Java.Interop/JreRuntime.cs
@@ -91,8 +91,9 @@ static unsafe JreRuntimeOptions CreateJreVM (JreRuntimeOptions builder)
builder.TypeManager ??= new JreTypeManager (builder.typeMappings);
#endif // NET
- bool onMono = Type.GetType ("Mono.Runtime", throwOnError: false) != null;
+ bool onMono = Type.GetType ("Mono.RuntimeStructs", throwOnError: false) != null;
if (onMono) {
+ Console.WriteLine ($"MonoVM support enabled");
builder.ValueManager = builder.ValueManager ?? new MonoRuntimeValueManager ();
builder.ObjectReferenceManager = builder.ObjectReferenceManager ?? new MonoRuntimeObjectReferenceManager ();
}
diff --git a/src/java-interop/.gitignore b/src/java-interop/.gitignore
index b44e02a75..dd69cf665 100644
--- a/src/java-interop/.gitignore
+++ b/src/java-interop/.gitignore
@@ -1,2 +1,3 @@
+coreclr.exp
jni.c
jni.g.cs
diff --git a/src/java-interop/CMakeLists.txt b/src/java-interop/CMakeLists.txt
index 5ab5e2a6c..e5c70c813 100644
--- a/src/java-interop/CMakeLists.txt
+++ b/src/java-interop/CMakeLists.txt
@@ -1,4 +1,4 @@
-set(CMAKE_OSX_ARCHITECTURES x86_64 arm64)
+cmake_minimum_required(VERSION 3.10.2)
project(
java-interop
@@ -14,8 +14,9 @@ set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
option(ENABLE_MONO_INTEGRATION "Require Mono runtime" OFF)
+option(ENABLE_OSX_ARCHITECTURES "macOS architectures" "")
-cmake_minimum_required(VERSION 3.10.2)
+set(CMAKE_OSX_ARCHITECTURES ${ENABLE_OSX_ARCHITECTURES})
set(JAVA_INTEROP_CORE_SOURCES
java-interop-dlfcn.cc
@@ -44,7 +45,6 @@ if(ENABLE_MONO_INTEGRATION)
include_directories(${dir})
endforeach()
list(APPEND LINK_FLAGS ${MONO_LINK_FLAGS})
- list(APPEND LINK_FLAGS "-Wl,-undefined -Wl,suppress -Wl,-flat_namespace")
set(JAVA_INTEROP_SOURCES ${JAVA_INTEROP_CORE_SOURCES} ${JAVA_INTEROP_MONO_SOURCES})
else()
set(JAVA_INTEROP_SOURCES ${JAVA_INTEROP_CORE_SOURCES})
diff --git a/src/java-interop/coreclr.def b/src/java-interop/coreclr.def
new file mode 100644
index 000000000..6eb946c9e
--- /dev/null
+++ b/src/java-interop/coreclr.def
@@ -0,0 +1,20 @@
+LIBRARY CORECLR
+
+EXPORTS
+ mono_class_from_mono_type
+ mono_class_get_field_from_name
+ mono_class_get_name
+ mono_class_get_namespace
+ mono_class_is_subclass_of
+ mono_class_vtable
+ mono_domain_get
+ mono_field_get_value
+ mono_field_set_value
+ mono_field_static_set_value
+ mono_gc_register_bridge_callbacks
+ mono_gc_wait_for_bridge_processing
+ mono_object_get_class
+ mono_thread_attach
+ mono_thread_current
+ mono_thread_get_managed_id
+ mono_thread_get_name_utf8
diff --git a/src/java-interop/coreclr.lib b/src/java-interop/coreclr.lib
new file mode 100644
index 000000000..aa421bc7b
Binary files /dev/null and b/src/java-interop/coreclr.lib differ
diff --git a/src/java-interop/java-interop-gc-bridge-mono.cc b/src/java-interop/java-interop-gc-bridge-mono.cc
index 7d8588432..aca306c60 100644
--- a/src/java-interop/java-interop-gc-bridge-mono.cc
+++ b/src/java-interop/java-interop-gc-bridge-mono.cc
@@ -3,7 +3,6 @@
#include
#include
#include
-#include
#include
#include "java-interop.h"
@@ -12,6 +11,7 @@
#include "java-interop-util.h"
#ifdef _WINDOWS
+#include
#include
#endif
@@ -530,13 +530,21 @@ get_object_ref_type (JNIEnv *env, jobject handle)
static int
gref_inc (JavaInteropGCBridge *bridge)
{
+#if _WINDOWS
+ return InterlockedIncrement ((LONG volatile*) &bridge->gc_gref_count);
+#else // !_WINDOWS
return __sync_add_and_fetch (&bridge->gc_gref_count, 1);
+#endif // _!WINDOWS
}
static int
gref_dec (JavaInteropGCBridge *bridge)
{
+#if _WINDOWS
+ return InterlockedDecrement ((LONG volatile*) &bridge->gc_gref_count);
+#else // !_WINDOWS
return __sync_sub_and_fetch (&bridge->gc_gref_count, 1);
+#endif // _!WINDOWS
}
#if defined (ANDROID)
diff --git a/src/java-interop/java-interop-mono.h b/src/java-interop/java-interop-mono.h
index 4cfb6a3a1..16ec344a5 100644
--- a/src/java-interop/java-interop-mono.h
+++ b/src/java-interop/java-interop-mono.h
@@ -4,6 +4,7 @@
#include "java-interop.h"
#include
+#include
#include
#include
#include
diff --git a/src/java-interop/java-interop.csproj b/src/java-interop/java-interop.csproj
index 4ca20ea66..99d8d778f 100644
--- a/src/java-interop/java-interop.csproj
+++ b/src/java-interop/java-interop.csproj
@@ -28,7 +28,18 @@
-
+
+
+
+ 8.0.13
+
+
+
+
+
diff --git a/src/java-interop/java-interop.targets b/src/java-interop/java-interop.targets
index eaefe2c11..9d35aaa47 100644
--- a/src/java-interop/java-interop.targets
+++ b/src/java-interop/java-interop.targets
@@ -8,25 +8,10 @@
<_JavaInteropLibName Condition=" $([MSBuild]::IsOSPlatform ('windows')) ">java-interop.dll
-
- <_JavaInteropNativeLib Include="CMakeLists.txt">
- x86_amd64
- win-x64\
-
- <_JavaInteropNativeLib Include="CMakeLists.txt">
- x86
- win-x86\
-
-
-
-
- <_JavaInteropNativeLib Include="CMakeLists.txt" />
-
-
-
+
PreserveNewest
- %(Dir)$(_JavaInteropLibName)
+ $(_JavaInteropLibName)
@@ -39,42 +24,54 @@
-
-
-
-
+
+
+ <_PrepareArch Condition=" '$(NETCoreSdkRuntimeIdentifier)' == 'win-x64' ">x86_amd64
+
-
-
- <_MonoDirs>"-DMONO_INCLUDE_LIST=@(MonoIncludePath, ';')"
- <_MonoLib>"-DMONO_LINK_FLAGS=$(MonoLibs)"
- <_EnableMono>-DENABLE_MONO_INTEGRATION=ON
+
+ <_CmakeOsxArch Condition=" '$(NETCoreSdkRuntimeIdentifier)' == 'osx-x64' ">x86_64
+ <_CmakeOsxArch Condition=" '$(NETCoreSdkRuntimeIdentifier)' == 'osx-arm64' ">arm64
+
- <_JdkDirs>"-DJDK_INCLUDE_LIST=@(JdkIncludePath, ';')"
- <_Jni_c>"-DJNI_C_PATH=$(MSBuildThisFileDirectory)$(IntermediateOutputPath)jni.c"
- <_ExtraArgs>$([MSBuild]::Escape('$(_JdkDirs) $(_Jni_c) $(_EnableMono) $(_MonoDirs) $(_MonoLib)'))
+ <_MonoNativePath>$(NuGetPackageRoot)microsoft.netcore.app.runtime.mono.$(NETCoreSdkRuntimeIdentifier)/$(DotNetRuntimePacksVersion)/runtimes/$(NETCoreSdkRuntimeIdentifier)/native/
+ <_MonoIncludePath>$(_MonoNativePath)include/mono-2.0
+ <_DEnableMono>-DENABLE_MONO_INTEGRATION=ON
+ <_DEnableOsxArchitectures Condition=" $([MSBuild]::IsOSPlatform ('osx')) ">"-DENABLE_OSX_ARCHITECTURES=$(_CmakeOsxArch)"
+ <_DMonoDirs>"-DMONO_INCLUDE_LIST=$(_MonoIncludePath)"
+ <_DJdkDirs>"-DJDK_INCLUDE_LIST=@(JdkIncludePath, ';')"
+ <_DJni_c>"-DJNI_C_PATH=$(MSBuildThisFileDirectory)$(IntermediateOutputPath)jni.c"
+ <_MonoLinkFlags Condition=" $([MSBuild]::IsOSPlatform ('windows')) " >$(MSBuildThisFileDirectory)coreclr.lib
+ <_MonoLinkFlags Condition=" !$([MSBuild]::IsOSPlatform ('windows')) ">-L $(_MonoNativePath) -lcoreclr
+ <_DMonoLinkFlags>"-DMONO_LINK_FLAGS=$(_MonoLinkFlags)"
+ <_ExtraArgs>$([MSBuild]::Escape('$(_DJdkDirs) $(_DJni_c) $(_DEnableMono) $(_DMonoDirs) $(_DMonoLinkFlags) $(_DEnableOsxArchitectures)'))
+
+
+
+
+
-
+ DependsOnTargets="GetNativeBuildCommands;_BuildJni_c;_GetJavaInteropBuildInfo;_UpdateCoreCLRLib"
+ AfterTargets="ResolveReferences"
+ Inputs="CMakeLists.txt;$(MSBuildThisFileFullPath);java-interop.csproj;@(ClInclude);@(ClCompile);coreclr.lib"
+ Outputs="$(IntermediateOutputPath)$(_JavaInteropLibName)">
+
<_Cmake
Condition=" '$(PrepareNativeToolchain)' != '' "
- Include="PrepareNativeToolchain=$(PrepareNativeToolchain) %(_JavaInteropNativeLib.Arch)"
+ Include="PrepareNativeToolchain=$(PrepareNativeToolchain) $(_PrepareArch)"
/>
<_Cmake Include="CmakePath=$(CmakePath)" />
<_Cmake Include="CmakeGenerator=$(CmakeGenerator)" />
<_Cmake Include="CmakeSourceDir=$(MSBuildThisFileDirectory)" />
- <_Cmake Include="CmakeBuildDir=$(MSBuildThisFileDirectory)$(IntermediateOutputPath)%(_JavaInteropNativeLib.Dir)" />
+ <_Cmake Include="CmakeBuildDir=$(MSBuildThisFileDirectory)$(IntermediateOutputPath)" />
<_Cmake Include="CmakeExtraArgs=$(_ExtraArgs)" />
-
- <_Libs Include="$(IntermediateOutputPath)%(_JavaInteropNativeLib.Dir)$(_JavaInteropLibName)*" />
+
-
-
+
+
+
+
$(TestOutputFullPath)
- $(OutputPath)java.base-tests.jar
+ java.base-tests.jar
diff --git a/tests/NativeTiming/CMakeLists.txt b/tests/NativeTiming/CMakeLists.txt
index a98557ebe..0d4e50d8f 100644
--- a/tests/NativeTiming/CMakeLists.txt
+++ b/tests/NativeTiming/CMakeLists.txt
@@ -1,9 +1,9 @@
+cmake_minimum_required(VERSION 3.10.2)
+
set(CMAKE_OSX_ARCHITECTURES x86_64 arm64)
project(NativeTiming C)
-cmake_minimum_required(VERSION 3.10.2)
-
foreach(dir in ${JDK_INCLUDE_LIST})
include_directories(${dir})
endforeach()
diff --git a/tests/TestJVM/TestJVM.cs b/tests/TestJVM/TestJVM.cs
index 0272b7142..2ff1e0715 100644
--- a/tests/TestJVM/TestJVM.cs
+++ b/tests/TestJVM/TestJVM.cs
@@ -79,39 +79,28 @@ static string GetOutputDirectoryName ()
return new StreamWriter (path, append: false, encoding: new UTF8Encoding (encoderShouldEmitUTF8Identifier: false));
}
- public static string? GetJvmLibraryPath () => GetJdkInfo ().JdkJvmPath;
+ public static string? GetJvmLibraryPath (Action? logger = null) => GetJdkInfo (logger).JdkJvmPath;
- static (JdkInfo? JdkInfo, string? JdkJvmPath) GetJdkInfo ()
+ static (JdkInfo? JdkInfo, string? JdkJvmPath) GetJdkInfo (Action? logger = null)
{
- var info = ReadJavaSdkDirectoryFromJdkInfoProps ();
+ var info = ReadJavaSdkDirectoryFromJdkInfoProps (logger);
if (info.JdkJvmPath != null) {
return (JdkInfo: info.JavaSdkDirectory == null ? null : new JdkInfo (info.JavaSdkDirectory), JdkJvmPath: info.JdkJvmPath);
}
- var jdk = JdkInfo.GetKnownSystemJdkInfos ()
+ var jdk = JdkInfo.GetKnownSystemJdkInfos (logger)
.FirstOrDefault ();
return (jdk, jdk?.JdkJvmPath);
}
- static (string? JavaSdkDirectory, string? JdkJvmPath) ReadJavaSdkDirectoryFromJdkInfoProps ()
+ static (string? JavaSdkDirectory, string? JdkJvmPath) ReadJavaSdkDirectoryFromJdkInfoProps (Action? logger)
{
- var location = typeof (TestJVM).Assembly.Location;
- var binDir = Path.GetDirectoryName (Path.GetDirectoryName (location)) ?? Environment.CurrentDirectory;
- var testDir = Path.GetFileName (Path.GetDirectoryName (location));
- if (testDir == null) {
- return (null, null);
- }
- if (!testDir.StartsWith ("Test", StringComparison.OrdinalIgnoreCase)) {
- return (null, null);
- }
- var buildName = testDir.Replace ("Test", "Build");
- if (buildName.Contains ('-')) {
- buildName = buildName.Substring (0, buildName.IndexOf ('-'));
- }
- var jdkPropFile = Path.Combine (binDir, buildName, "JdkInfo.props");
+ var jdkPropFile = TryProbeForJdkInfoProps (logger);
+ logger?.Invoke (TraceLevel.Verbose, $"TestJVM: jdkPropFile? {jdkPropFile}");
if (!File.Exists (jdkPropFile)) {
return (null, null);
}
+ logger?.Invoke (TraceLevel.Verbose, $"TestJVM: Extracting $(JdkJvmPath) from: {jdkPropFile}");
var msbuild = XNamespace.Get ("http://schemas.microsoft.com/developer/msbuild/2003");
var jdkProps = XDocument.Load (jdkPropFile);
@@ -129,9 +118,47 @@ static string GetOutputDirectoryName ()
.Elements (msbuild + "JavaSdkDirectory")
.FirstOrDefault ();
+ logger?.Invoke (TraceLevel.Verbose, $"TestJVM: $(JavaSdkDirectory)={jdkPath?.Value}; $(JdkJvmPath)={jdkJvmPath.Value}");
return (JavaSdkDirectory: jdkPath?.Value, JdkJvmPath: jdkJvmPath.Value);
}
+ static string? TryProbeForJdkInfoProps (Action? logger)
+ {
+ for (var probing = Path.GetDirectoryName (typeof (TestJVM).Assembly.Location); probing != null; probing = Path.GetDirectoryName (probing)) {
+ logger?.Invoke (TraceLevel.Verbose, $"TestJVM: probing for JdkInfo.props around {probing}");
+ if (File.Exists (Path.Combine (probing, "Java.Interop.sln"))) {
+ // we've hit the root of the repo checkout
+ return ProbeFromRootDir (probing);
+ }
+
+ var dirName = Path.GetFileName (probing);
+ if (dirName.StartsWith ("Test", StringComparison.OrdinalIgnoreCase)) {
+ var buildName = dirName.Replace ("Test", "Build");
+ if (buildName.Contains ('-')) {
+ buildName = buildName.Substring (0, buildName.IndexOf ('-'));
+ }
+ return Path.Combine (Path.GetDirectoryName (probing)!, buildName, "JdkInfo.props");
+ }
+ }
+ return null;
+
+ string ProbeFromRootDir (string location)
+ {
+ var buildDebug = Path.Combine (location, "bin", "BuildDebug");
+ var buildRelease = Path.Combine (location, "bin", "BuildRelease");
+ if (Directory.Exists (buildDebug) && !Directory.Exists (buildRelease)) {
+ return Path.Combine (buildDebug, "JdkInfo.props");
+ }
+ if (Directory.Exists (buildRelease) && !Directory.Exists (buildDebug)) {
+ return Path.Combine (buildRelease, "JdkInfo.props");
+ }
+ var dir = Directory.GetLastWriteTime (buildDebug) > Directory.GetLastWriteTime (buildRelease)
+ ? buildDebug
+ : buildRelease;
+ return Path.Combine (dir, "JdkInfo.props");
+ }
+ }
+
public TestJVM (string[]? jars = null, Dictionary? typeMappings = null)
: this (CreateOptions (jars, Assembly.GetCallingAssembly (), typeMappings))
{