Skip to content

Commit 5588e7d

Browse files
[trimming] Enable $(_DefaultValueAttributeSupport) for $(TrimMode)=partial (#9525)
Context: dotnet/runtime#109724 In .NET 9, certain apps could crash with: System.ArgumentException: RuntimeInstanceNotAllowed ?, in object DefaultValueAttribute.get_Value() ?, in new XmlAttributes(ICustomAttributeProvider) ?, in XmlAttributes XmlReflectionImporter.GetAttributes(MemberInfo) ?, in bool XmlReflectionImporter.InitializeStructMembers(StructMapping, StructModel, bool, string, RecursionLimiter) ?, in StructMapping XmlReflectionImporter.ImportStructLikeMapping(StructModel, string, bool, XmlAttributes, RecursionLimiter) .NET's concept of `$(PublishTrimmed)` is used to decide which trimmer feature switches are toggled. This is normally set for both Debug & Release, but Android only sets it for Release. This means that the `$(_DefaultValueAttributeSupport)` feature switch is not set properly in some cases, which causes the crash. For now, we can set `$(_DefaultValueAttributeSupport)` for `TrimMode=partial`, the default in .NET MAUI apps. See #9526 for how we might better address this in the future. In order to test this change: * Add a `XmlSerializerTest` to `Mono.Android-Tests` * Run a copy of `Mono.Android-Tests` with `-p:TestsFlavor=TrimModePartial` * Also set `$(_DefaultValueAttributeSupport)` for `TrimMode=full` in our test project, so `XmlSerializerTest` will pass in that mode as well. Co-authored-by: Jonathan Peppers <[email protected]>
1 parent a1fab8b commit 5588e7d

File tree

5 files changed

+38
-1
lines changed

5 files changed

+38
-1
lines changed

build-tools/automation/azure-pipelines.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,16 @@ extends:
203203
artifactSource: bin/Test$(XA.Build.Configuration)/$(DotNetTargetFramework)-android/Mono.Android.NET_Tests-Signed.aab
204204
artifactFolder: $(DotNetTargetFramework)-NoAot
205205

206+
- template: /build-tools/automation/yaml-templates/apk-instrumentation.yaml@self
207+
parameters:
208+
configuration: $(XA.Build.Configuration)
209+
testName: Mono.Android.NET_Tests-TrimModePartial
210+
project: tests/Mono.Android-Tests/Runtime-Microsoft.Android.Sdk/Mono.Android.NET-Tests.csproj
211+
testResultsFiles: TestResult-Mono.Android.NET_Tests-$(XA.Build.Configuration)TrimModePartial.xml
212+
extraBuildArgs: -p:TestsFlavor=TrimModePartial -p:TrimMode=partial
213+
artifactSource: bin/Test$(XA.Build.Configuration)/$(DotNetTargetFramework)-android/Mono.Android.NET_Tests-Signed.aab
214+
artifactFolder: $(DotNetTargetFramework)-TrimModePartial
215+
206216
- template: /build-tools/automation/yaml-templates/apk-instrumentation.yaml@self
207217
parameters:
208218
configuration: $(XA.Build.Configuration)

src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.DefaultProperties.targets

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@
114114
<UseNativeHttpHandler Condition="'$(UseNativeHttpHandler)' == ''">true</UseNativeHttpHandler>
115115
<BuiltInComInteropSupport Condition="'$(BuiltInComInteropSupport)' == ''">false</BuiltInComInteropSupport>
116116
<JsonSerializerIsReflectionEnabledByDefault Condition="'$(JsonSerializerIsReflectionEnabledByDefault)' == '' and '$(TrimMode)' == 'partial'">true</JsonSerializerIsReflectionEnabledByDefault>
117+
<!-- Set to disable throwing behavior, see: https://github.com/dotnet/runtime/issues/109724 -->
118+
<_DefaultValueAttributeSupport Condition="'$(_DefaultValueAttributeSupport)' == '' and '$(TrimMode)' == 'partial'">true</_DefaultValueAttributeSupport>
117119
<MetricsSupport Condition="'$(MetricsSupport)' == ''">false</MetricsSupport>
118120
<AndroidAvoidEmitForPerformance Condition="'$(AndroidAvoidEmitForPerformance)' == ''">$(AvoidEmitForPerformance)</AndroidAvoidEmitForPerformance>
119121
<AndroidAvoidEmitForPerformance Condition="'$(AndroidAvoidEmitForPerformance)' == ''">true</AndroidAvoidEmitForPerformance>

tests/Mono.Android-Tests/Mono.Android-Test.Shared.projitems

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
<Compile Include="$(MSBuildThisFileDirectory)System.Text\EncodingTests.cs" />
4949
<Compile Include="$(MSBuildThisFileDirectory)System.Text.Json\JsonSerializerTest.cs" />
5050
<Compile Include="$(MSBuildThisFileDirectory)System.Threading\InterlockedTest.cs" />
51+
<Compile Include="$(MSBuildThisFileDirectory)System.Xml\XmlSerializer.cs" />
5152
<Compile Include="$(MSBuildThisFileDirectory)Java.Interop\JavaObjectExtensionsTests.cs" />
5253
<Compile Include="$(MSBuildThisFileDirectory)Xamarin.Android.Net\AndroidClientHandlerTests.cs" />
5354
<Compile Include="$(MSBuildThisFileDirectory)Xamarin.Android.Net\AndroidMessageHandlerTests.cs" />

tests/Mono.Android-Tests/Runtime-Microsoft.Android.Sdk/Mono.Android.NET-Tests.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@
3838
<AndroidLinkTool Condition=" '$(AndroidLinkTool)' == '' ">r8</AndroidLinkTool>
3939
<TrimMode Condition=" '$(TrimMode)' == '' ">full</TrimMode>
4040
<!-- Trimmer switches required for tests -->
41-
<JsonSerializerIsReflectionEnabledByDefault>true</JsonSerializerIsReflectionEnabledByDefault>
41+
<JsonSerializerIsReflectionEnabledByDefault Condition="'$(TrimMode)' == 'full'">true</JsonSerializerIsReflectionEnabledByDefault>
42+
<_DefaultValueAttributeSupport Condition="'$(TrimMode)' == 'full'">true</_DefaultValueAttributeSupport>
4243
</PropertyGroup>
4344

4445
<ItemGroup>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System.Xml.Serialization;
2+
using System.ComponentModel;
3+
4+
using NUnit.Framework;
5+
6+
namespace System.XmlTests {
7+
public class C {
8+
[DefaultValue(typeof(C), "c")]
9+
public Type? T { get; }
10+
}
11+
12+
[TestFixture]
13+
public class XmlSerializerTest {
14+
15+
[Test]
16+
public void TrimmingDefaultValueAttribute ()
17+
{
18+
// Context: https://github.com/dotnet/runtime/issues/109724
19+
var s = new XmlSerializer(typeof(C));
20+
_ = new C().T; // Prevent C.T from being removed by trimming
21+
}
22+
}
23+
}

0 commit comments

Comments
 (0)