I'm developing a Kotlin JVM library that currently...
# compiler
d
I'm developing a Kotlin JVM library that currently targets Java 11 bytecode. I'm only familiar with backend development so I'm wondering if it's safe to bump that to Java 17 bytecode without impacting Android compatibility. My questions: 1. Does Android tooling translate libraries compiled to Java 17 bytecode into compatible Java 11 bytecode so apps can run on all Java 11 bytecode devices or is there a portion of the market that would be excluded by this upgrade? 2. My library uses Inline classes and inline functions extensively. If I target Java 17 bytecode, does this cause issues by inlining incompatible Java 17 bytecode into the Java 11 bytecode? I'm not sure what the order of operations is during compilation / translation. Thanks in advance and let me know if I'm asking the wrong questions 🙏
j
Android does not use Java bytecode. The version you target is mostly irrelevant.
The biggest impact of bumping to 17 is that you force your consumers to also be using 17, but again, this makes no real difference and is just a minor annoyance.
Whether your bytecode targets 8, 11, 17, or any other version the Android toolchain converts the Java bytecode to Dalvik bytecode and that version no longer exists.
In general I would recommend targeting the lowest version possible. Especially since you are writing Kotlin, there is very little advantage to changing the bytecode version to be less old.
The bigger concern on Android is Java API availability. What is the reason you want to bump to 17? Is it because you want to leverage a feature of Java 17 bytecode? Or because you want to use APIs that were added to Java between 11 and 17?
d
Thanks 🙏
My main reason is to be able to bump some dependencies of my library which themselves bumped the minimum JDK version to 17.
j
If they use APIs from newer versions you are going to severely limit the versions of Android on which your library can then be used, or potentially just completely make it unusable if the APIs used are completely absent. You should make that you're running your unit test suite on an Android emulator for the minimum-supported version.
d
Oh, I see. I was hoping that the Android tooling would automatically transform new Java 17 bytecode to compatible Dalvik instructions for older devices and replace API calls with equivalent replacements. I guess that's wishful thinking and probably a large burden to maintain for the Android team.
j
The bytecode is translated, that's mostly no problem. There's very little innovation in bytecode. Some of the simple APIs can be backported, but many require associated changes to the VM.
1
You can use tools like animal sniffer to determine if you have any problematic API calls as part of your build: https://www.mojohaus.org/animal-sniffer/. There's signatures which correspond to the Android API levels, so you could validate yourself (and your dependencies) against your minimum Android API level.
Unfortunately those signatures are not aware of the backporting capabilities of the Android toolchain. Sometimes references to new APIs are okay and sometimes they're not, but it at least gives you a starting point.
There's also two types of API backporting. There's a version which is built-in to the tool that everyone uses to convert Java bytecode to Dalvik bytecode. This does backports for simple things. A long-standing example (which is mostly irrelevant now) is
Long.hashCode
which was added in Java 8 which it would backport automatically. I wrote about it here: jakewharton.com/d8-library-desugaring/
The second type is called core library desugaring, which does larger API surfaces such as the entire java.time library.
d
Wow, thank you! I'll look into those 🙏
u
@Dan Rusu also consider that not all Android apps and libs use desugaring and may not want to incorporate it for the sake of using your or dependent libraries, as it implies additional complexity, which generally harbors the potential for problems. Personally I aim for lean Android code, as every extra bit of variety implies more problems/work down the road.
d
Oh, interesting thanks! I'll stick with the older dependencies then, until it becomes absolutely necessary to upgrade.