Skip to content

Missing Types or Members

Jonathan Pobst edited this page Apr 2, 2021 · 4 revisions

The general philosophy with bindings is: prefer incomplete bindings that are usable over complete bindings that do not compile. That is, if the process hits a case it cannot resolve, it simply omits the type or member.

Most times users only need a few types or members from a library and we would rather them be able to use them immediately than have to fix every single type and member in the library before it compiles.

Of course, there will be times when the type or member that is omitted is one that is needed, and you need to take action in order to help the binding process resolve the issue.

First Steps

Diagnostic MSBuild Log

The first step is absolutely to enable Diagnostic MSBuild logs, and Rebuild (not Build) the project. Most times when a type/member is going to be omitted, a message is written to the diagnostic log telling stating why.

For example, if the type com.example.MyClass is missing, you may see messages like this:

Kotlin: Hiding internal class com.example.MyClass
Error while processing type 'com.example.MyClass': Type 'androidx.fragment.app.FragmentActivity' was not found.

If you see one of these messages for the missing type/member, you now know exactly why it's missing, and can go to Next Steps.

Ensure Jar/Aar Build Action is Correct

If bindings are not being generated for *any* type in your Java library, the issue might be the .jar/.aar is not correctly added to the project. The build action for a library that you want managed bindings for must be set to one of:

  • InputJar
  • EmbeddedJar
  • LibraryProjectZip

If it is set to one of the "reference" build actions like ReferenceJar or EmbeddedReferenceJar, managed bindings will not be generated for the library.

Decompiling the Java Library

Another common issue is that the .jar/.aar may not match the version you expect or match the API documentation you are viewing. For example, you may be looking for API that was added in a version 2.5.0, but your .jar is version 2.4.0.

It's often a good idea to use a Java decompiler on the .jar/.aar to ensure that the type or member you are looking for does indeed exist in the library and that it is public. (Non-public members are generally not bound.)

Next Steps

At this point, you have ensured that:

  • The desired type/member exists in the .jar/.aar an is public. (Using a Java decompiler)
  • The desired type/member does not exist in the generated C# API. (/obj/$(Configuration)/$(TargetFramework)/generated/src)

This means somewhere along the pipeline the bindings process is deciding to omit the type/member. If you found a message from the Diagnostic MSBuild log, you probably have a good idea of where the issue is occurring. The Understanding the Binding Pipeline guide is a helpful introduction to what we're going to be investigating here.

There are outputs created at various points in the binding pipeline that describe exactly what API the process expects to generate at each step. By examining these, you can determine at which point the process decided to omit the desired API.

The examinable artifacts in order are:

  • The input .jar/.aar.
  • /obj/$(Configuration)/$(TargetFramework)/api.xml-class-parse
  • /obj/$(Configuration)/$(TargetFramework)/api.xml
  • /obj/$(Configuration)/$(TargetFramework)/api.xml.fixed
  • The C# output: /obj/$(Configuration)/$(TargetFramework)/generated/src/*.cs
Clone this wiki locally