Xamarin Build Error Compilation can't be completed because some library classes are missing

Viewed 1867

When I try to build my Xamarin.Droid project I get following Build error:

2>R8 : warning : Missing class: java.lang.ClassValue
2>R8 : error : Compilation can't be completed because some library classes are missing.

I got this error from one day to another... Is there a way to find out where java.lang.ClassValue is needed, or add it manual?

Edit: I did some research and got new informations: When I build the solution on another maschine (I this case Microsofts AppCenter) it builds without any problems. So I thought that my solution is fine, maybe there are problems with the android sdk or the jdk. So I created a new Xamarin.Forms project and build the android part, that worked without any problems. So the android sdk or jdk seems to be fine.

1 Answers

Not that this is a solution exactly, but it may point you in the right direction. I'm currently getting this message as a result of a bound Android-library under our own maintenance. When I remove the NuGet from our project, the message disappears and the code compiles. Obviously I can't make use of the program features using this library then either, but at least it looks like the library is causing the issue... May be it could be the same in your case?


What fixed the issue for me

After I knew which library was causing issues, I decided to dive it a bit more with a demo-app I had written specifically to test that library. From here I found out that enabling d8-dexing or r8-code-shrinking together with multi-dexing is what caused the issue. You can use either or, so:

  • Turn of code-shrinker options such as ProGuard or r8, and use d8-dexing.
  • Turn of multi-dexing, use d8-dexing and optionally a code-shrinker.

My suggestion is to use the latter, as with d8-dexing, your dexed reference-table should be much more efficient and smaller anyway, meaning you might not even need multi-dexing any more.

In addition, it seems the above resolution doesn't play to nicely with linking, so set linking options to "None".

Problems on a Mac CI

After I fixed all of the above I ran into a further issue when trying to compile our app on a Mac CI, which told me Mono.Android.dll could not be AOT-compiled. This, apparently, is an issue with the file being too big for LLVM on a Mac, though, as described here, for which the solution is to simply turn off LLVM.


A better way of fixing it

Today I was pointed to another set of potential fixes highlighted here. This page actually mentions three fixes, of which option B is the preferred one as this is in-line with "the upstream recommendation from the Google Guava library" (cited from this thread).

For me option A - reverting to dx-dexing - didn't quite work, as, though I was able to remove the warning pertaining to java.lang.ClassValue, I got a whole bunch of other warnings back. Option B, using ProGuard-rules used in combination with R8, was a better choice in that respect, since this allowed me to get rid of all the other warnings as well. In fact, though, this removed the difference between options B & C, as their outcome thereby became the same. Yet, just following the suggestions in this document, my app started crashing on launch. To resolve this, I had to check for errors in Logcat, which showed me a class that was needed was being linked away. Adding another rule to explicitly keep that class then finally resolved the remainder of the problem, giving me the below ProGuard-configuration:

-dontwarn java.lang.ClassValue
-dontwarn kotlin.jvm.internal.Lambda
-dontwarn kotlin.jvm.functions.Function1
-dontwarn kotlin.jvm.internal.markers.KMappedMarker
-dontwarn kotlin.jvm.functions.Function0
-dontwarn kotlin.coroutines.jvm.internal.SuspendLambda
-dontwarn kotlin.jvm.functions.Function2
-keep class com.google.android.material.internal.BaselineLayout

With this configuration, I'm now once again able to use both AOT and LLVM.

Related