dotnet / maui

.NET MAUI is the .NET Multi-platform App UI, a framework for building native device applications spanning mobile, tablet, and desktop.
https://dot.net/maui
MIT License
21.64k stars 1.62k forks source link

Switching from .net7.0-android to .net8.0-android causes 'missing java symbols errors' in runtime inside a .net8.0-android MAUI app #21102

Open ksidirop-laerdal opened 2 months ago

ksidirop-laerdal commented 2 months ago

Description

In runtime I get 'missing java symbols' errors in regard to 'nordicsemi-android-mcumgr-ble-1.9.2.jar' when attempting to make csharp-to-java calls (using standard android-binding techniques) from within a .net8.0-android MAUI app. The call is really simple:

new DeviceResetter().Reset(); // this calls the underlying .aar lib

Note that this exception only occurs when I target net8.0-android to generate the nuget (while the same nuget works just fine when it gets compiled against net7.0-android instead of net8.0-android)

The error is raised from a csharp-to-java call (shown above) over to the .aar library employed in the .csproj below.

Steps to Reproduce

Here's the csproj of the project generating the nuget in question:

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <IsOSX Condition="      '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))'     == 'true' ">true</IsOSX>
        <IsLinux Condition="    '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))'   == 'true' ">true</IsLinux>
        <IsWindows Condition="  '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true' ">true</IsWindows>
        <IsUnix Condition="     '$(IsOSX)' == 'true' OR '$(IsLinux)' == 'true' ">true</IsUnix>

        <TargetFramework>net8.0-android</TargetFramework>

        <DebugType>pdbonly</DebugType>
        <DefineConstants>$(DefineConstants);TRACE</DefineConstants>
        <IsBindingProject>true</IsBindingProject>

        <NoWarn>$(NoWarn);CS0108;CS0114;BG8700;BG8605;BG8606;NETSDK1202;</NoWarn>
    </PropertyGroup>

    <PropertyGroup>
        <AndroidLinkMode>Full</AndroidLinkMode>
        <AndroidSupportedAbis>armeabi-v7a;arm64-v8a</AndroidSupportedAbis>
    </PropertyGroup>

    <PropertyGroup>
        <AndroidLibsFolder>Libraries</AndroidLibsFolder>
        <AndroidLibsDependenciesFolder>$(AndroidLibsFolder)/Dependencies</AndroidLibsDependenciesFolder>

        <CoreAarLibrary>$(AndroidLibsFolder)/mcumgr-wrapper.aar</CoreAarLibrary>
    </PropertyGroup>

    <ItemGroup>
        <Folder Include="Libraries\"/>
        <Folder Include="Libraries\Dependencies\" />
        <Folder Include="Transforms\"/>
    </ItemGroup>

    <Target Name="PrintBuildInfo" BeforeTargets="PrepareForBuild">
        <Message Importance="High" Text="OS:               '$(OS)'               "/>
        <Message Importance="High" Text="Platform:         '$(Platform)'         "/>
        <Message Importance="High" Text="PackageId:        '$(PackageId)'        "/>
        <Message Importance="High" Text="Configuration:    '$(Configuration)'    "/>
        <Message Importance="High" Text="PackageVersion:   '$(PackageVersion)'   "/>
        <Message Importance="High" Text="TargetFramework:  '$(TargetFramework)'  "/>
        <Message Importance="High" Text="DefineConstants:  '$(DefineConstants)'  "/>
        <Message Importance="high" Text="DesignTimeBuild:  '$(DesignTimeBuild)'  "/>
        <Message Importance="high" Text="BuildingProject:  '$(BuildingProject)'  "/>
        <Message Importance="high" Text="MSBuildNodeCount: '$(MSBuildNodeCount)' "/>

        <Message Importance="high" Text="ShouldBuildNativeLibraries: '$(ShouldBuildNativeLibraries)' "/>
    </Target>

    <Import Project="Foobar.Bindings.Android.NetX.targets"/>

    <ItemGroup>
        <!-- these dependencies have been field-tested and are known to work at least as far back as Android 10.0 -->
        <PackageReference Include="Xamarin.AndroidX.Core" Version="1.12.0.4" PrivateAssets="All" />

        <!-- the mcumgr-file-uploading aspect KotlinX.Coroutines jars with version 1.7+ -->
        <!-- to work as intended otherwise we get missing symbols errors in runtime     -->
        <PackageReference Include="Xamarin.KotlinX.Coroutines.Android" Version="1.8.0.1" />
    </ItemGroup>

</Project>

The file 'Foobar.Bindings.Android.NetX.targets' looks like so:

<?xml version="1.0" encoding="utf-8"?>

