Skip to content

Commit 9ee49e1

Browse files
[Tests] Add NativeAOT regression test for R8-kept runtime ACWs
Adds NativeAotKeepsRuntimeAcwJavaTypesUnderR8, which builds a Release NativeAOT app with r8 and asserts that classes.dex still contains the runtime UncaughtExceptionMarshaler ACW kept by the generated NativeAOT ProGuard rules. If those keep rules are missing, R8 tree-shakes the runtime JCWs and the app crashes at startup inside JavaInteropRuntime.init. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent e43bd8b commit 9ee49e1

1 file changed

Lines changed: 30 additions & 0 deletions

File tree

  • src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1548,6 +1548,36 @@ public void BuildProguardEnabledProject ([Values ("", "android-arm64")] string r
15481548
}
15491549
}
15501550

1551+
[Test]
1552+
public void NativeAotKeepsRuntimeAcwJavaTypesUnderR8 ()
1553+
{
1554+
const bool isRelease = true;
1555+
if (IgnoreUnsupportedConfiguration (AndroidRuntime.NativeAOT, release: isRelease)) {
1556+
return;
1557+
}
1558+
var proj = new XamarinAndroidApplicationProject {
1559+
IsRelease = isRelease,
1560+
LinkTool = "r8",
1561+
};
1562+
proj.SetRuntime (AndroidRuntime.NativeAOT);
1563+
using (var b = CreateApkBuilder ()) {
1564+
Assert.IsTrue (b.Build (proj), "Build should have succeeded.");
1565+
1566+
var intermediate = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath);
1567+
var dexFile = Path.Combine (intermediate, "android", "bin", "classes.dex");
1568+
FileAssert.Exists (dexFile);
1569+
1570+
// Regression test: the trimmable NativeAOT path generates its ACW keep rules from the
1571+
// ILC DGML into proguard_project_references.cfg. If that file is not passed to R8, R8
1572+
// tree-shakes the runtime ACW/JCW classes out of classes.dex and the app crashes at
1573+
// startup inside JavaInteropRuntime.init with a ClassNotFoundException for the
1574+
// UncaughtExceptionMarshaler Java Callable Wrapper. The JCW class name is CRC-hashed
1575+
// (e.g. `scrc64...UncaughtExceptionMarshaler`), so match on the type name suffix.
1576+
Assert.IsTrue (DexUtils.ContainsClass ("UncaughtExceptionMarshaler;", dexFile, AndroidSdkPath),
1577+
$"`{dexFile}` should include the UncaughtExceptionMarshaler ACW kept by the generated NativeAOT ProGuard rules.");
1578+
}
1579+
}
1580+
15511581
XamarinAndroidApplicationProject CreateMultiDexRequiredApplication (string debugConfigurationName = "Debug", string releaseConfigurationName = "Release")
15521582
{
15531583
var proj = new XamarinAndroidApplicationProject (debugConfigurationName, releaseConfigurationName);

0 commit comments

Comments
 (0)