xamarin / AndroidX

AndroidX bindings for .NET for Android
MIT License
173 stars 42 forks source link

Can't get past `javac: error: package androidx.fragment.app does not exist` #857

Closed justin-caldicott closed 3 months ago

justin-caldicott commented 3 months ago

Android application type

Classic Xamarin.Android (MonoAndroid12.0, etc.)

Affected platform version

Rider 2023.3.3 on MacOS 14.3.1 with Apple Chip

Description

Attempting to upgrade an old Xamarin.Android app, not using Xamarin.Forms, to a recent targetVersion - trying v13.0, 33. On swapping all Xamarin.Android.Support usages for Xamarin.AndroidX, I don't seem to be able to get past some strange java compilation errors.

The C# code appears to compile fine, but getting lots of java errors like the following:

/Library/Java/JavaVirtualMachines/microsoft-11.jdk/Contents/Home/bin/javac -J-Dfile.encoding=UTF8 "@/var/folders/97/sv_6wxsj0vs50msnbg5k1nwm0000gn/T/tmp372df0de.tmp" -target 1.8 -source 1.8 
0>SomeFragment.java(5,31): Error JAVAC0000 javac:  error: package androidx.fragment.app does not exist
    extends androidx.fragment.app.Fragment
0>SomeActivity.java(8,35): Error JAVAC0000 javac:  error: package androidx.core.app.ActivityCompat does not exist
        androidx.core.app.ActivityCompat.OnRequestPermissionsResultCallback
...

Any guidance appreciated - I've exhausted pretty much every angle I can think of. At the least this feels like a documentation issue somewhere.

Steps to Reproduce

Not clarified - working with an existing project

Did you find any workaround?

No response

Relevant log output

No response

jpobst commented 3 months ago

Have you added the following NuGet packages to your project?

justin-caldicott commented 3 months ago

Thanks @jpobst, yes I added the new packages and followed the errors in Rider to make sure all implicit dependencies are included too. There are no C# errors now, just these java ones.

I admit I'm not sure how the java side of the bindings work. The java files with errors are in e.g. obj/Debug/android/<guid>/SomeFragment.java. The lines it's complaining about are:

public class SomeFragment
    extends androidx.fragment.app.Fragment <<<<<< javac cannot find androidx.fragment.app
    implements
        mono.android.IGCUserPeer

I saw in the installed packages there's an aar folder with e.g. androidx.fragment.fragment.aar inside. Presumably this is where it should be finding the package from?

One unusual thing here is we restore packages with -ExcludeVersion to a packages folder within the repo root. Assembly resolution is OK with this due to hint paths, e.g.

    <Reference Include="Xamarin.AndroidX.Fragment">
      <HintPath>..\packages\Xamarin.AndroidX.Fragment\lib\monoandroid12.0\Xamarin.AndroidX.Fragment.dll</HintPath>
    </Reference>

Maybe this causes problems for java package resolution somehow? It didn't have this behaviour on previous versions, but then we're jumping a lot of versions in one go as the app wasn't updated for a couple of years.

jpobst commented 3 months ago

I suspect using <Reference> is the issue. These .dlls do not contain the .aar embedded in them for build performance reasons.

When you reference it as a <PackageReference> the MSBuild system will run any .targets files in the NuGet package when you build your project.

If you look in the NuGet you'll see build\monoandroid12.0\Xamarin.AndroidX.Fragment.targets.

This contains this MSBuild which adds the .aar to your project:

<ItemGroup>
  <AndroidAarLibrary Include="$(MSBuildThisFileDirectory)..\..\aar\androidx.fragment.fragment.aar">
    <AndroidXSkipAndroidXMigration>true</AndroidXSkipAndroidXMigration>
  </AndroidAarLibrary>
</ItemGroup>

By using a <Reference> instead of a <PackageReference> this never gets executed and the .aar never gets added to your application.

justin-caldicott commented 3 months ago

Many thanks @jpobst, all set!

I'm not in a position to switch to <PackageReference> just yet. But what you explained let me realise I could just add the android library references to the project file directly. They probably would have been added if I'd installed the package properly, rather than just installing them to a folder. Really do need to update our build scripts!

So I have a bunch of additional lines like:

    <AndroidAarLibrary Include="$(ProjectDir)..\packages\Xamarin.AndroidX.Fragment\aar\androidx.fragment.fragment.aar"/>

There were already a couple there for Kotlin.StdLib and Kotlin.StdLib.Common.

Sorry, not really an issue in the product then, just support.. but much appreciated. Closing.