From 63f8023791c8c74704541b1f5b23c5de90221caf Mon Sep 17 00:00:00 2001 From: Jonathan Pobst Date: Thu, 21 Nov 2024 09:25:20 -1000 Subject: [PATCH 1/4] [build] Target net9.0 --- Directory.Build.props | 2 +- build-tools/automation/azure-pipelines.yaml | 4 ++-- src/Java.Interop/Java.Interop/JniValueMarshaler.cs | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 8aa75e7b4..5da999fb1 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -9,7 +9,7 @@ true true - 8.0 + 9.0 net$(DotNetTargetFrameworkVersion) diff --git a/build-tools/automation/azure-pipelines.yaml b/build-tools/automation/azure-pipelines.yaml index 8fe06a4a7..a534ca2e3 100644 --- a/build-tools/automation/azure-pipelines.yaml +++ b/build-tools/automation/azure-pipelines.yaml @@ -19,8 +19,8 @@ pr: variables: RunningOnCI: true Build.Configuration: Release - DotNetCoreVersion: 8.0.303 - DotNetTargetFramework: net8.0 + DotNetCoreVersion: 9.0.100 + DotNetTargetFramework: net9.0 NetCoreTargetFrameworkPathSuffix: -$(DotNetTargetFramework) HostedPoolName: Azure Pipelines HostedWinImage: windows-2022 diff --git a/src/Java.Interop/Java.Interop/JniValueMarshaler.cs b/src/Java.Interop/Java.Interop/JniValueMarshaler.cs index 4238108f9..f7d911ba5 100644 --- a/src/Java.Interop/Java.Interop/JniValueMarshaler.cs +++ b/src/Java.Interop/Java.Interop/JniValueMarshaler.cs @@ -177,6 +177,7 @@ Expression CreateSelf (JniValueMarshalerContext context, ParameterExpression sou return self; } + [UnconditionalSuppressMessage ("Trimming", "IL2073", Justification = ExpressionRequiresUnreferencedCode)] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type _GetType () => GetType (); From acadec3e20dee13cd80334a8b6c9538104001999 Mon Sep 17 00:00:00 2001 From: Jonathan Pobst Date: Wed, 15 Jan 2025 10:48:57 -1000 Subject: [PATCH 2/4] Try .NET `9.0.200` --- build-tools/automation/azure-pipelines.yaml | 2 +- ...buggerDisableUserUnhandledExceptionsAttribute.cs | 13 ------------- 2 files changed, 1 insertion(+), 14 deletions(-) delete mode 100644 tests/generator-Tests/SupportFiles/DebuggerDisableUserUnhandledExceptionsAttribute.cs diff --git a/build-tools/automation/azure-pipelines.yaml b/build-tools/automation/azure-pipelines.yaml index a534ca2e3..d23031a36 100644 --- a/build-tools/automation/azure-pipelines.yaml +++ b/build-tools/automation/azure-pipelines.yaml @@ -19,7 +19,7 @@ pr: variables: RunningOnCI: true Build.Configuration: Release - DotNetCoreVersion: 9.0.100 + DotNetCoreVersion: 9.0.200 DotNetTargetFramework: net9.0 NetCoreTargetFrameworkPathSuffix: -$(DotNetTargetFramework) HostedPoolName: Azure Pipelines diff --git a/tests/generator-Tests/SupportFiles/DebuggerDisableUserUnhandledExceptionsAttribute.cs b/tests/generator-Tests/SupportFiles/DebuggerDisableUserUnhandledExceptionsAttribute.cs deleted file mode 100644 index 079616b91..000000000 --- a/tests/generator-Tests/SupportFiles/DebuggerDisableUserUnhandledExceptionsAttribute.cs +++ /dev/null @@ -1,13 +0,0 @@ -#if !NET9_0_OR_GREATER - -using System; - -namespace System.Diagnostics -{ - // This attribute was added in .NET 9, and we may not be targeting .NET 9 yet. - public class DebuggerDisableUserUnhandledExceptionsAttribute : Attribute - { - } -} - -#endif // !NET9_0_OR_GREATER From 0d6099b8c47618f98307942e4a124884144deb4f Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Wed, 12 Feb 2025 16:19:17 -0600 Subject: [PATCH 3/4] Fix (silence?) trimmer warnings Most of these callsites are not called on Android anyway. We can silence them as a way to not introduce new warnings. --- .../Java.Interop/MarshalMemberBuilder.cs | 5 +++++ .../JniRuntime.JniMarshalMemberBuilder.cs | 5 +++++ .../Java.Interop/JniRuntime.JniTypeManager.cs | 15 ++++++--------- .../Java.Interop/JniRuntime.JniValueManager.cs | 5 ++--- .../Java.Interop/JreTypeManager.cs | 17 +++++++++++++++-- .../Java.Interop/ManagedValueManager.cs | 12 +++++++++--- 6 files changed, 42 insertions(+), 17 deletions(-) diff --git a/src/Java.Interop.Export/Java.Interop/MarshalMemberBuilder.cs b/src/Java.Interop.Export/Java.Interop/MarshalMemberBuilder.cs index 6b3e4458b..159db9fed 100644 --- a/src/Java.Interop.Export/Java.Interop/MarshalMemberBuilder.cs +++ b/src/Java.Interop.Export/Java.Interop/MarshalMemberBuilder.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Linq.Expressions; using System.Reflection; @@ -11,8 +12,12 @@ namespace Java.Interop { + [RequiresDynamicCode (ExpressionRequiresUnreferencedCode)] + [RequiresUnreferencedCode (ExpressionRequiresUnreferencedCode)] public class MarshalMemberBuilder : JniRuntime.JniMarshalMemberBuilder { + internal const string ExpressionRequiresUnreferencedCode = "System.Linq.Expression usage may trim away required code."; + public MarshalMemberBuilder () { } diff --git a/src/Java.Interop/Java.Interop/JniRuntime.JniMarshalMemberBuilder.cs b/src/Java.Interop/Java.Interop/JniRuntime.JniMarshalMemberBuilder.cs index b74d6ec87..2670e09f6 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.JniMarshalMemberBuilder.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.JniMarshalMemberBuilder.cs @@ -29,8 +29,13 @@ public JniMarshalMemberBuilder MarshalMemberBuilder { internal bool UseMarshalMemberBuilder => marshalMemberBuilder != null; + const string NotUsedInAndroid = "This code path is not used in Android projects."; + + // FIXME: https://github.com/dotnet/java-interop/issues/1192 [DynamicDependency (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor, "Java.Interop.MarshalMemberBuilder", "Java.Interop.Export")] + [UnconditionalSuppressMessage ("Trimming", "IL2026", Justification = NotUsedInAndroid)] [UnconditionalSuppressMessage ("Trimming", "IL2035", Justification = "Java.Interop.Export.dll is not always present.")] + [UnconditionalSuppressMessage ("Trimming", "IL3050", Justification = NotUsedInAndroid)] partial void SetMarshalMemberBuilder (CreationOptions options) { if (!options.UseMarshalMemberBuilder) { diff --git a/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs b/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs index a6acbe77a..9a8e5be9d 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs @@ -266,18 +266,16 @@ protected virtual IEnumerable GetSimpleReferences (Type type) static readonly Type[] EmptyTypeArray = Array.Empty (); const string NotUsedInAndroid = "This code path is not used in Android projects."; + // FIXME: https://github.com/dotnet/java-interop/issues/1192 + [UnconditionalSuppressMessage ("Trimming", "IL3050", Justification = NotUsedInAndroid)] static Type MakeArrayType (Type type) => - // FIXME: https://github.com/dotnet/java-interop/issues/1192 - #pragma warning disable IL3050 type.MakeArrayType (); - #pragma warning restore IL3050 + // FIXME: https://github.com/dotnet/java-interop/issues/1192 [UnconditionalSuppressMessage ("Trimming", "IL2055", Justification = NotUsedInAndroid)] + [UnconditionalSuppressMessage ("Trimming", "IL3050", Justification = NotUsedInAndroid)] static Type MakeGenericType (Type type, Type arrayType) => - // FIXME: https://github.com/dotnet/java-interop/issues/1192 - #pragma warning disable IL3050 type.MakeGenericType (arrayType); - #pragma warning restore IL3050 [UnconditionalSuppressMessage ("Trimming", "IL2073", Justification = "Types returned here should be preserved via other means.")] [return: DynamicallyAccessedMembers (MethodsConstructors)] @@ -400,16 +398,15 @@ IEnumerable CreateGetTypesForSimpleReferenceEnumerator (string jniSimpleRe // https://github.com/xamarin/xamarin-android/blob/5472eec991cc075e4b0c09cd98a2331fb93aa0f3/src/Microsoft.Android.Sdk.ILLink/MarkJavaObjects.cs#L176-L186 const string makeGenericTypeMessage = "Generic 'Invoker' types are preserved by the MarkJavaObjects trimmer step."; + // FIXME: https://github.com/dotnet/java-interop/issues/1192 [UnconditionalSuppressMessage ("Trimming", "IL2055", Justification = makeGenericTypeMessage)] + [UnconditionalSuppressMessage ("Trimming", "IL3050", Justification = makeGenericTypeMessage)] [return: DynamicallyAccessedMembers (Constructors)] static Type MakeGenericType ( [DynamicallyAccessedMembers (Constructors)] Type type, Type [] arguments) => - // FIXME: https://github.com/dotnet/java-interop/issues/1192 - #pragma warning disable IL3050 type.MakeGenericType (arguments); - #pragma warning restore IL3050 var signature = type.GetCustomAttribute (); if (signature == null || signature.InvokerType == null) { diff --git a/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs b/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs index eb9e23790..36a4745c5 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs @@ -675,12 +675,11 @@ static JniValueMarshaler GetObjectArrayMarshaler (Type elementType) { const string makeGenericMethodMessage = "This code path is not used in Android projects."; + // FIXME: https://github.com/dotnet/java-interop/issues/1192 [UnconditionalSuppressMessage ("Trimming", "IL2060", Justification = makeGenericMethodMessage)] + [UnconditionalSuppressMessage ("Trimming", "IL3050", Justification = makeGenericMethodMessage)] static MethodInfo MakeGenericMethod (MethodInfo method, Type type) => - // FIXME: https://github.com/dotnet/java-interop/issues/1192 - #pragma warning disable IL3050 method.MakeGenericMethod (type); - #pragma warning restore IL3050 Func indirect = GetObjectArrayMarshalerHelper; var reifiedMethodInfo = MakeGenericMethod ( diff --git a/src/Java.Runtime.Environment/Java.Interop/JreTypeManager.cs b/src/Java.Runtime.Environment/Java.Interop/JreTypeManager.cs index 4912b6877..061b4e7ad 100644 --- a/src/Java.Runtime.Environment/Java.Interop/JreTypeManager.cs +++ b/src/Java.Runtime.Environment/Java.Interop/JreTypeManager.cs @@ -4,6 +4,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; @@ -17,7 +18,13 @@ namespace Java.Interop { public class JreTypeManager : JniRuntime.JniTypeManager { - public override void RegisterNativeMembers (JniType nativeClass, Type type, ReadOnlySpan methods) + const string NotUsedInAndroid = "This code path is not used in Android projects."; + + public override void RegisterNativeMembers ( + JniType nativeClass, + [DynamicallyAccessedMembers (MethodsAndPrivateNested)] + Type type, + ReadOnlySpan methods) { if (base.TryRegisterNativeMembers (nativeClass, type, methods)) { return; @@ -63,6 +70,10 @@ public override void RegisterNativeMembers (JniType nativeClass, Type type, Read nativeClass.RegisterNativeMethods (registrations.ToArray ()); } + // FIXME: https://github.com/dotnet/java-interop/issues/1192 + [UnconditionalSuppressMessage ("Trimming", "IL2062", Justification = NotUsedInAndroid)] + [UnconditionalSuppressMessage ("Trimming", "IL2070", Justification = NotUsedInAndroid)] + [UnconditionalSuppressMessage ("Trimming", "IL2078", Justification = NotUsedInAndroid)] static void AddInterfaceMethods (JniMethodMap toRegister, Type type) { foreach (var iface in type.GetInterfaces ()) { @@ -86,7 +97,9 @@ static void AddJniMethod (JniMethodMap toRegister, MethodInfo declaringMethod, M toRegister [("n_" + signature.MemberName, signature.MemberSignature)] = targetMethod ?? declaringMethod; } - static void AddClassMethods (JniMethodMap toRegister, Type type) + // FIXME: https://github.com/dotnet/java-interop/issues/1192 + [UnconditionalSuppressMessage ("Trimming", "IL2070", Justification = NotUsedInAndroid)] + static void AddClassMethods (JniMethodMap toRegister, [DynamicallyAccessedMembers (Methods)] Type type) { const BindingFlags Flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; foreach (var method in type.GetMethods (Flags)) { diff --git a/src/Java.Runtime.Environment/Java.Interop/ManagedValueManager.cs b/src/Java.Runtime.Environment/Java.Interop/ManagedValueManager.cs index 4016909b2..46fd69206 100644 --- a/src/Java.Runtime.Environment/Java.Interop/ManagedValueManager.cs +++ b/src/Java.Runtime.Environment/Java.Interop/ManagedValueManager.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; @@ -231,12 +232,17 @@ void ActivateViaReflection (JniObjectReference reference, ConstructorInfo cinfo, { 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 + var self = GetUninitializedObject (declType); self.SetPeerReference (reference); cinfo.Invoke (self, argumentValues); + + // FIXME: https://github.com/dotnet/java-interop/issues/1192 + const string getUninitializedObject = "This code path is not used in Android projects."; + [UnconditionalSuppressMessage ("Trimming", "IL2067", Justification = getUninitializedObject)] + [UnconditionalSuppressMessage ("Trimming", "IL2072", Justification = getUninitializedObject)] + static IJavaPeerable GetUninitializedObject (Type type) => + (IJavaPeerable) System.Runtime.CompilerServices.RuntimeHelpers.GetUninitializedObject (type); } public override List GetSurfacedPeers () From 4c40eaf198bfffc887e8b279851c8bdbd5c7736d Mon Sep 17 00:00:00 2001 From: Jonathan Pobst Date: Tue, 18 Feb 2025 10:13:16 -1000 Subject: [PATCH 4/4] Enable `Debugger.BreakForUserUnhandledException ()`. --- src/Java.Interop/Java.Interop/JniRuntime.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Java.Interop/Java.Interop/JniRuntime.cs b/src/Java.Interop/Java.Interop/JniRuntime.cs index 0d004da18..5b9f0ed1f 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.cs @@ -446,8 +446,7 @@ public virtual void OnUserUnhandledException (ref JniTransition transition, Exce { transition.SetPendingException (e); - // TODO: Enable when we move to 'net9.0' - //Debugger.BreakForUserUnhandledException (e); + Debugger.BreakForUserUnhandledException (e); } public virtual void RaisePendingException (Exception pendingException)