<Project>

    <PropertyGroup>
        <LangVersion>10.0</LangVersion>

        <!-- net8 supports android13 and it corresponds to android-api level 34.0 -->
        <TargetPlatformVersion Condition="      '$(TargetFramework.ToLower().StartsWith(net8.0))' == 'true' ">34.0</TargetPlatformVersion>
        <SupportedOSPlatformVersion Condition=" '$(TargetFramework.ToLower().StartsWith(net8.0))' == 'true' ">34</SupportedOSPlatformVersion>
    </PropertyGroup>

    <ItemGroup>
        <!-- the default mechanism automagically scans aars and jars and ... messes things up when multiple aar and jars are involved resulting in cryptic crashes  -->
        <!-- during the build process   so we reset everything back to a blank slate and then proceed to manually set up everything from scratch like we always do  -->
        <ReferenceJar Remove="**"/>
        <TransformFile Remove="**"/>
        <AndroidLibrary Remove="**"/>
        <AndroidAarLibrary Remove="**"/>

        <TransformFile Include="Transforms/*.xml"/>

        <AndroidLibrary Include="$(CoreAarLibrary)" Bind="true" Condition=" 'Exists($(CoreAarLibrary))' == 'true' " />

        <AndroidLibrary Include="$(AndroidLibsFolder)/Dependencies/slf4j-api.jar" Bind="false" />
        <AndroidLibrary Include="$(AndroidLibsFolder)/Dependencies/jackson-core.jar" Bind="false" />
        <AndroidLibrary Include="$(AndroidLibsFolder)/Dependencies/jackson-databind.jar" Bind="false" />
        <AndroidLibrary Include="$(AndroidLibsFolder)/Dependencies/jackson-annotations.jar" Bind="false" />
        <AndroidLibrary Include="$(AndroidLibsFolder)/Dependencies/jackson-dataformat-cbor.jar" Bind="false" />
        <AndroidLibrary Include="$(AndroidLibsFolder)/Dependencies/nordicsemi-android-ble-2.7.3.jar" Bind="false" />
        <AndroidLibrary Include="$(AndroidLibsFolder)/Dependencies/nordicsemi-android-mcumgr-ble-1.9.2.jar" Bind="false" />
        <AndroidLibrary Include="$(AndroidLibsFolder)/Dependencies/nordicsemi-android-mcumgr-core-1.9.2.jar" Bind="false" />
    </ItemGroup>

    <Target Name="PrintBindingConfiguration" AfterTargets="CoreCompile">
        <Message Importance="High" Text="**** Transform files to use for NetX-Android (@(TransformFile->Count()) in total):      " />
        <Message Importance="high" Text="****                                                                                    " />
        <Message Importance="high" Text="****   '%(TransformFile.Identity)'                                                      " />
        <Message Importance="high" Text="****                                                                                    " />

        <Message Importance="High" Text="**** Android libraries to embed for NetX-Android (@(AndroidLibrary->Count()) in total): " />
        <Message Importance="high" Text="****                                                                                    " />
        <Message Importance="high" Text="****   '%(AndroidLibrary.Identity)'                                                     " />
        <Message Importance="high" Text="****                                                                                    " />

        <Error Text="No transform files found on disk! This looks fishy ... erroring out ..."
               Condition=" @(TransformFile->Count()) == 0 "/>

        <ItemGroup>
            <MissingTransformFiles Include="@(TransformFile)" Condition="    ! Exists(%(FullPath)) " />
            <MissingAndroidLibraries Include="@(AndroidLibrary)" Condition=" ! Exists(%(FullPath)) " />
        </ItemGroup>

        <Error Text="@(MissingTransformFiles->Count()) file(s) specified by the property 'TransformFile' were not found on disk: $(MissingTransformFiles)"
               Condition=" @(MissingTransformFiles->Count()) != 0 "/>

        <Error Text="@(MissingAndroidLibraries->Count()) file(s) specified by the property 'AndroidLibrary' were not found on disk: $(MissingAndroidLibraries)"
               Condition=" @(MissingAndroidLibraries->Count()) != 0 "/>
    </Target>
</Project>

Link to public reproduction project repository

No response

Version with bug

8.0.3 GA

Is this a regression from previous behavior?

Yes, this used to work in .NET MAUI

Last version that worked well

8.0.3 GA

Affected platforms

Android

Affected platform versions

Android 10+

Did you find any workaround?

I just reverted to using .net7.0-android for the nuget-project. Works fine when the nuget is used from a .net8.0-android maui-app.

Relevant log output

No response

PureWeen commented 1 month ago

@jonathanpeppers thoughts?

