Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nothing preserves an assembly reference, if no C# types are used directly #9008

Open
jonathanpeppers opened this issue Jun 6, 2024 · 0 comments
Assignees
Labels
Area: App+Library Build Issues when building Library projects or Application projects. bug Component does not function as intended.
Milestone

Comments

@jonathanpeppers
Copy link
Member

jonathanpeppers commented Jun 6, 2024

Android framework version

net8.0-android, net9.0-android

Affected platform version

.NET 9

Description

Context:

In the above PR, I had to add a class named Foo and use it for the CustomWidgetTests to succeed.

The situation is:

  • A class library with a custom view is used
  • The custom view is only accessed from an AndroidResource .xml file
  • The C# compiler drops the assembly reference, because no C# code references anything in the class library
  • The assembly doesn't even get passed to the trimmer/linker

Possible Solution

I suppose we could do something that would support passing all Android class libraries to the trimmer. Even ones that the C# compiler deems is unused?

We'd then rely on the trimmer to do its job to remove unused code.

Steps to Reproduce

  1. Remove Foo.cs from the changes in [trimming] preserve custom views and $(AndroidHttpClientHandlerType) #8954
  2. Run the APK tests in Release mode

Did you find any workaround?

Reference some C# class, such as Foo or even the previous code would work:

// usage of typeof(CustomTextView) includes the assembly reference
[DynamicDependency (DynamicallyAccessedMemberTypes.All, typeof (CustomTextView))]

Relevant log output

Mentioned in 9a782d7.

Xamarin.Android.RuntimeTests.CustomWidgetTests failed with:

	(Binary XML file line #1 in Mono.Android.NET_Tests:layout/uppercase_custom: Binary XML file line #1 in Mono.Android.NET_Tests:layout/uppercase_custom: Error inflating class Mono.Android_Test.Library.CustomTextView)
	   at Java.Interop.JniEnvironment.InstanceMethods.CallObjectMethod(JniObjectReference , JniMethodInfo , JniArgumentValue* )
	   at Java.Interop.JniPeerMembers.JniInstanceMethods.InvokeVirtualObjectMethod(String , IJavaPeerable , JniArgumentValue* )
	   at Android.Views.LayoutInflater.Inflate(Int32 , ViewGroup )
	   at Xamarin.Android.RuntimeTests.CustomWidgetTests.<>c.<UpperCaseCustomWidget_ShouldNotThrowInflateException>b__0_0()
	   at NUnit.Framework.Constraints.VoidInvocationDescriptor.Invoke()
	   at NUnit.Framework.Constraints.ExceptionInterceptor.Intercept(Object )
	--- End of managed Java.Lang.RuntimeException stack trace ---
	android.view.InflateException: Binary XML file line #1 in Mono.Android.NET_Tests:layout/uppercase_custom: Binary XML file line #1 in Mono.Android.NET_Tests:layout/uppercase_custom: Error inflating class Mono.Android_Test.Library.CustomTextView
	Caused by: android.view.InflateException: Binary XML file line #1 in Mono.Android.NET_Tests:layout/uppercase_custom: Error inflating class Mono.Android_Test.Library.CustomTextView
	Caused by: java.lang.ClassNotFoundException: Mono.Android_Test.Library.CustomTextView
	   at java.lang.Class.classForName(Native Method)
	   at java.lang.Class.forName(Class.java:454)
	   at android.view.LayoutInflater.createView(LayoutInflater.java:815)
	   at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:1006)
	   at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:961)
	   at android.view.LayoutInflater.rInflate(LayoutInflater.java:1123)
	   at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1084)
	   at android.view.LayoutInflater.inflate(LayoutInflater.java:682)
	   at android.view.LayoutInflater.inflate(LayoutInflater.java:534)
	   at android.view.LayoutInflater.inflate(LayoutInflater.java:481)
	   at crc643df67da7b13bb6b1.TestInstrumentation_1.n_onStart(Native Method)
	   at crc643df67da7b13bb6b1.TestInstrumentation_1.onStart(TestInstrumentation_1.java:32)
	   at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2189)
	Caused by: java.lang.ClassNotFoundException: Didn't find class "Mono.Android_Test.Library.CustomTextView" on path

In this case, Mono.Android_Test.Library.CustomTextView was used
from an Android layout, but not used anywhere in managed code.

@jonathanpeppers jonathanpeppers added Area: App+Library Build Issues when building Library projects or Application projects. needs-triage Issues that need to be assigned. labels Jun 6, 2024
@jonathanpeppers jonathanpeppers removed the needs-triage Issues that need to be assigned. label Jun 6, 2024
@jonathanpeppers jonathanpeppers added this to the .NET 9 milestone Jun 6, 2024
jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue Jun 6, 2024
@jpobst jpobst added the bug Component does not function as intended. label Jun 7, 2024
jonathanpeppers added a commit that referenced this issue Jun 17, 2024
#8954)

Fixes: #8797

Here are two cases `TrimMode=full` can break applications:

* `$(AndroidHttpClientHandlerType)` set to a custom type

* Custom views (Android `.xml`) that are not referenced in C# code

In the `MarkJavaObjects` trimmer step we can preserve both of these
cases by:

* Passing in `$(AndroidHttpClientHandlerType)`, preserve the public,
  parameterless constructor of the type

* Pass in `$(_CustomViewMapFile)`, preserve `IJavaObject` types if
  they are found in the map file

Filed an issue to address the usage of `Foo` in tests in the future:

* #9008
@jonpryor jonpryor modified the milestones: .NET 9, .NET 10 Aug 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: App+Library Build Issues when building Library projects or Application projects. bug Component does not function as intended.
Projects
None yet
Development

No branches or pull requests

4 participants