diff --git a/Java.Interop.sln b/Java.Interop.sln
index d662692ca..3af4b28fb 100644
--- a/Java.Interop.sln
+++ b/Java.Interop.sln
@@ -113,6 +113,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Java.Interop.Tools.Expressi
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Java.Interop.Tools.Expressions-Tests", "tests\Java.Interop.Tools.Expressions-Tests\Java.Interop.Tools.Expressions-Tests.csproj", "{211BAA88-66B1-41B2-88B2-530DBD8DF702}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hello-NativeAOTFromJNI", "samples\Hello-NativeAOTFromJNI\Hello-NativeAOTFromJNI.csproj", "{8DB3842B-73D7-491C-96F9-EBC863E2C917}"
+EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
src\Java.Interop.NamingCustomAttributes\Java.Interop.NamingCustomAttributes.projitems*{58b564a1-570d-4da2-b02d-25bddb1a9f4f}*SharedItemsImports = 5
@@ -320,6 +322,10 @@ Global
{211BAA88-66B1-41B2-88B2-530DBD8DF702}.Debug|Any CPU.Build.0 = Debug|Any CPU
{211BAA88-66B1-41B2-88B2-530DBD8DF702}.Release|Any CPU.ActiveCfg = Release|Any CPU
{211BAA88-66B1-41B2-88B2-530DBD8DF702}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8DB3842B-73D7-491C-96F9-EBC863E2C917}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8DB3842B-73D7-491C-96F9-EBC863E2C917}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8DB3842B-73D7-491C-96F9-EBC863E2C917}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8DB3842B-73D7-491C-96F9-EBC863E2C917}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -374,6 +380,7 @@ Global
{CB05E11B-B96F-4179-A4E9-5D6BDE29A8FC} = {271C9F30-F679-4793-942B-0D9527CB3E2F}
{1A0262FE-3CDB-4AF2-AAD8-65C59524FE8A} = {0998E45F-8BCE-4791-A944-962CD54E2D80}
{211BAA88-66B1-41B2-88B2-530DBD8DF702} = {271C9F30-F679-4793-942B-0D9527CB3E2F}
+ {8DB3842B-73D7-491C-96F9-EBC863E2C917} = {D5A93398-AEB1-49F3-89DC-3904A47DB0C7}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {29204E0C-382A-49A0-A814-AD7FBF9774A5}
diff --git a/build-tools/automation/azure-pipelines.yaml b/build-tools/automation/azure-pipelines.yaml
index 654db943e..df6f1bf06 100644
--- a/build-tools/automation/azure-pipelines.yaml
+++ b/build-tools/automation/azure-pipelines.yaml
@@ -57,6 +57,7 @@ jobs:
- template: templates\core-tests.yaml
parameters:
runNativeDotnetTests: true
+ nativeAotRid: win-x64
platformName: .NET - Windows
- template: templates\fail-on-issue.yaml
@@ -87,6 +88,7 @@ jobs:
- template: templates\core-tests.yaml
parameters:
runNativeTests: true
+ nativeAotRid: osx-x64
platformName: .NET - MacOS
- template: templates\fail-on-issue.yaml
diff --git a/build-tools/automation/templates/core-tests.yaml b/build-tools/automation/templates/core-tests.yaml
index 1f11013ed..5c886152b 100644
--- a/build-tools/automation/templates/core-tests.yaml
+++ b/build-tools/automation/templates/core-tests.yaml
@@ -2,6 +2,7 @@ parameters:
condition: succeeded()
runNativeTests: false
platformName:
+ nativeAotRid:
steps:
- task: DotNetCoreCLI@2
@@ -173,6 +174,19 @@ steps:
arguments: -c $(Build.Configuration) tools/java-source-utils/java-source-utils.csproj -t:RunTests
continueOnError: true
+- powershell: >
+ dotnet publish -c $(Build.Configuration) -r ${{ parameters.nativeAotRid }}
+ samples/Hello-NativeAOTFromJNI/Hello-NativeAOTFromJNI.csproj
+ displayName: 'Tests: publish Hello-NativeAOTFromJNI'
+ continueOnError: true
+
+- powershell: >
+ dotnet build -c $(Build.Configuration) -r ${{ parameters.nativeAotRid }}
+ -t:RunJavaSample
+ samples/Hello-NativeAOTFromJNI/Hello-NativeAOTFromJNI.csproj
+ displayName: 'Tests: run Hello-NativeAOTFromJNI'
+ continueOnError: true
+
- task: PublishTestResults@2
displayName: Publish JUnit Test Results
inputs:
diff --git a/samples/Hello-NativeAOTFromJNI/App.cs b/samples/Hello-NativeAOTFromJNI/App.cs
new file mode 100644
index 000000000..c2e326921
--- /dev/null
+++ b/samples/Hello-NativeAOTFromJNI/App.cs
@@ -0,0 +1,31 @@
+using System.Runtime.InteropServices;
+
+using Java.Interop;
+
+namespace Hello_NativeAOTFromJNI;
+
+static class App {
+
+ // symbol name from `$(IntermediateOutputPath)obj/Release/osx-x64/h-classes/net_dot_jni_hello_App.h`
+ [UnmanagedCallersOnly (EntryPoint="Java_net_dot_jni_hello_App_sayHello")]
+ static IntPtr sayHello (IntPtr jnienv, IntPtr klass)
+ {
+ var envp = new JniTransition (jnienv);
+ try {
+ var s = $"Hello from .NET NativeAOT!";
+ Console.WriteLine (s);
+ var h = JniEnvironment.Strings.NewString (s);
+ var r = JniEnvironment.References.NewReturnToJniRef (h);
+ JniObjectReference.Dispose (ref h);
+ return r;
+ }
+ catch (Exception e) {
+ Console.Error.WriteLine ($"Error in App.sayHello(): {e.ToString ()}");
+ envp.SetPendingException (e);
+ }
+ finally {
+ envp.Dispose ();
+ }
+ return nint.Zero;
+ }
+}
diff --git a/samples/Hello-NativeAOTFromJNI/Hello-NativeAOTFromJNI.csproj b/samples/Hello-NativeAOTFromJNI/Hello-NativeAOTFromJNI.csproj
new file mode 100644
index 000000000..53822ff34
--- /dev/null
+++ b/samples/Hello-NativeAOTFromJNI/Hello-NativeAOTFromJNI.csproj
@@ -0,0 +1,52 @@
+
+
+
+ $(DotNetTargetFramework)
+
+
+
+
+
+ Hello_NativeAOTFromJNI
+ enable
+ enable
+ true
+ true
+ Shared
+
+ AnyCPU
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/Hello-NativeAOTFromJNI/Hello-NativeAOTFromJNI.targets b/samples/Hello-NativeAOTFromJNI/Hello-NativeAOTFromJNI.targets
new file mode 100644
index 000000000..695c22c18
--- /dev/null
+++ b/samples/Hello-NativeAOTFromJNI/Hello-NativeAOTFromJNI.targets
@@ -0,0 +1,106 @@
+
+
+
+ "$(DOTNET_HOST_PATH)"
+
+
+
+
+
+
+
+ <_JcwGenRefAsmDirs Include="@(ReferencePathWithRefAssemblies->'%(RootDir)%(Directory).'->Distinct())" />
+
+
+ <_JcwGen>"$(UtilityOutputFullPath)/jcw-gen.dll"
+ <_Target>--codegen-target JavaInterop1
+ <_Output>-o "$(IntermediateOutputPath)/java"
+ <_Libpath>@(_JcwGenRefAsmDirs->'-L "%(Identity)"', ' ')
+
+
+
+
+
+
+
+
+ <_JnimmRefAsmDirs Include="@(RuntimePackAsset->'%(RootDir)%(Directory).'->Distinct())" />
+
+
+ <_JnimarshalmethodGen>"$(UtilityOutputFullPath)/jnimarshalmethod-gen.dll"
+ <_Verbosity>-v -v --keeptemp
+ <_Libpath>-L "$(TargetDir)" @(_JnimmRefAsmDirs->'-L "%(Identity)"', ' ')
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_JcwSource Include="$(IntermediateOutputPath)java\**\*.java" />
+
+
+ <_Source Include="@(_JcwSource->Replace('%5c', '/'))" />
+ <_Source Include="@(HelloNativeAOTFromJNIJar->Replace('%5c', '/'))" />
+
+
+
+ <_JavacOpt Include="$(_JavacSourceOptions)" />
+ <_JavacOpt Include="-d "$(IntermediateOutputPath)h-classes" " />
+ <_JavacOpt Include="-classpath "$(OutputPath)java-interop.jar" " />
+ <_JavacOpt Include=""@$(IntermediateOutputPath)_java_sources.txt"" />
+ <_JavacOpt Include="-h "$(IntermediateOutputPath)h-classes" " />
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_Classpath Include="hello-from-java.jar" />
+ <_Classpath Include="java-interop.jar" />
+
+
+ <_CPSep Condition=" '$(OS)' == 'Windows_NT' ">;
+ <_CPSep Condition=" '$(_CPSep)' == '' ">:
+ <_CP>@(_Classpath, '$(_CPSep)')
+
+
+
+
diff --git a/samples/Hello-NativeAOTFromJNI/JavaInteropRuntime.cs b/samples/Hello-NativeAOTFromJNI/JavaInteropRuntime.cs
new file mode 100644
index 000000000..c956536df
--- /dev/null
+++ b/samples/Hello-NativeAOTFromJNI/JavaInteropRuntime.cs
@@ -0,0 +1,40 @@
+using System.Runtime.InteropServices;
+
+using Java.Interop;
+
+namespace Hello_NativeAOTFromJNI;
+
+static class JavaInteropRuntime
+{
+ static JniRuntime? runtime;
+
+ [UnmanagedCallersOnly (EntryPoint="JNI_OnLoad")]
+ static int JNI_OnLoad (IntPtr vm, IntPtr reserved)
+ {
+ return (int) JniVersion.v1_6;
+ }
+
+ [UnmanagedCallersOnly (EntryPoint="JNI_OnUnload")]
+ static void JNI_OnUnload (IntPtr vm, IntPtr reserved)
+ {
+ runtime?.Dispose ();
+ }
+
+ // symbol name from `$(IntermediateOutputPath)obj/Release/osx-arm64/h-classes/net_dot_jni_hello_JavaInteropRuntime.h`
+ [UnmanagedCallersOnly (EntryPoint="Java_net_dot_jni_hello_JavaInteropRuntime_init")]
+ static void init (IntPtr jnienv, IntPtr klass)
+ {
+ Console.WriteLine ($"C# init()");
+ try {
+ var options = new JreRuntimeOptions {
+ EnvironmentPointer = jnienv,
+ TypeManager = new NativeAotTypeManager (),
+ UseMarshalMemberBuilder = false,
+ };
+ runtime = options.CreateJreVM ();
+ }
+ catch (Exception e) {
+ Console.Error.WriteLine ($"JavaInteropRuntime.init: error: {e}");
+ }
+ }
+}
diff --git a/samples/Hello-NativeAOTFromJNI/ManagedType.cs b/samples/Hello-NativeAOTFromJNI/ManagedType.cs
new file mode 100644
index 000000000..3d21f7163
--- /dev/null
+++ b/samples/Hello-NativeAOTFromJNI/ManagedType.cs
@@ -0,0 +1,22 @@
+namespace Example;
+
+using Java.Interop;
+
+[JniTypeSignature (JniTypeName)]
+class ManagedType : Java.Lang.Object {
+ internal const string JniTypeName = "example/ManagedType";
+
+ [JavaCallableConstructor(SuperConstructorExpression="")]
+ public ManagedType (int value)
+ {
+ this.value = value;
+ }
+
+ int value;
+
+ [JavaCallable ("getString")]
+ public Java.Lang.String GetString ()
+ {
+ return new Java.Lang.String ($"Hello from C#, via Java.Interop! Value={value}");
+ }
+}
diff --git a/samples/Hello-NativeAOTFromJNI/NativeAotTypeManager.cs b/samples/Hello-NativeAOTFromJNI/NativeAotTypeManager.cs
new file mode 100644
index 000000000..7d21d95e1
--- /dev/null
+++ b/samples/Hello-NativeAOTFromJNI/NativeAotTypeManager.cs
@@ -0,0 +1,37 @@
+using Java.Interop;
+
+namespace Hello_NativeAOTFromJNI;
+
+class NativeAotTypeManager : JniRuntime.JniTypeManager {
+
+#pragma warning disable IL2026
+ Dictionary typeMappings = new () {
+ [Example.ManagedType.JniTypeName] = typeof (Example.ManagedType),
+ };
+#pragma warning restore IL2026
+
+
+ protected override IEnumerable GetTypesForSimpleReference (string jniSimpleReference)
+ {
+ if (typeMappings.TryGetValue (jniSimpleReference, out var target))
+ yield return target;
+ foreach (var t in base.GetTypesForSimpleReference (jniSimpleReference))
+ yield return t;
+ }
+
+ protected override IEnumerable GetSimpleReferences (Type type)
+ {
+ return base.GetSimpleReferences (type)
+ .Concat (CreateSimpleReferencesEnumerator (type));
+ }
+
+ IEnumerable CreateSimpleReferencesEnumerator (Type type)
+ {
+ if (typeMappings == null)
+ yield break;
+ foreach (var e in typeMappings) {
+ if (e.Value == type)
+ yield return e.Key;
+ }
+ }
+}
diff --git a/samples/Hello-NativeAOTFromJNI/README.md b/samples/Hello-NativeAOTFromJNI/README.md
new file mode 100644
index 000000000..3494607bf
--- /dev/null
+++ b/samples/Hello-NativeAOTFromJNI/README.md
@@ -0,0 +1,164 @@
+# Hello From JNI
+
+[JNI][0] supports *two* modes of operation:
+
+ 1. Native code creates the JVM, e.g. via [`JNI_CreateJavaVM()`][1], or
+ 2. The JVM already exists, and calls [`JNI_OnLoad()`][2] when loading a native library.
+
+Java.Interop samples and unit tests rely on the first approach.
+
+.NET Android / neé Xamarin.Android is the second approach.
+
+Bring an example of the latter into a Java.Interop sample, using [NativeAOT][3].
+
+## Building
+
+Building a native library with NativeAOT requires a Release configuration build.
+For in-repo use, that means that xamarin/Java.Interop itself needs to be built in
+Release configuration:
+
+```sh
+% dotnet build -c Release -t:Prepare
+% dotnet build -c Release
+```
+
+Once Java.Interop itself is built, you can *publish* the sample:
+
+```sh
+% cd samples/Hello-NativeAOTFromJNI
+% dotnet publish -c Release -r osx-x64
+```
+
+The resulting native library contains the desired symbols:
+
+```sh
+% nm bin/Release/osx-x64/publish/Hello-NativeAOTFromJNI.dylib | grep ' S '
+00000000000ef880 S _JNI_OnLoad
+00000000000ef8b0 S _JNI_OnUnload
+00000000000ef5d0 S _Java_net_dot_jni_hello_App_sayHello
+00000000000ef900 S _Java_net_dot_jni_hello_JavaInteropRuntime_init
+```
+
+Use the `RunJavaSample` target to run Java, which will run
+`System.loadLibrary("Hello-NativeAOTFromJNI")`, which will cause the
+NativeAOT-generated `libHello-NativeAOTFromJNI.dylib` to be run:
+
+```sh
+% dotnet build -c Release -r osx-x64 -t:RunJavaSample -v m --nologo --no-restore
+ Hello from Java!
+ C# init()
+ Hello from .NET NativeAOT!
+ String returned to Java: Hello from .NET NativeAOT!
+ # jonp: called `Example.ManagedType/__<$>_jni_marshal_methods.__RegisterNativeMembers()` w/ 1 methods to register.
+ mt.getString()=Hello from C#, via Java.Interop! Value=42
+
+Build succeeded.
+ 0 Warning(s)
+ 0 Error(s)
+
+Time Elapsed 00:00:01.04
+
+% (cd bin/Release/osx-x64/publish ; java -cp hello-from-java.jar:java-interop.jar net/dot/jni/hello/App)
+Hello from Java!
+C# init()
+Hello from .NET NativeAOT!
+String returned to Java: Hello from .NET NativeAOT!
+# jonp: called `Example.ManagedType/__<$>_jni_marshal_methods.__RegisterNativeMembers()` w/ 1 methods to register.
+mt.getString()=Hello from C#, via Java.Interop! Value=42
+```
+
+Note the use of `(cd …; java …)` so that `libHello-NativeAOTFromJNI.dylib` is
+in the current working directory, so that it can be found.
+
+# Notes
+
+To support cross-compilation, the project should set
+`$(PlatformTarget)`=AnyCPU.
+
+# Known Knowns?
+
+With this sample "done" (-ish), there are some
+"potentially solved, if not ideally" used to make NativeAOT + Java *viable*.
+
+## `Type.GetType()`
+
+Commit
+[xamarin/java.interop@005c9141](https://github.com/xamarin/java.interop/commit/005c914170a0af9069ff18fd4dd9d45463dd5dc6)
+uses JNI Type Signatures to avoid `Type.GetType()` invocations, which continue
+to be used in .NET Android.
+
+```Java
+/* partial */ class JavaCallableWrapper
+{
+ public static final String __md_methods;
+ static {
+ __md_methods =
+ "n_GetString:()Ljava/lang/String;:__export__\n" +
+ "";
+ net.dot.jni.ManagedPeer.registerNativeMembers (
+ /* nativeClass */ ManagedType.class,
+ /* methods */ __md_methods);
+ }
+
+ public ManagedType (int p0)
+ {
+ super ();
+ if (getClass () == ManagedType.class) {
+ net.dot.jni.ManagedPeer.construct (
+ /* self */ this,
+ /* constructorSignature */ "(I)V",
+ /* arguments */ new java.lang.Object[] { p0 });
+ }
+ }
+}
+```
+
+This requires the use of JNI method signatures within the constructor
+to lookup the corresponding managed constructor to invoke. While this
+works, it requires additional work to lookup the constructor, as there
+may not be a 1:1 relation between types within the JNI method signature
+and managed code. In particular, Java *arrays* may have multiple types
+which can be used from managed code.
+
+
+# Known Unknowns
+
+With this sample "done" (-ish), there are several "future research directions" to
+make NativeAOT + Java *viable*.
+
+## GC
+
+Firstly, there's the open GC question: NativeAOT doesn't provide a "GC Bridge"
+like MonoVM does, so how do we support cross-VM object references?
+
+ * [Collecting Cyclic Garbage across Foreign Function Interfaces: Who Takes the Last Piece of Cake?](https://pldi23.sigplan.org/details/pldi-2023-pldi/25/Collecting-Cyclic-Garbage-across-Foreign-Function-Interfaces-Who-Takes-the-Last-Piec)
+ * [`JavaScope`?](https://github.com/jonpryor/java.interop/commits/jonp-registration-scope)
+ (Less a "solution" and more a "Glorious Workaround".)
+
+
+## Type Maps
+
+A "derivative" of the `Type.GetType()` problem is that Java.Interop needs a way
+to associate a Java type to a .NET `System.Type` instance, for all manner of
+reasons. (One such reason: `JniRuntime.JniValueManager.GetValue()` needs to
+know the associated type so that it can create a "peer wrapper", if needed.)
+
+Java.Interop unit tests "hack" around this by using a dictionary in TestJVM,
+and `Hello-NativeAOTFromJNI` follows suite. This isn't a "real" answer, though.
+
+.NET Android has a very complicated typemap mechanism that involves a table
+between the Java JNI name and an { assembly name, type token } pair, along with
+copious use of MonoVM embedding API such as `mono_class_get()`. ***A Lot***
+of effort has gone into making type maps performant.
+
+How do we "do" type maps in NativeAOT? We may need to consider some equivalent
+to the iOS "static registrar", and this also needs to support getting `Type`
+instances for non-`public` types. There are also concerns about initialization
+overhead; a `Dictionary` will require loading and resolving
+*all* the `Type` instances as part of startup, which *can't* be good for
+reducing startup time. What other data structure could be used?
+
+[0]: https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/jniTOC.html
+[1]: https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/invocation.html#creating_the_vm
+[2]: https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/invocation.html#JNJI_OnLoad
+[3]: https://github.com/dotnet/samples/blob/main/core/nativeaot/NativeLibrary/README.md
\ No newline at end of file
diff --git a/samples/Hello-NativeAOTFromJNI/java/net/dot/jni/hello/App.java b/samples/Hello-NativeAOTFromJNI/java/net/dot/jni/hello/App.java
new file mode 100644
index 000000000..427016263
--- /dev/null
+++ b/samples/Hello-NativeAOTFromJNI/java/net/dot/jni/hello/App.java
@@ -0,0 +1,18 @@
+package net.dot.jni.hello;
+
+import net.dot.jni.hello.JavaInteropRuntime;
+import example.ManagedType;
+
+class App {
+
+ public static void main(String[] args) {
+ System.out.println("Hello from Java!");
+ JavaInteropRuntime.init();
+ String s = sayHello();
+ System.out.println("String returned to Java: " + s);
+ ManagedType mt = new ManagedType(42);
+ System.out.println("mt.getString()=" + mt.getString());
+ }
+
+ static native String sayHello();
+}
diff --git a/samples/Hello-NativeAOTFromJNI/java/net/dot/jni/hello/JavaInteropRuntime.java b/samples/Hello-NativeAOTFromJNI/java/net/dot/jni/hello/JavaInteropRuntime.java
new file mode 100644
index 000000000..aa7f1b0d7
--- /dev/null
+++ b/samples/Hello-NativeAOTFromJNI/java/net/dot/jni/hello/JavaInteropRuntime.java
@@ -0,0 +1,12 @@
+package net.dot.jni.hello;
+
+public class JavaInteropRuntime {
+ static {
+ System.loadLibrary("Hello-NativeAOTFromJNI");
+ }
+
+ private JavaInteropRuntime() {
+ }
+
+ public static native void init();
+}
diff --git a/src/Java.Interop/Java.Interop.csproj b/src/Java.Interop/Java.Interop.csproj
index 80eb91aee..3a7dd4325 100644
--- a/src/Java.Interop/Java.Interop.csproj
+++ b/src/Java.Interop/Java.Interop.csproj
@@ -32,6 +32,7 @@
9.0
8.0
$(JICoreLibVersion)
+ true
FEATURE_JNIENVIRONMENT_JI_FUNCTION_POINTERS;$(DefineConstants)
diff --git a/src/Java.Interop/Java.Interop/JniRuntime.JniMarshalMemberBuilder.cs b/src/Java.Interop/Java.Interop/JniRuntime.JniMarshalMemberBuilder.cs
index 77be210f0..0d8ee1a3a 100644
--- a/src/Java.Interop/Java.Interop/JniRuntime.JniMarshalMemberBuilder.cs
+++ b/src/Java.Interop/Java.Interop/JniRuntime.JniMarshalMemberBuilder.cs
@@ -27,6 +27,8 @@ public JniMarshalMemberBuilder MarshalMemberBuilder {
}
}
+ internal bool UseMarshalMemberBuilder => marshalMemberBuilder != null;
+
[DynamicDependency (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor, "Java.Interop.MarshalMemberBuilder", "Java.Interop.Export")]
[UnconditionalSuppressMessage ("Trimming", "IL2035", Justification = "Java.Interop.Export.dll is not always present.")]
partial void SetMarshalMemberBuilder (CreationOptions options)
diff --git a/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs b/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs
index 181469f6d..b26e3b614 100644
--- a/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs
+++ b/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs
@@ -374,7 +374,10 @@ static Type GetPeerType ([DynamicallyAccessedMembers (Constructors)] Type type)
[UnconditionalSuppressMessage ("Trimming", "IL2055", Justification = makeGenericTypeMessage)]
[UnconditionalSuppressMessage ("AOT", "IL3050", Justification = makeGenericTypeMessage)]
[return: DynamicallyAccessedMembers (Constructors)]
- static Type MakeGenericType (Type type, Type [] arguments) =>
+ static Type MakeGenericType (
+ [DynamicallyAccessedMembers (Constructors)]
+ Type type,
+ Type [] arguments) =>
type.MakeGenericType (arguments);
Type[] arguments = type.GetGenericArguments ();
diff --git a/src/Java.Interop/Java.Interop/JniValueMarshaler.cs b/src/Java.Interop/Java.Interop/JniValueMarshaler.cs
index ae8e096c2..8b5b08cb5 100644
--- a/src/Java.Interop/Java.Interop/JniValueMarshaler.cs
+++ b/src/Java.Interop/Java.Interop/JniValueMarshaler.cs
@@ -172,10 +172,13 @@ Expression CreateSelf (JniValueMarshalerContext context, ParameterExpression sou
{
var self = Expression.Variable (GetType (), sourceValue.Name + "_marshaler");
context.LocalVariables.Add (self);
- context.CreationStatements.Add (Expression.Assign (self, Expression.New (GetType ())));
+ context.CreationStatements.Add (Expression.Assign (self, Expression.New (_GetType ())));
return self;
}
+ [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
+ Type _GetType () => GetType ();
+
[RequiresUnreferencedCode (ExpressionRequiresUnreferencedCode)]
public virtual Expression CreateReturnValueFromManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue)
{
diff --git a/src/Java.Interop/Java.Interop/JniValueMarshalerAttribute.cs b/src/Java.Interop/Java.Interop/JniValueMarshalerAttribute.cs
index b674094be..03bb442b5 100644
--- a/src/Java.Interop/Java.Interop/JniValueMarshalerAttribute.cs
+++ b/src/Java.Interop/Java.Interop/JniValueMarshalerAttribute.cs
@@ -29,8 +29,8 @@ public JniValueMarshalerAttribute (
MarshalerType = marshalerType;
}
+ [DynamicallyAccessedMembers (ParameterlessConstructorsInterfaces)]
public Type MarshalerType {
- [return: DynamicallyAccessedMembers (ParameterlessConstructorsInterfaces)]
get;
}
}
diff --git a/src/Java.Interop/Java.Interop/ManagedPeer.cs b/src/Java.Interop/Java.Interop/ManagedPeer.cs
index 763e439f2..6a9834954 100644
--- a/src/Java.Interop/Java.Interop/ManagedPeer.cs
+++ b/src/Java.Interop/Java.Interop/ManagedPeer.cs
@@ -8,6 +8,7 @@
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
+using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Text;
@@ -54,6 +55,7 @@ public override JniPeerMembers JniPeerMembers {
const string ConstructSignature = "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)V";
// TODO: Keep in sync with the code generated by ExportedMemberBuilder
+ [UnmanagedFunctionPointer (CallingConvention.Winapi)]
delegate void ConstructMarshalMethod (IntPtr jnienv,
IntPtr klass,
IntPtr n_self,
@@ -254,6 +256,7 @@ static List[] GetConstructorCandidateParameterTypes (string signature)
const string RegisterNativeMembersSignature = "(Ljava/lang/Class;Ljava/lang/String;)V";
+ [UnmanagedFunctionPointer (CallingConvention.Winapi)]
delegate void RegisterMarshalMethod (IntPtr jnienv,
IntPtr klass,
IntPtr n_nativeClass,
diff --git a/src/Java.Interop/Properties/AssemblyInfo.cs b/src/Java.Interop/Properties/AssemblyInfo.cs
index 01afd8e26..bff1cb28c 100644
--- a/src/Java.Interop/Properties/AssemblyInfo.cs
+++ b/src/Java.Interop/Properties/AssemblyInfo.cs
@@ -14,6 +14,13 @@
"814f144e5d817efc4c6502cc012df310783348304e3ae38573c6d658c234025821fda87a0be8a0" +
"d504df564e2c93b2b878925f42503e9d54dfef9f9586d9e6f38a305769587b1de01f6c0410328b" +
"2c9733db")]
+[assembly: InternalsVisibleTo (
+ "Java.Runtime.Environment, PublicKey=" +
+ "0024000004800000940000000602000000240000525341310004000011000000438ac2a5acfbf1" +
+ "6cbd2b2b47a62762f273df9cb2795ceccdf77d10bf508e69e7a362ea7a45455bbf3ac955e1f2e2" +
+ "814f144e5d817efc4c6502cc012df310783348304e3ae38573c6d658c234025821fda87a0be8a0" +
+ "d504df564e2c93b2b878925f42503e9d54dfef9f9586d9e6f38a305769587b1de01f6c0410328b" +
+ "2c9733db")]
[assembly: InternalsVisibleTo (
"Java.Interop-Tests, PublicKey=" +
"0024000004800000940000000602000000240000525341310004000011000000438ac2a5acfbf1" +
diff --git a/src/Java.Runtime.Environment/Java.Interop/JreRuntime.cs b/src/Java.Runtime.Environment/Java.Interop/JreRuntime.cs
index d7cc0f648..811523b35 100644
--- a/src/Java.Runtime.Environment/Java.Interop/JreRuntime.cs
+++ b/src/Java.Runtime.Environment/Java.Interop/JreRuntime.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Reflection;
@@ -103,7 +104,7 @@ static unsafe JreRuntimeOptions CreateJreVM (JreRuntimeOptions builder)
builder.LibraryHandler.LoadJvmLibrary (builder.JvmLibraryPath!);
if (!builder.ClassPath.Any (p => p.EndsWith ("java-interop.jar", StringComparison.OrdinalIgnoreCase))) {
- var loc = typeof (JreRuntimeOptions).Assembly.Location;
+ var loc = GetAssemblyLocation (typeof (JreRuntimeOptions).Assembly);
var dir = string.IsNullOrEmpty (loc) ? null : Path.GetDirectoryName (loc);
var jij = string.IsNullOrEmpty (dir) ? null : Path.Combine (dir, "java-interop.jar");
if (!File.Exists (jij)) {
@@ -146,6 +147,15 @@ static unsafe JreRuntimeOptions CreateJreVM (JreRuntimeOptions builder)
}
}
+ [UnconditionalSuppressMessage ("Trimming", "IL3000", Justification = "We check for a null Assembly.Location value!")]
+ internal static string? GetAssemblyLocation (Assembly assembly)
+ {
+ var location = assembly.Location;
+ if (!string.IsNullOrEmpty (location))
+ return location;
+ return null;
+ }
+
JvmLibraryHandler LibraryHandler;
internal protected JreRuntime (JreRuntimeOptions builder)
@@ -189,11 +199,15 @@ public static JvmLibraryHandler Create ()
{
var handler = Environment.GetEnvironmentVariable ("JI_LOADER_TYPE");
switch (handler?.ToLowerInvariant ()) {
+#if !NET
case "":
case null:
+#endif // NET
case "java-interop":
return new JavaInteropLibJvmLibraryHandler ();
#if NET
+ case "":
+ case null:
case "native-library":
return new NativeLibraryJvmLibraryHandler ();
#endif // NET
@@ -281,10 +295,10 @@ static JavaInteropLibJvmLibraryHandler ()
public override void LoadJvmLibrary (string path)
{
IntPtr errorPtr = IntPtr.Zero;
- int r = NativeMethods.java_interop_jvm_load_with_error_message (path, out errorPtr);
+ int r = JreNativeMethods.java_interop_jvm_load_with_error_message (path, out errorPtr);
if (r != 0) {
string? error = Marshal.PtrToStringAnsi (errorPtr);
- NativeMethods.java_interop_free (errorPtr);
+ JreNativeMethods.java_interop_free (errorPtr);
if (r == JAVA_INTEROP_JVM_FAILED_ALREADY_LOADED) {
return;
}
@@ -294,17 +308,17 @@ public override void LoadJvmLibrary (string path)
public override int CreateJavaVM (out IntPtr javavm, out IntPtr jnienv, ref JavaVMInitArgs args)
{
- return NativeMethods.java_interop_jvm_create (out javavm, out jnienv, ref args);
+ return JreNativeMethods.java_interop_jvm_create (out javavm, out jnienv, ref args);
}
public override IEnumerable GetAvailableInvocationPointers ()
{
int nVMs;
- int r = NativeMethods.java_interop_jvm_list (null, 0, out nVMs);
+ int r = JreNativeMethods.java_interop_jvm_list (null, 0, out nVMs);
if (r != 0)
throw new NotSupportedException ("JNI_GetCreatedJavaVMs() returned: " + r.ToString ());
var handles = new IntPtr [nVMs];
- r = NativeMethods.java_interop_jvm_list (handles, handles.Length, out nVMs);
+ r = JreNativeMethods.java_interop_jvm_list (handles, handles.Length, out nVMs);
if (r != 0)
throw new InvalidOperationException ("JNI_GetCreatedJavaVMs() [take 2!] returned: " + r.ToString ());
return handles;
@@ -315,14 +329,15 @@ public override void Dispose ()
}
}
- partial class NativeMethods {
+ partial class JreNativeMethods {
- static NativeMethods ()
+ static JreNativeMethods ()
{
if (Environment.OSVersion.Platform == PlatformID.Win32NT) {
- var baseDir = Path.GetDirectoryName (typeof (JreRuntime).Assembly.Location) ?? throw new NotSupportedException ();
+ var loc = JreRuntime.GetAssemblyLocation (typeof (JreRuntime).Assembly) ?? throw new NotSupportedException ();
+ var baseDir = Path.GetDirectoryName (loc) ?? throw new NotSupportedException ();
var newDir = Path.Combine (baseDir, Environment.Is64BitProcess ? "win-x64" : "win-x86");
- NativeMethods.AddDllDirectory (newDir);
+ JreNativeMethods.AddDllDirectory (newDir);
}
}
diff --git a/src/Java.Runtime.Environment/Java.Interop/JreTypeManager.cs b/src/Java.Runtime.Environment/Java.Interop/JreTypeManager.cs
index 358d009c8..4912b6877 100644
--- a/src/Java.Runtime.Environment/Java.Interop/JreTypeManager.cs
+++ b/src/Java.Runtime.Environment/Java.Interop/JreTypeManager.cs
@@ -23,6 +23,10 @@ public override void RegisterNativeMembers (JniType nativeClass, Type type, Read
return;
}
+ if (!Runtime.UseMarshalMemberBuilder) {
+ throw new NotSupportedException ("JniRuntime.MarshalMemberBuilder is required and not present.");
+ }
+
var toRegister = new JniMethodMap ();
AddInterfaceMethods (toRegister, type);
diff --git a/src/Java.Runtime.Environment/Java.Interop/ManagedValueManager.cs b/src/Java.Runtime.Environment/Java.Interop/ManagedValueManager.cs
index 7ff510a7a..4016909b2 100644
--- a/src/Java.Runtime.Environment/Java.Interop/ManagedValueManager.cs
+++ b/src/Java.Runtime.Environment/Java.Interop/ManagedValueManager.cs
@@ -22,7 +22,7 @@ public override void WaitForGCBridgeProcessing ()
public override void CollectPeers ()
{
if (RegisteredInstances == null)
- throw new ObjectDisposedException (nameof (MonoRuntimeValueManager));
+ throw new ObjectDisposedException (nameof (ManagedValueManager));
var peers = new List ();
@@ -51,7 +51,7 @@ public override void CollectPeers ()
public override void AddPeer (IJavaPeerable value)
{
if (RegisteredInstances == null)
- throw new ObjectDisposedException (nameof (MonoRuntimeValueManager));
+ throw new ObjectDisposedException (nameof (ManagedValueManager));
var r = value.PeerReference;
if (!r.IsValid)
@@ -116,7 +116,7 @@ void WarnNotReplacing (int key, IJavaPeerable ignoreValue, IJavaPeerable keepVal
public override IJavaPeerable? PeekPeer (JniObjectReference reference)
{
if (RegisteredInstances == null)
- throw new ObjectDisposedException (nameof (MonoRuntimeValueManager));
+ throw new ObjectDisposedException (nameof (ManagedValueManager));
if (!reference.IsValid)
return null;
@@ -142,7 +142,7 @@ void WarnNotReplacing (int key, IJavaPeerable ignoreValue, IJavaPeerable keepVal
public override void RemovePeer (IJavaPeerable value)
{
if (RegisteredInstances == null)
- throw new ObjectDisposedException (nameof (MonoRuntimeValueManager));
+ throw new ObjectDisposedException (nameof (ManagedValueManager));
if (value == null)
throw new ArgumentNullException (nameof (value));
@@ -204,8 +204,11 @@ public override void ActivatePeer (IJavaPeerable? self, JniObjectReference refer
var runtime = JniEnvironment.Runtime;
try {
- var f = runtime.MarshalMemberBuilder.CreateConstructActivationPeerFunc (cinfo);
- f (cinfo, reference, argumentValues);
+ if (runtime.UseMarshalMemberBuilder) {
+ ActivateViaMarshalMemberBuilder (runtime.MarshalMemberBuilder, reference, cinfo, argumentValues);
+ return;
+ }
+ ActivateViaReflection (reference, cinfo, argumentValues);
} catch (Exception e) {
var m = string.Format ("Could not activate {{ PeerReference={0} IdentityHashCode=0x{1} Java.Type={2} }} for managed type '{3}'.",
reference,
@@ -218,10 +221,28 @@ public override void ActivatePeer (IJavaPeerable? self, JniObjectReference refer
}
}
+ void ActivateViaMarshalMemberBuilder (JniRuntime.JniMarshalMemberBuilder builder, JniObjectReference reference, ConstructorInfo cinfo, object?[]? argumentValues)
+ {
+ var f = builder.CreateConstructActivationPeerFunc (cinfo);
+ f (cinfo, reference, argumentValues);
+ }
+
+ void ActivateViaReflection (JniObjectReference reference, ConstructorInfo cinfo, object?[]? argumentValues)
+ {
+ var declType = cinfo.DeclaringType ?? throw new NotSupportedException ("Do not know the type to create!");
+
+#pragma warning disable IL2072
+ var self = (IJavaPeerable) System.Runtime.CompilerServices.RuntimeHelpers.GetUninitializedObject (declType);
+#pragma warning restore IL2072
+ self.SetPeerReference (reference);
+
+ cinfo.Invoke (self, argumentValues);
+ }
+
public override List GetSurfacedPeers ()
{
if (RegisteredInstances == null)
- throw new ObjectDisposedException (nameof (MonoRuntimeValueManager));
+ throw new ObjectDisposedException (nameof (ManagedValueManager));
lock (RegisteredInstances) {
var peers = new List (RegisteredInstances.Count);
diff --git a/src/Java.Runtime.Environment/Java.Interop/MonoRuntimeObjectReferenceManager.cs b/src/Java.Runtime.Environment/Java.Interop/MonoRuntimeObjectReferenceManager.cs
index 82b4961ae..47812f237 100644
--- a/src/Java.Runtime.Environment/Java.Interop/MonoRuntimeObjectReferenceManager.cs
+++ b/src/Java.Runtime.Environment/Java.Interop/MonoRuntimeObjectReferenceManager.cs
@@ -13,19 +13,19 @@ class MonoRuntimeObjectReferenceManager : JniRuntime.JniObjectReferenceManager {
public override void OnSetRuntime (JniRuntime runtime)
{
base.OnSetRuntime (runtime);
- bridge = NativeMethods.java_interop_gc_bridge_get_current ();
+ bridge = JreNativeMethods.java_interop_gc_bridge_get_current ();
if (bridge != IntPtr.Zero) {
- logLocalRefs = NativeMethods.java_interop_gc_bridge_lref_get_log_file (bridge) != IntPtr.Zero;
- logGlobalRefs = NativeMethods.java_interop_gc_bridge_gref_get_log_file (bridge) != IntPtr.Zero;
+ logLocalRefs = JreNativeMethods.java_interop_gc_bridge_lref_get_log_file (bridge) != IntPtr.Zero;
+ logGlobalRefs = JreNativeMethods.java_interop_gc_bridge_gref_get_log_file (bridge) != IntPtr.Zero;
}
}
public override int GlobalReferenceCount {
- get {return NativeMethods.java_interop_gc_bridge_get_gref_count (bridge);}
+ get {return JreNativeMethods.java_interop_gc_bridge_get_gref_count (bridge);}
}
public override int WeakGlobalReferenceCount {
- get {return NativeMethods.java_interop_gc_bridge_get_weak_gref_count (bridge);}
+ get {return JreNativeMethods.java_interop_gc_bridge_get_weak_gref_count (bridge);}
}
public override bool LogLocalReferenceMessages {
@@ -36,8 +36,8 @@ public override void WriteLocalReferenceLine (string format, params object[] arg
{
if (!LogLocalReferenceMessages)
return;
- NativeMethods.java_interop_gc_bridge_lref_log_message (bridge, 0, string.Format (format, args));
- NativeMethods.java_interop_gc_bridge_lref_log_message (bridge, 0, "\n");
+ JreNativeMethods.java_interop_gc_bridge_lref_log_message (bridge, 0, string.Format (format, args));
+ JreNativeMethods.java_interop_gc_bridge_lref_log_message (bridge, 0, "\n");
}
public override JniObjectReference CreateLocalReference (JniObjectReference reference, ref int localReferenceCount)
@@ -46,7 +46,7 @@ public override JniObjectReference CreateLocalReference (JniObjectReference refe
return reference;
var r = base.CreateLocalReference (reference, ref localReferenceCount);
- NativeMethods.java_interop_gc_bridge_lref_log_new (bridge,
+ JreNativeMethods.java_interop_gc_bridge_lref_log_new (bridge,
localReferenceCount,
reference.Handle,
ToByte (reference.Type),
@@ -76,7 +76,7 @@ public override void DeleteLocalReference (ref JniObjectReference reference, ref
{
if (!reference.IsValid)
return;
- NativeMethods.java_interop_gc_bridge_lref_log_delete (bridge,
+ JreNativeMethods.java_interop_gc_bridge_lref_log_delete (bridge,
localReferenceCount,
reference.Handle,
ToByte (reference.Type),
@@ -91,7 +91,7 @@ public override void CreatedLocalReference (JniObjectReference reference, ref in
if (!reference.IsValid)
return;
base.CreatedLocalReference (reference, ref localReferenceCount);
- NativeMethods.java_interop_gc_bridge_lref_log_new (bridge,
+ JreNativeMethods.java_interop_gc_bridge_lref_log_new (bridge,
localReferenceCount,
reference.Handle,
ToByte (reference.Type),
@@ -106,7 +106,7 @@ public override IntPtr ReleaseLocalReference (ref JniObjectReference reference,
{
if (!reference.IsValid)
return IntPtr.Zero;
- NativeMethods.java_interop_gc_bridge_lref_log_delete (bridge,
+ JreNativeMethods.java_interop_gc_bridge_lref_log_delete (bridge,
localReferenceCount,
reference.Handle,
ToByte (reference.Type),
@@ -124,8 +124,8 @@ public override void WriteGlobalReferenceLine (string format, params object?[]?
{
if (!LogGlobalReferenceMessages)
return;
- NativeMethods.java_interop_gc_bridge_gref_log_message (bridge, 0, string.Format (format, args!));
- NativeMethods.java_interop_gc_bridge_gref_log_message (bridge, 0, "\n");
+ JreNativeMethods.java_interop_gc_bridge_gref_log_message (bridge, 0, string.Format (format, args!));
+ JreNativeMethods.java_interop_gc_bridge_gref_log_message (bridge, 0, "\n");
}
public override JniObjectReference CreateGlobalReference (JniObjectReference reference)
@@ -133,7 +133,7 @@ public override JniObjectReference CreateGlobalReference (JniObjectReference ref
if (!reference.IsValid)
return reference;
var n = base.CreateGlobalReference (reference);
- NativeMethods.java_interop_gc_bridge_gref_log_new (bridge,
+ JreNativeMethods.java_interop_gc_bridge_gref_log_new (bridge,
reference.Handle,
ToByte (reference.Type),
n.Handle,
@@ -148,7 +148,7 @@ public override void DeleteGlobalReference (ref JniObjectReference reference)
{
if (!reference.IsValid)
return;
- NativeMethods.java_interop_gc_bridge_gref_log_delete (bridge,
+ JreNativeMethods.java_interop_gc_bridge_gref_log_delete (bridge,
reference.Handle,
ToByte (reference.Type),
GetCurrentManagedThreadName (LogGlobalReferenceMessages),
@@ -162,7 +162,7 @@ public override JniObjectReference CreateWeakGlobalReference (JniObjectReference
if (!reference.IsValid)
return reference;
var n = base.CreateWeakGlobalReference (reference);
- NativeMethods.java_interop_gc_bridge_weak_gref_log_new (bridge,
+ JreNativeMethods.java_interop_gc_bridge_weak_gref_log_new (bridge,
reference.Handle,
ToByte (reference.Type),
n.Handle,
@@ -177,7 +177,7 @@ public override void DeleteWeakGlobalReference (ref JniObjectReference reference
{
if (!reference.IsValid)
return;
- NativeMethods.java_interop_gc_bridge_weak_gref_log_delete (bridge,
+ JreNativeMethods.java_interop_gc_bridge_weak_gref_log_delete (bridge,
reference.Handle,
ToByte (reference.Type),
GetCurrentManagedThreadName (LogGlobalReferenceMessages),
@@ -202,7 +202,7 @@ static byte ToByte (JniObjectReferenceType type)
}
}
- partial class NativeMethods {
+ partial class JreNativeMethods {
[DllImport (JavaInteropLib, CallingConvention=CallingConvention.Cdecl)]
internal static extern int java_interop_gc_bridge_get_gref_count (IntPtr bridge);
diff --git a/src/Java.Runtime.Environment/Java.Interop/MonoRuntimeValueManager.cs b/src/Java.Runtime.Environment/Java.Interop/MonoRuntimeValueManager.cs
index 223d03f4b..f0edf42d3 100644
--- a/src/Java.Runtime.Environment/Java.Interop/MonoRuntimeValueManager.cs
+++ b/src/Java.Runtime.Environment/Java.Interop/MonoRuntimeValueManager.cs
@@ -27,32 +27,32 @@ public override void OnSetRuntime (JniRuntime runtime)
{
base.OnSetRuntime (runtime);
- bridge = NativeMethods.java_interop_gc_bridge_get_current ();
+ bridge = JreNativeMethods.java_interop_gc_bridge_get_current ();
if (bridge != IntPtr.Zero)
return;
- bridge = NativeMethods.java_interop_gc_bridge_new (runtime.InvocationPointer);
+ bridge = JreNativeMethods.java_interop_gc_bridge_new (runtime.InvocationPointer);
if (bridge == IntPtr.Zero)
throw new NotSupportedException ("Could not initialize JNI::Mono GC Bridge!");
try {
- if (NativeMethods.java_interop_gc_bridge_set_bridge_processing_field (bridge, typeof (MonoRuntimeValueManager).TypeHandle, nameof (GCBridgeProcessingIsActive)) < 0)
+ if (JreNativeMethods.java_interop_gc_bridge_set_bridge_processing_field (bridge, typeof (MonoRuntimeValueManager).TypeHandle, nameof (GCBridgeProcessingIsActive)) < 0)
throw new NotSupportedException ("Could not set bridge processing field!");
foreach (var t in new[]{typeof (JavaObject), typeof (JavaException)}) {
- if (NativeMethods.java_interop_gc_bridge_register_bridgeable_type (bridge, t.TypeHandle) < 0)
+ if (JreNativeMethods.java_interop_gc_bridge_register_bridgeable_type (bridge, t.TypeHandle) < 0)
throw new NotSupportedException ("Could not register type " + t.FullName + "!");
}
- if (NativeMethods.java_interop_gc_bridge_add_current_app_domain (bridge) < 0)
+ if (JreNativeMethods.java_interop_gc_bridge_add_current_app_domain (bridge) < 0)
throw new NotSupportedException ("Could not register current AppDomain!");
- if (NativeMethods.java_interop_gc_bridge_set_current_once (bridge) < 0)
+ if (JreNativeMethods.java_interop_gc_bridge_set_current_once (bridge) < 0)
throw new NotSupportedException ("Could not set GC Bridge instance!");
}
catch (Exception) {
- NativeMethods.java_interop_gc_bridge_free (bridge);
+ JreNativeMethods.java_interop_gc_bridge_free (bridge);
bridge = IntPtr.Zero;
throw;
}
- if (NativeMethods.java_interop_gc_bridge_register_hooks (bridge, GCBridgeUseWeakReferenceKind.Jni) < 0)
+ if (JreNativeMethods.java_interop_gc_bridge_register_hooks (bridge, GCBridgeUseWeakReferenceKind.Jni) < 0)
throw new NotSupportedException ("Could not register GC Bridge with Mono!");
}
@@ -60,7 +60,7 @@ public override void WaitForGCBridgeProcessing ()
{
if (!GCBridgeProcessingIsActive)
return;
- NativeMethods.java_interop_gc_bridge_wait_for_bridge_processing (bridge);
+ JreNativeMethods.java_interop_gc_bridge_wait_for_bridge_processing (bridge);
}
public override void CollectPeers ()
@@ -92,7 +92,7 @@ protected override void Dispose (bool disposing)
}
if (bridge != IntPtr.Zero) {
- NativeMethods.java_interop_gc_bridge_remove_current_app_domain (bridge);
+ JreNativeMethods.java_interop_gc_bridge_remove_current_app_domain (bridge);
bridge = IntPtr.Zero;
}
}
@@ -382,7 +382,7 @@ internal static void Collect ()
}
}
- partial class NativeMethods {
+ partial class JreNativeMethods {
const string JavaInteropLib = "java-interop";