jfversluis commented 1 week ago

@ksidirop-laerdal are you still experiencing this issue?

@jonathanpeppers second ping for maybe thoughts 😄

jonathanpeppers commented 1 week ago

The issue doesn't share the full stack trace or sample project (random project files aren't quite enough). Without those, I'm not sure what we can do here.

Sharing adb logcat output would be a place to start:

ksidirop-laerdal commented 1 week ago

You can find the two binlogs for net8 and net7 attached. I've also attached the two generated nuget packages: 1068 is net8 and 1069 is net7.

Nugets.zip binlogs.zip

jonathanpeppers commented 1 week ago

What is the error you are getting? You said:

In runtime I get 'missing java symbols' errors

What is the error? adb logcat output would have this information + stack traces.

ksidirop-laerdal commented 6 days ago

What is the error you are getting? You said:

In runtime I get 'missing java symbols' errors

What is the error? adb logcat output would have this information + stack traces.

Here's the output of logcat per your request - the error seems reasonable considering that the nugets themselves differ considerably between net7 and net8 in the sense that under net8 one of the .aar libs has significantly less size and cannot even be unpacked to examine what it actually has (as if it's corrupt or something)

2024-05-07 19:01:37.687 18640-18640 DOTNET                  com.laerdal.mcumgr.testbed.maui      I  2024/05/07 19:01:37.681 [ERROR] Didn't find class "io.runtime.mcumgr.ble.McuMgrBleTransport" on path: DexPathList[[zip file "/data/app/com.laerdal.mcumgr.testbed.maui-tdb5SbP5FOnPtwolOSKccQ==/base.apk"],nativeLibraryDirectories=[/data/app/com.laerdal.mcumgr.testbed.maui-tdb5SbP5FOnPtwolOSKccQ==/lib/arm64, /data/app/com.laerdal.mcumgr.testbed.maui-tdb5SbP5FOnPtwolOSKccQ==/base.apk!/lib/arm64-v8a, /system/lib64, /system/product/lib64]]
2024-05-07 19:01:37.688 18640-18640 DOTNET                  com.laerdal.mcumgr.testbed.maui      I  Java.Lang.ClassNotFoundException: Didn't find class "io.runtime.mcumgr.ble.McuMgrBleTransport" on path: DexPathList[[zip file "/data/app/com.laerdal.mcumgr.testbed.maui-tdb5SbP5FOnPtwolOSKccQ==/base.apk"],nativeLibraryDirectories=[/data/app/com.laerdal.mcumgr.testbed.maui-tdb5SbP5FOnPtwolOSKccQ==/lib/arm64, /data/app/com.laerdal.mcumgr.testbed.maui-tdb5SbP5FOnPtwolOSKccQ==/base.apk!/lib/arm64-v8a, /system/lib64, /system/product/lib64]]

                                                                                                      --- End of managed Java.Lang.ClassNotFoundException stack trace ---
2024-05-07 19:01:37.689 18640-18640 DOTNET                  com.laerdal.mcumgr.testbed.maui      I  java.lang.ClassNotFoundException: Didn't find class "io.runtime.mcumgr.ble.McuMgrBleTransport" on path: DexPathList[[zip file "/data/app/com.laerdal.mcumgr.testbed.maui-tdb5SbP5FOnPtwolOSKccQ==/base.apk"],nativeLibraryDirectories=[/data/app/com.laerdal.mcumgr.testbed.maui-tdb5SbP5FOnPtwolOSKccQ==/lib/arm64, /data/app/com.laerdal.mcumgr.testbed.maui-tdb5SbP5FOnPtwolOSKccQ==/base.apk!/lib/arm64-v8a, /system/lib64, /system/product/lib64]]
                                                                                                        at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:196)
                                                                                                        at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
2024-05-07 19:01:37.689 18640-18640 DOTNET                  com.laerdal.mcumgr.testbed.maui      I      at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
                                                                                                        at no.laerdal.mcumgr_laerdal_wrapper.AndroidDeviceResetter.<init>(AndroidDeviceResetter.java:27)
2024-05-07 19:01:37.689 18640-18640 DOTNET                  com.laerdal.mcumgr.testbed.maui      I      at crc64bfd4581495b560bb.DeviceResetter_AndroidNativeDeviceResetterAdapterProxy.<init>(DeviceResetter_AndroidNativeDeviceResetterAdapterProxy.java:23)
                                                                                                        at crc64fcf28c0e24b4cc31.ButtonHandler_ButtonClickListener.n_onClick(Native Method)
                                                                                                        at crc64fcf28c0e24b4cc31.ButtonHandler_ButtonClickListener.onClick(ButtonHandler_ButtonClickListener.java:31)
