diff --git a/build-tools/Java.Interop.Sdk/Sdk/Sdk.targets b/build-tools/Java.Interop.Sdk/Sdk/Sdk.targets index 92ef90e2a..466fb605d 100644 --- a/build-tools/Java.Interop.Sdk/Sdk/Sdk.targets +++ b/build-tools/Java.Interop.Sdk/Sdk/Sdk.targets @@ -64,6 +64,7 @@ @@ -105,6 +106,7 @@ @@ -120,6 +122,7 @@ diff --git a/samples/Hello-Java.Base/Hello-Java.Base.csproj b/samples/Hello-Java.Base/Hello-Java.Base.csproj index e2d023c86..1405024ff 100644 --- a/samples/Hello-Java.Base/Hello-Java.Base.csproj +++ b/samples/Hello-Java.Base/Hello-Java.Base.csproj @@ -7,6 +7,14 @@ enable Hello.App + + + + + + + $(MSBuildThisFileDirectory)bin\$(Configuration)\ + @@ -15,4 +23,6 @@ + + diff --git a/samples/Hello-Java.Base/Program.cs b/samples/Hello-Java.Base/Program.cs index b1e0d5bac..733590374 100644 --- a/samples/Hello-Java.Base/Program.cs +++ b/samples/Hello-Java.Base/Program.cs @@ -1,5 +1,8 @@ using System; +using System.Collections.Generic; using System.Diagnostics; +using System.Linq; +using System.IO; using System.Threading; using Mono.Options; @@ -26,7 +29,7 @@ public static void Main (string[] args) $"{{PATH}} to JVM to use. Default is:\n {jvmPath}", v => jvmPath = v }, { "m", - "Create multiple Java VMs. This will likely creash.", + "Create multiple Java VMs. This will likely crash.", v => createMultipleVMs = v != null }, { "t", $"Timing; invoke Object.hashCode() {N} times, print average.", @@ -43,6 +46,12 @@ public static void Main (string[] args) var builder = new JreRuntimeOptions () { JniAddNativeMethodRegistrationAttributePresent = true, JvmLibraryPath = jvmPath, + ClassPath = { + Path.Combine (Path.GetDirectoryName (typeof (App).Assembly.Location)!, "Hello-Java.Base.jar"), + }, + TypeMappings = { + [MyJLO.JniTypeName] = typeof (MyJLO), + }, }; builder.AddOption ("-Xcheck:jni"); @@ -63,7 +72,7 @@ public static void Main (string[] args) static void CreateJLO () { - var jlo = new Java.Lang.Object (); + var jlo = new MyJLO (); Console.WriteLine ($"binding? {jlo.ToString ()}"); } @@ -115,4 +124,9 @@ static unsafe void CreateAnotherJVM () } } } + + [JniTypeSignature (JniTypeName)] + class MyJLO : Java.Lang.Object { + internal const string JniTypeName = "net/dot/jni/sample/MyJLO"; + } } diff --git a/src/Java.Runtime.Environment/Java.Interop/JreRuntime.cs b/src/Java.Runtime.Environment/Java.Interop/JreRuntime.cs index 811523b35..8da7d8909 100644 --- a/src/Java.Runtime.Environment/Java.Interop/JreRuntime.cs +++ b/src/Java.Runtime.Environment/Java.Interop/JreRuntime.cs @@ -35,6 +35,9 @@ public class JreRuntimeOptions : JniRuntime.CreationOptions { public TextWriter? JniGlobalReferenceLogWriter {get; set;} public TextWriter? JniLocalReferenceLogWriter {get; set;} + internal Dictionary? typeMappings; + public IDictionary TypeMappings => typeMappings ??= new (); + internal JvmLibraryHandler? LibraryHandler {get; set;} public JreRuntimeOptions () @@ -85,7 +88,7 @@ static unsafe JreRuntimeOptions CreateJreVM (JreRuntimeOptions builder) builder.LibraryHandler = JvmLibraryHandler.Create (); #if NET - builder.TypeManager ??= new JreTypeManager (); + builder.TypeManager ??= new JreTypeManager (builder.typeMappings); #endif // NET bool onMono = Type.GetType ("Mono.Runtime", throwOnError: false) != null; diff --git a/src/Java.Runtime.Environment/Java.Interop/JreTypeManager.cs b/src/Java.Runtime.Environment/Java.Interop/JreTypeManager.cs index 061b4e7ad..7be7bbee9 100644 --- a/src/Java.Runtime.Environment/Java.Interop/JreTypeManager.cs +++ b/src/Java.Runtime.Environment/Java.Interop/JreTypeManager.cs @@ -18,6 +18,44 @@ namespace Java.Interop { public class JreTypeManager : JniRuntime.JniTypeManager { + IDictionary? typeMappings; + + public JreTypeManager () + : this (null) + { + } + + public JreTypeManager (IDictionary? typeMappings) + { + this.typeMappings = typeMappings; + } + + protected override IEnumerable GetTypesForSimpleReference (string jniSimpleReference) + { + foreach (var t in base.GetTypesForSimpleReference (jniSimpleReference)) + yield return t; + if (typeMappings == null) + yield break; + if (typeMappings.TryGetValue (jniSimpleReference, out var target)) + yield return target; + } + + 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; + } + } + const string NotUsedInAndroid = "This code path is not used in Android projects."; public override void RegisterNativeMembers ( diff --git a/tests/TestJVM/TestJVM.cs b/tests/TestJVM/TestJVM.cs index caf00ad44..0272b7142 100644 --- a/tests/TestJVM/TestJVM.cs +++ b/tests/TestJVM/TestJVM.cs @@ -23,7 +23,6 @@ public TestJVMOptions (Assembly? callingAssembly = null) public ICollection JarFilePaths {get;} = new List (); public Assembly CallingAssembly {get; set;} - public Dictionary? TypeMappings {get; set;} internal JdkInfo? JdkInfo {get; set;} } @@ -141,9 +140,13 @@ public TestJVM (string[]? jars = null, Dictionary? typeMappings = static TestJVMOptions CreateOptions (string[]? jarFiles, Assembly callingAssembly, Dictionary? typeMappings) { var o = new TestJVMOptions { - TypeMappings = typeMappings, CallingAssembly = callingAssembly, }; + if (typeMappings != null) { + foreach (var e in typeMappings) { + o.TypeMappings.Add (e.Key, e.Value); + } + } if (jarFiles != null) { foreach (var jar in jarFiles) { o.JarFilePaths.Add (jar); @@ -153,48 +156,12 @@ static TestJVMOptions CreateOptions (string[]? jarFiles, Assembly callingAssembl } } - public class TestJvmTypeManager : -#if NET - JreTypeManager -#else // !NET - JniRuntime.JniTypeManager -#endif // !NET + public class TestJvmTypeManager : JreTypeManager { - Dictionary? typeMappings; - - public TestJvmTypeManager (Dictionary? typeMappings) + public TestJvmTypeManager (IDictionary? typeMappings) + : base (typeMappings) { - this.typeMappings = typeMappings; - } - - protected override IEnumerable GetTypesForSimpleReference (string jniSimpleReference) - { - foreach (var t in base.GetTypesForSimpleReference (jniSimpleReference)) - yield return t; - if (typeMappings == null) - yield break; - Type target; -#pragma warning disable CS8600 // huh? - if (typeMappings.TryGetValue (jniSimpleReference, out target)) - yield return target; -#pragma warning restore CS8600 - } - - 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; - } } } }