dotnet / android

.NET for Android provides open-source bindings of the Android SDK for use with .NET managed languages such as C#
MIT License
1.93k stars 532 forks source link

AndroidPackagingOptionsInclude is ignored #9520

Closed alexander-efremov closed 2 days ago

alexander-efremov commented 4 days ago

Android framework version

net9.0-android

Affected platform version

VS 2022 17.12

Description

We have .NET Android application which we migrated from .NET 6.0 to .NET 9.0. The app use Kotlin bindings that require Kotlin.StdLib and Kotlin.Reflect packages. The application doesn't work neither DEBUG or RELEASE mode. The exception in ADB log is :

java.lang.AssertionError: Built-in class kotlin.Any is not found at 
kotlin.reflect.jvm.internal.impl.builtins.KotlinBuiltIns$3.invoke(KotlinBuiltIns.java:93)

We found that starting from .NET 7.0 the SDK excludes kotlin-related code from resulting APK file. Related issues/PRs are: AndroidPackagingOptionsExclude cannot be modified Fix AndroidPackagingOptionsExclude so it can be overridden in the csproj

We applied the way from this comment 1778925855 and built the app using .NET 8.0 SDK. The resulting APK contained the kotlin-related code and our app works fine.

But in .NET 9.0 the AndroidPackagingOptionsExclude and the new AndroidPackagingOptionsInclude items were moved to AutoImport.props (docs). So the new way for us to modify was to use the Directory.Build.props file:

<Project>
    <ItemGroup>
        <AndroidPackagingOptionsExclude Remove="@(AndroidPackagingOptionsExclude)" />
        <AndroidPackagingOptionsInclude Include="$([MSBuild]::Escape('*.kotlin*'))" />
        <AndroidPackagingOptionsInclude Include="$([MSBuild]::Escape('*.test*'))" /> <!-- added here as flag that our props have been applied -->
    </ItemGroup>
</Project>

But resulting APK still lacked the kotlin code. In msbuild logs we found that SDK still removes kotlin code:

                   AndroidPackagingOptionsExclude
                       *.kotlin*
                       *.kotlin_*
                       DebugProbesKt.bin
                       DebugProbesKt.bin
                   AndroidPackagingOptionsInclude
                       *.kotlin*
                       *.kotlin_builtins
                       *.test*
Ignoring jar entry 'META-INF/annotations.kotlin_module' from '05D34BA5CA8637CF.jar'. Filename matched the exclude pattern '.*\.kotlin.*'. (TaskId:358)
                     Ignoring jar entry 'META-INF/kotlin-stdlib.kotlin_module' from 'F91D79B39A269A7E.jar'. Filename matched the exclude pattern '.*\.kotlin.*'. (TaskId:358)
                     Ignoring jar entry 'kotlin/annotation/annotation.kotlin_builtins' from 'F91D79B39A269A7E.jar'. Filename matched the exclude pattern '.*\.kotlin.*'. (TaskId:358)
                     Ignoring jar entry 'kotlin/collections/collections.kotlin_builtins' from 'F91D79B39A269A7E.jar'. Filename matched the exclude pattern '.*\.kotlin.*'. (TaskId:358)
                     Ignoring jar entry 'kotlin/coroutines/coroutines.kotlin_builtins' from 'F91D79B39A269A7E.jar'. Filename matched the exclude pattern '.*\.kotlin.*'. (TaskId:358)
                     Ignoring jar entry 'kotlin/internal/internal.kotlin_builtins' from 'F91D79B39A269A7E.jar'. Filename matched the exclude pattern '.*\.kotlin.*'. (TaskId:358)
                     Ignoring jar entry 'kotlin/kotlin.kotlin_builtins' from 'F91D79B39A269A7E.jar'. Filename matched the exclude pattern '.*\.kotlin.*'. (TaskId:358)
                     Ignoring jar entry 'kotlin/ranges/ranges.kotlin_builtins' from 'F91D79B39A269A7E.jar'. Filename matched the exclude pattern '.*\.kotlin.*'. (TaskId:358)
                     Ignoring jar entry 'kotlin/reflect/reflect.kotlin_builtins' from 'F91D79B39A269A7E.jar'. Filename matched the exclude pattern '.*\.kotlin.*'. (TaskId:358)
                     Ignoring jar entry 'META-INF/kotlin-stdlib-jdk7.kotlin_module' from 'F91D79B39A269A7E.jar'. Filename matched the exclude pattern '.*\.kotlin.*'. (TaskId:358)
                     Ignoring jar entry 'META-INF/kotlin-stdlib-jdk8.kotlin_module' from 'F91D79B39A269A7E.jar'. Filename matched the exclude pattern '.*\.kotlin.*'. (TaskId:358)

