Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xamarin.Android binding invalid opcode

Recently received a new Android SDK (aar) to bind in Xamarin. When initially starting the binding I receive the error

COMPILETODALVIK : Uncaught translation error : com.android.dx.cf.code.SimException: invalid opcode ba (invokedynamic requires --min-sdk-version >= 26)
like image 754
Adam Avatar asked Feb 08 '19 09:02

Adam


1 Answers

This error is due to the SDK containing Java 8 (v1.8) byte code and it needs to be compatible with Java 7 (v1.7) to support lower API versions of Android.

In your Android project (not the binding project), add the following property.

<AndroidEnableDesugar>True</AndroidEnableDesugar>

or if you are in VS 2019+ you can turn on D8 which enables this by default.

<AndroidDexTool>d8</AndroidDexTool>

Desugaring is the process of allowing Java 8 byte code to be converted into Java 7 compatible byte code. This is a Google process that performs the conversion and is part of the Xamarin.Android build process.

Then if the SDK doesn't have any dependencies, it should all work. If you have EmbeddedReferenceJars, then things get more complicated.

In Visual Studio 2017 you will experience errors similar to

Error: java.lang.TypeNotPresentException :  Type io.reactivex.functions.Consumer not present

It will be unable to find these types in reference jars, because the desugaring processing isn't working properly. From Github Issues you eventually find the reason:

The first fix here is to add the `--classpath_entry` flag for every
`--input`, for some reason `Desugar` is not treating `--input` jars as
classpath entries

The bug is already tracked and fixed in Visual Studio 2019 Preview 2.

Now you switch to Visual Studio 2019 Preview 2 and you will come across this error.

Java.Lang.NoClassDefFoundError: Failed resolution of: Lcom/google/devtools/build/android/desugar/runtime/ThrowableExtension;

The desugaring processing is failing again because it needs this class to help communicate to the desugared code.

The class ThrowableExtension is actually found: https://github.com/bazelbuild/bazel/blob/master/src/tools/android/java/com/google/devtools/build/android/desugar/runtime/ThrowableExtension.java

You then take that Java class and you can compile it into a jar. A quick way to do it is copy that java file into a folder. Then inside that folder create a folder called output.

Call this command

javac -d ./output ThrowableExtension.java

Then move into the output directory and call this command

jar cvf desugar.jar *

It will create desugar.jar. Add that as an EmbeddedReferenceJar in your Android binding project. Your binding with Java 8 byte code with desugaring should now work.

Hopefully this might be resolved in a future Visual Studio version, so all these steps aren't necessary, but until then, at least you know what is happening and how to fix it.

like image 105
Adam Avatar answered Oct 31 '22 04:10

Adam