2024-05-07 19:01:37.689 18640-18640 DOTNET                  com.laerdal.mcumgr.testbed.maui      I      at android.view.View.performClick(View.java:7140)
                                                                                                        at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1211)
                                                                                                        at android.view.View.performClickInternal(View.java:7117)
                                                                                                        at android.view.View.access$3500(View.java:801)
2024-05-07 19:01:37.690 18640-18640 DOTNET                  com.laerdal.mcumgr.testbed.maui      I      at android.view.View$PerformClick.run(View.java:27355)
                                                                                                        at android.os.Handler.handleCallback(Handler.java:883)
                                                                                                        at android.os.Handler.dispatchMessage(Handler.java:100)
                                                                                                        at android.os.Looper.loop(Looper.java:214)
                                                                                                        at android.app.ActivityThread.main(ActivityThread.java:7403)
2024-05-07 19:01:37.690 18640-18640 DOTNET                  com.laerdal.mcumgr.testbed.maui      I      at java.lang.reflect.Method.invoke(Native Method)
                                                                                                        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
                                                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935)
2024-05-07 19:01:37.690 18640-18640 DOTNET                  com.laerdal.mcumgr.testbed.maui      I    --- End of managed Java.Lang.ClassNotFoundException stack trace ---
2024-05-07 19:01:37.691 18640-18640 DOTNET                  com.laerdal.mcumgr.testbed.maui      I  java.lang.ClassNotFoundException: Didn't find class "io.runtime.mcumgr.ble.McuMgrBleTransport" on path: DexPathList[[zip file "/data/app/com.laerdal.mcumgr.testbed.maui-tdb5SbP5FOnPtwolOSKccQ==/base.apk"],nativeLibraryDirectories=[/data/app/com.laerdal.mcumgr.testbed.maui-tdb5SbP5FOnPtwolOSKccQ==/lib/arm64, /data/app/com.laerdal.mcumgr.testbed.maui-tdb5SbP5FOnPtwolOSKccQ==/base.apk!/lib/arm64-v8a, /system/lib64, /system/product/lib64]]
2024-05-07 19:01:37.691 18640-18640 DOTNET                  com.laerdal.mcumgr.testbed.maui      I      at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:196)
                                                                                                        at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
                                                                                                        at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
                                                                                                        at no.laerdal.mcumgr_laerdal_wrapper.AndroidDeviceResetter.<init>(AndroidDeviceResetter.java:27)
2024-05-07 19:01:37.691 18640-18640 DOTNET                  com.laerdal.mcumgr.testbed.maui      I      at crc64bfd4581495b560bb.DeviceResetter_AndroidNativeDeviceResetterAdapterProxy.<init>(DeviceResetter_AndroidNativeDeviceResetterAdapterProxy.java:23)
                                                                                                        at crc64fcf28c0e24b4cc31.ButtonHandler_ButtonClickListener.n_onClick(Native Method)
2024-05-07 19:01:37.692 18640-18640 DOTNET                  com.laerdal.mcumgr.testbed.maui      I      at crc64fcf28c0e24b4cc31.ButtonHandler_ButtonClickListener.onClick(ButtonHandler_ButtonClickListener.java:31)
                                                                                                        at android.view.View.performClick(View.java:7140)
                                                                                                        at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1211)
2024-05-07 19:01:37.692 18640-18640 DOTNET                  com.laerdal.mcumgr.testbed.maui      I      at android.view.View.performClickInternal(View.java:7117)
                                                                                                        at android.view.View.access$3500(View.java:801)
                                                                                                        at android.view.View$PerformClick.run(View.java:27355)
                                                                                                        at android.os.Handler.handleCallback(Handler.java:883)
                                                                                                        at android.os.Handler.dispatchMessage(Handler.java:100)
2024-05-07 19:01:37.692 18640-18640 DOTNET                  com.laerdal.mcumgr.testbed.maui      I      at android.os.Looper.loop(Looper.java:214)
                                                                                                        at android.app.ActivityThread.main(ActivityThread.java:7403)
                                                                                                        at java.lang.reflect.Method.invoke(Native Method)
                                                                                                        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
2024-05-07 19:01:37.692 18640-18640 DOTNET                  com.laerdal.mcumgr.testbed.maui      I      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935)
jonathanpeppers commented 6 days ago

This error usually means your Java dependencies are incomplete.

Do you know what .aar contains io.runtime.mcumgr.ble.McuMgrBleTransport? If you can find the missing .aar, you could add it to your project with Bind="false". (It's likely a Java-only dependency you wouldn't need to call from C#)