Steps to Reproduce

  1. File -> New Project -> MAUI (Android) .NET 9.0
  2. Add
    <ItemGroup>
      <PackageReference Include="Xamarin.Kotlin.StdLib" Version="2.0.21.1" />
    </ItemGroup>
  3. Publish the app in debug mode. The resulting APK doesn't have kotlin related code.

The link on .NET 8.0 project (works fine): link The link on .NET 9.0 project (doesn't work): link

Did you find any workaround?

Only the way is bypass the issue is to commented out the code in AutoImports.props:

Relevant log output

AndroidPackagingOptionsExclude
                       *.kotlin*
                       *.kotlin_*
                       DebugProbesKt.bin
                       DebugProbesKt.bin
                   AndroidPackagingOptionsInclude
                       *.kotlin*
                       *.kotlin_builtins
                       *.test*

Ignoring jar entry 'META-INF/annotations.kotlin_module' from '05D34BA5CA8637CF.jar'. Filename matched the exclude pattern '.*\.kotlin.*'. (TaskId:358)
                     Ignoring jar entry 'META-INF/kotlin-stdlib.kotlin_module' from 'F91D79B39A269A7E.jar'. Filename matched the exclude pattern '.*\.kotlin.*'. (TaskId:358)
                     Ignoring jar entry 'kotlin/annotation/annotation.kotlin_builtins' from 'F91D79B39A269A7E.jar'. Filename matched the exclude pattern '.*\.kotlin.*'. (TaskId:358)
                     Ignoring jar entry 'kotlin/collections/collections.kotlin_builtins' from 'F91D79B39A269A7E.jar'. Filename matched the exclude pattern '.*\.kotlin.*'. (TaskId:358)
                     Ignoring jar entry 'kotlin/coroutines/coroutines.kotlin_builtins' from 'F91D79B39A269A7E.jar'. Filename matched the exclude pattern '.*\.kotlin.*'. (TaskId:358)
                     Ignoring jar entry 'kotlin/internal/internal.kotlin_builtins' from 'F91D79B39A269A7E.jar'. Filename matched the exclude pattern '.*\.kotlin.*'. (TaskId:358)
                     Ignoring jar entry 'kotlin/kotlin.kotlin_builtins' from 'F91D79B39A269A7E.jar'. Filename matched the exclude pattern '.*\.kotlin.*'. (TaskId:358)
                     Ignoring jar entry 'kotlin/ranges/ranges.kotlin_builtins' from 'F91D79B39A269A7E.jar'. Filename matched the exclude pattern '.*\.kotlin.*'. (TaskId:358)
                     Ignoring jar entry 'kotlin/reflect/reflect.kotlin_builtins' from 'F91D79B39A269A7E.jar'. Filename matched the exclude pattern '.*\.kotlin.*'. (TaskId:358)
                     Ignoring jar entry 'META-INF/kotlin-stdlib-jdk7.kotlin_module' from 'F91D79B39A269A7E.jar'. Filename matched the exclude pattern '.*\.kotlin.*'. (TaskId:358)
                     Ignoring jar entry 'META-INF/kotlin-stdlib-jdk8.kotlin_module' from 'F91D79B39A269A7E.jar'. Filename matched the exclude pattern '.*\.kotlin.*'. (TaskId:358)
dellis1972 commented 3 days ago

This is probably related https://github.com/dotnet/android/pull/8459.

dellis1972 commented 3 days ago

I suspect Directory.Build.props might well be too early in the build process. It is one of the first files evaluated, as a result the AndroidPackagingOptionsExclude is not being cleared by the <AndroidPackagingOptionsExclude Remove="@(AndroidPackagingOptionsExclude)" /> code.

dellis1972 commented 3 days ago

Looks like there is a bug, the ItemGroup is not passed when we are building a Debug Apk/aab. I'll get that fixed. However placing the code in a Directly.Build.props is not going to work. You need to make the adjustments after AutoImports has been run. Which means doing changes in the csproj. If you want to still have this code in one file you can always use the Import element to pull in the props file into your csproj. You can't use Directory.Build.props here either as MSbuild will not re-import a file if it already did.

 <Import Project="Foo.props" />
alexander-efremov commented 3 days ago

hey @dellis1972 I have tried to import the props in the way you suggested, but no luck. The updated csproj:

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <TargetFramework>net8.0-android</TargetFramework>
        <SupportedOSPlatformVersion>21</SupportedOSPlatformVersion>
        <OutputType>Exe</OutputType>
        <Nullable>enable</Nullable>
        <ImplicitUsings>enable</ImplicitUsings>
        <ApplicationId>com.companyname.KotlinReflectTest90</ApplicationId>
        <ApplicationVersion>1</ApplicationVersion>
        <ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
        <Platform>Android</Platform>
        <TrimMode>full</TrimMode>
    </PropertyGroup>
    <ItemGroup>
        <PackageReference Include="Xamarin.Kotlin.StdLib" Version="2.0.21.1"/>
    </ItemGroup>
    <Import Project="Foo.props"/>
</Project>

The logs still reports the old AndroidPackagingOptionsExclude values:

                   AndroidPackagingOptionsExclude
                       *.kotlin_*
                       DebugProbesKt.bin
                       DebugProbesKt.bin
                   AndroidPackagingOptionsInclude
                       *.kotlin_builtins

The log output:

Ignoring jar entry 'META-INF/annotations.kotlin_module' from '05D34BA5CA8637CF.jar'. Filename matched the exclude pattern '.*\.kotlin_.*'. (TaskId:357)
                     Ignoring jar entry 'META-INF/kotlin-stdlib.kotlin_module' from 'F91D79B39A269A7E.jar'. Filename matched the exclude pattern '.*\.kotlin_.*'. (TaskId:357)
                     Ignoring jar entry 'kotlin/annotation/annotation.kotlin_builtins' from 'F91D79B39A269A7E.jar'. Filename matched the exclude pattern '.*\.kotlin_.*'. (TaskId:357)
                     Ignoring jar entry 'kotlin/collections/collections.kotlin_builtins' from 'F91D79B39A269A7E.jar'. Filename matched the exclude pattern '.*\.kotlin_.*'. (TaskId:357)
                     Ignoring jar entry 'kotlin/coroutines/coroutines.kotlin_builtins' from 'F91D79B39A269A7E.jar'. Filename matched the exclude pattern '.*\.kotlin_.*'. (TaskId:357)
                     Ignoring jar entry 'kotlin/internal/internal.kotlin_builtins' from 'F91D79B39A269A7E.jar'. Filename matched the exclude pattern '.*\.kotlin_.*'. (TaskId:357)
                     Ignoring jar entry 'kotlin/kotlin.kotlin_builtins' from 'F91D79B39A269A7E.jar'. Filename matched the exclude pattern '.*\.kotlin_.*'. (TaskId:357)
                     Ignoring jar entry 'kotlin/ranges/ranges.kotlin_builtins' from 'F91D79B39A269A7E.jar'. Filename matched the exclude pattern '.*\.kotlin_.*'. (TaskId:357)
                     Ignoring jar entry 'kotlin/reflect/reflect.kotlin_builtins' from 'F91D79B39A269A7E.jar'. Filename matched the exclude pattern '.*\.kotlin_.*'. (TaskId:357)
                     Ignoring jar entry 'META-INF/kotlin-stdlib-jdk7.kotlin_module' from 'F91D79B39A269A7E.jar'. Filename matched the exclude pattern '.*\.kotlin_.*'. (TaskId:357)
                     Ignoring jar entry 'META-INF/kotlin-stdlib-jdk8.kotlin_module' from 'F91D79B39A269A7E.jar'. Filename matched the exclude pattern '.*\.kotlin_.*'. (TaskId:357)

Also, I would like to underline that we builds net8.0-android using .NET 9.0.100 SDK.

dellis1972 commented 3 days ago

If you are using .net 8 it will still pull in the dotnet 8 targets even if you are using .net 9 afaik.

dellis1972 commented 3 days ago

also note I did say there is a bug for Debug builds. For release it works as expected here.

alexander-efremov commented 3 days ago

If you are using .net 8 it will still pull in the dotnet 8 targets even if you are using .net 9 afaik.

Noted, thank you! I tried to build net9.0-android using .NET 9.0 SDK with <Import Project="Foo.props" /> both in Debug/Release mode and the kotlin folder is inside of resulting APK.