From ca39e4da148b88bf6967a49a34f96bc85b3e6a76 Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Tue, 4 Mar 2025 15:50:10 -0600 Subject: [PATCH] [tests] fix trimmer warnings in Java.Interop-Tests Context: https://github.com/dotnet/android/pull/9846 When building `Mono.Android.NET-Tests.csproj` for NativeAOT, you end up with many warnings (that are upgraded to errors): external/Java.Interop/tests/Java.Interop-Tests/Java.Interop/JniEnvironmentTests.cs(92,4): error IL2026: Using member 'System.Reflection.Assembly.GetType(String, Boolean)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Types might be removed by trimming. If the type name is a string literal, consider using Type.GetType instead. external/Java.Interop/tests/Java.Interop-Tests/Java.Interop/JniEnvironmentTests.cs(93,4): error IL2026: Using member 'System.Reflection.Assembly.GetType(String, Boolean)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Types might be removed by trimming. If the type name is a string literal, consider using Type.GetType instead. external/Java.Interop/tests/Java.Interop-Tests/Java.Interop/JavaObjectArrayTest.cs(15,11): error IL2091: 'T' generic argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors', 'DynamicallyAccessedMemberTypes.NonPublicConstructors' in 'Java.Interop.JavaObjectArray'. The generic parameter 'T' of 'Java.InteropTests.JavaObjectArrayContractTest' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. external/Java.Interop/tests/Java.Interop-Tests/Java.Interop/JavaObjectArrayTest.cs(21,48): error IL2091: 'T' generic argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors', 'DynamicallyAccessedMemberTypes.NonPublicConstructors' in 'Java.Interop.JavaObjectArray'. The generic parameter 'T' of 'Java.InteropTests.JavaObjectArrayContractTest' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. external/Java.Interop/tests/Java.Interop-Tests/Java.Interop/JavaObjectArrayTest.cs(22,48): error IL2091: 'T' generic argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors', 'DynamicallyAccessedMemberTypes.NonPublicConstructors' in 'Java.Interop.JavaObjectArray'. The generic parameter 'T' of 'Java.InteropTests.JavaObjectArrayContractTest' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. external/Java.Interop/tests/Java.Interop-Tests/Java.Interop/JavaObjectArrayTest.cs(23,44): error IL2091: 'T' generic argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors', 'DynamicallyAccessedMemberTypes.NonPublicConstructors' in 'Java.Interop.JavaObjectArray'. The generic parameter 'T' of 'Java.InteropTests.JavaObjectArrayContractTest' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. external/Java.Interop/tests/Java.Interop-Tests/Java.Interop/JavaExceptionTests.cs(105,34): error IL2026: Using member 'System.Reflection.Assembly.GetType(String, Boolean)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Types might be removed by trimming. If the type name is a string literal, consider using Type.GetType instead. external/Java.Interop/tests/Java.Interop-Tests/Java.Interop/JavaExceptionTests.cs(108,34): error IL2072: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors' in call to 'System.Activator.CreateInstance(Type, params Object[])'. The return value of method 'System.Reflection.Assembly.GetType(String, Boolean)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. external/Java.Interop/tests/Java.Interop-Tests/Java.Interop/JniEnvironmentTests.cs(99,41): error IL2077: 'target' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods', 'DynamicallyAccessedMemberTypes.NonPublicMethods' in call to 'System.Delegate.CreateDelegate(Type, Type, String, Boolean, Boolean)'. The field 'Java.InteropTests.JniEnvironmentTests.NativeMethods_type' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. external/Java.Interop/tests/Java.Interop-Tests/Java.Interop/JniEnvironmentTests.cs(111,35): error IL2077: 'target' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods', 'DynamicallyAccessedMemberTypes.NonPublicMethods' in call to 'System.Delegate.CreateDelegate(Type, Type, String, Boolean, Boolean)'. The field 'Java.InteropTests.JniEnvironmentTests.NativeMethods_type' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. external/Java.Interop/tests/Java.Interop-Tests/Java.Interop/JniValueMarshalerContractTests.cs(650,127): error IL2092: 'DynamicallyAccessedMemberTypes' in 'DynamicallyAccessedMembersAttribute' on the parameter 'targetType' of method 'Java.InteropTests.DemoValueTypeValueMarshaler.CreateGenericValue(ref JniObjectReference, JniObjectReferenceOptions, Type)' don't match overridden parameter 'targetType' of method 'Java.Interop.JniValueMarshaler.CreateGenericValue(ref JniObjectReference, JniObjectReferenceOptions, Type)'. All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage. external/Java.Interop/tests/Java.Interop-Tests/Java.Interop/JniRuntimeJniValueManagerContract.cs(28,18): error IL2072: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicParameterlessConstructor' in call to 'System.Activator.CreateInstance(Type)'. The return value of method 'Java.InteropTests.JniRuntimeJniValueManagerContract.ValueManagerType.get' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. external/Java.Interop/tests/Java.Interop-Tests/Java.Interop/JniValueMarshalerContractTests.cs(36,35): error IL2091: 'T' generic argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors', 'DynamicallyAccessedMemberTypes.NonPublicConstructors' in 'Java.Interop.JniRuntime.JniValueManager.GetValueMarshaler()'. The generic parameter 'T' of 'Java.InteropTests.JniValueMarshalerContractTests' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. external/Java.Interop/tests/Java.Interop-Tests/Java.Interop/JniValueMarshalerContractTests.cs(224,18): error IL2026: Using member 'Java.Interop.JniValueMarshaler.CreateReturnValueFromManagedExpression(JniValueMarshalerContext, ParameterExpression)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. System.Linq.Expression usage may trim away required code. external/Java.Interop/tests/Java.Interop-Tests/Java.Interop/JniValueMarshalerContractTests.cs(224,18): error IL3050: Using member 'Java.Interop.JniValueMarshaler.CreateReturnValueFromManagedExpression(JniValueMarshalerContext, ParameterExpression)' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. System.Linq.Expression usage may trim away required code. We can address these here by importing: And then solving the warnings (that are now errors) by adding missing attributes. This might also improve the chances of these tests passing under NativeAOT, in general. --- .../Java.Interop-Tests.csproj | 1 + .../Java.Interop/JavaExceptionTests.cs | 4 +-- .../Java.Interop/JavaObjectArrayTest.cs | 6 +++- .../Java.Interop/JniEnvironmentTests.cs | 6 ++-- .../JniRuntimeJniValueManagerContract.cs | 12 ++++++-- .../JniValueMarshalerContractTests.cs | 28 +++++++++++++++---- 6 files changed, 44 insertions(+), 13 deletions(-) diff --git a/tests/Java.Interop-Tests/Java.Interop-Tests.csproj b/tests/Java.Interop-Tests/Java.Interop-Tests.csproj index 4e881e793..b4ae99498 100644 --- a/tests/Java.Interop-Tests/Java.Interop-Tests.csproj +++ b/tests/Java.Interop-Tests/Java.Interop-Tests.csproj @@ -10,6 +10,7 @@ + $(TestOutputFullPath) diff --git a/tests/Java.Interop-Tests/Java.Interop/JavaExceptionTests.cs b/tests/Java.Interop-Tests/Java.Interop/JavaExceptionTests.cs index 8469b55a4..d82a7ac0a 100644 --- a/tests/Java.Interop-Tests/Java.Interop/JavaExceptionTests.cs +++ b/tests/Java.Interop-Tests/Java.Interop/JavaExceptionTests.cs @@ -102,9 +102,7 @@ public void InnerExceptionIsNotAProxy () static JavaException CreateJavaProxyThrowable (Exception value) { - var JavaProxyThrowable_type = typeof(JavaObject) - .Assembly - .GetType ("Java.Interop.JavaProxyThrowable", throwOnError :true); + var JavaProxyThrowable_type = Type.GetType ("Java.Interop.JavaProxyThrowable, Java.Interop", throwOnError :true); var proxy = (JavaException) Activator.CreateInstance (JavaProxyThrowable_type, value); return proxy; } diff --git a/tests/Java.Interop-Tests/Java.Interop/JavaObjectArrayTest.cs b/tests/Java.Interop-Tests/Java.Interop/JavaObjectArrayTest.cs index b3e83c654..f02bbc06b 100644 --- a/tests/Java.Interop-Tests/Java.Interop/JavaObjectArrayTest.cs +++ b/tests/Java.Interop-Tests/Java.Interop/JavaObjectArrayTest.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using Java.Interop; @@ -8,7 +9,10 @@ namespace Java.InteropTests { - public abstract class JavaObjectArrayContractTest : JavaArrayContract + public abstract class JavaObjectArrayContractTest< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] + T + > : JavaArrayContract { protected override System.Collections.Generic.ICollection CreateCollection (System.Collections.Generic.IEnumerable values) { diff --git a/tests/Java.Interop-Tests/Java.Interop/JniEnvironmentTests.cs b/tests/Java.Interop-Tests/Java.Interop/JniEnvironmentTests.cs index b24626161..fd91beb3d 100644 --- a/tests/Java.Interop-Tests/Java.Interop/JniEnvironmentTests.cs +++ b/tests/Java.Interop-Tests/Java.Interop/JniEnvironmentTests.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using Java.Interop; @@ -88,9 +89,10 @@ public void References_CreatedReference_LocalRef () } } + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] static readonly Type NativeMethods_type = - typeof (JniEnvironment).Assembly.GetType ("Java.Interop.NativeMethods", throwOnError: false) ?? - typeof (JniEnvironment).Assembly.GetType ("Java.Interop.JIPinvokes.NativeMethods", throwOnError: false); + Type.GetType ("Java.Interop.NativeMethods, Java.Interop", throwOnError: false) ?? + Type.GetType ("Java.Interop.JIPinvokes.NativeMethods, Java.Interop", throwOnError: false); static Func GetNewRefFunc (string method) { diff --git a/tests/Java.Interop-Tests/Java.Interop/JniRuntimeJniValueManagerContract.cs b/tests/Java.Interop-Tests/Java.Interop/JniRuntimeJniValueManagerContract.cs index 21727ce2e..782b6e765 100644 --- a/tests/Java.Interop-Tests/Java.Interop/JniRuntimeJniValueManagerContract.cs +++ b/tests/Java.Interop-Tests/Java.Interop/JniRuntimeJniValueManagerContract.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; using System.Threading; @@ -19,6 +20,7 @@ namespace Java.InteropTests { #endif // !__ANDROID__ public abstract class JniRuntimeJniValueManagerContract : JavaVMFixture { + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] protected abstract Type ValueManagerType { get; } @@ -296,8 +298,12 @@ static string DumpPeers (IEnumerable peers) // Adding an instance already added in a previous scope? } - public abstract class JniRuntimeJniValueManagerContract : JniRuntimeJniValueManagerContract { - + public abstract class JniRuntimeJniValueManagerContract< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] + T + > : JniRuntimeJniValueManagerContract + { + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] protected override Type ValueManagerType => typeof (T); } @@ -313,8 +319,10 @@ public class JniRuntimeJniValueManagerContract_Mono : JniRuntimeJniValueManagerC [TestFixture] public class JniRuntimeJniValueManagerContract_NoGCIntegration : JniRuntimeJniValueManagerContract { + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] static Type ManagedValueManagerType = Type.GetType ("Java.Interop.ManagedValueManager, Java.Runtime.Environment", throwOnError:true)!; + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] protected override Type ValueManagerType => ManagedValueManagerType; } #endif // !__ANDROID__ diff --git a/tests/Java.Interop-Tests/Java.Interop/JniValueMarshalerContractTests.cs b/tests/Java.Interop-Tests/Java.Interop/JniValueMarshalerContractTests.cs index 0608ff18a..3c5668b66 100644 --- a/tests/Java.Interop-Tests/Java.Interop/JniValueMarshalerContractTests.cs +++ b/tests/Java.Interop-Tests/Java.Interop/JniValueMarshalerContractTests.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Linq.Expressions; using System.Reflection; @@ -13,7 +14,11 @@ namespace Java.InteropTests { - public abstract class JniValueMarshalerContractTests : JavaVMFixture { + public abstract class JniValueMarshalerContractTests< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] + T + > : JavaVMFixture + { protected abstract T Value {get;} @@ -211,6 +216,8 @@ public void DestroyGenericArgumentState () } [Test] + [RequiresUnreferencedCode ("CreateReturnValueFromManagedExpression")] + [RequiresDynamicCode ("CreateReturnValueFromManagedExpression")] public void CreateReturnValueFromManagedExpression () { var runtime = Expression.Variable (typeof (JniRuntime), "__jvm"); @@ -335,7 +342,11 @@ protected override string GetExpectedReturnValueFromManagedExpression (string jv } } - public abstract class JniValueMarshaler_BuiltinType_ContractTests : JniValueMarshalerContractTests { + public abstract class JniValueMarshaler_BuiltinType_ContractTests< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] + T + > : JniValueMarshalerContractTests + { protected override bool IsJniValueType {get {return true;}} protected override string GetExpectedReturnValueFromManagedExpression (string jvm, string value, Expression ret) @@ -442,8 +453,11 @@ public class JniValueMarshaler_NullableDouble_ContractTests : JniValueMarshalerC protected override double? Value {get {return 8D;}} } - public abstract class JniInt32ArrayValueMarshalerContractTests : JniValueMarshalerContractTests - where T : IEnumerable + public abstract class JniInt32ArrayValueMarshalerContractTests< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] + T + > : JniValueMarshalerContractTests + where T : IEnumerable { protected abstract T CreateArray (int[] values); protected abstract string ValueMarshalerSourceType {get;} @@ -647,7 +661,11 @@ public DemoValueTypeValueMarshaler () Int32Marshaler = JniRuntime.CurrentRuntime.ValueManager.GetValueMarshaler (); } - public override DemoValueType CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type targetType) + public override DemoValueType CreateGenericValue ( + ref JniObjectReference reference, + JniObjectReferenceOptions options, + [DynamicallyAccessedMembers (Constructors)] + Type targetType) { var v = Int32Marshaler.CreateGenericValue (ref reference, options, typeof (int)); return new DemoValueType (v);