What is "Desugaring" and why would I need it?
Tags: android, kotlin, desugaring, java
Published: 2020-08-07 11:43:32

#Do you know "desugaring support"?#

Some weeks ago I was reading on Calendars and Time, this lead me to some options and it made me unsure about which way to take so I tried to put some reading on it, here follows a brief result.

A long time ago Oracle realized that the java.Util.Date library was flawful and decided to split it in better components[^1][^4], problem was that because of Android version compatibility we couldn't use it.

So, Android DevSummit 2019, google makes it possible to do library desugaring with the first canary build of Android Studio 4.0. [^2]

# But what is desugaring?
 It's basically forward/upward compatibility (which can be also referred as backport) for new types and APIs. It enables us to use this newer Java libraries in older versions of android paying a small price on app size.

# APK size impact [^3]
Historically, in order to use the java.time APIs in an app with a minimum supported API level below 26 you would need to use the ThreeTenBP library (or ThreeTenABP). This is a standalone repackaging of the java.time APIs in the org.threeten.bp package which requires you to update all your imports.
D8 is basically performing that same operation but at the bytecode level. It rewrites your code from calling java.time to j$.time as seen in the bytecode diff above. To accompany that rewrite, an implementation needs to be bundled into the application. That is the cause of the large APK size change.
In this example the release APK is minified using R8 which also minifies the backport code. If minification is disabled, the increase in dex size jumps up to 180KB, 206 classes, 3272 methods, and 713 fields.

# Conclusion
This allowed us to avoid using third party libraries to handle "Time" that, until the release of desugaring, was the recommended way to handle time in Android (for example using Joda or ThreeTen).

# Beware
Another interesting point is that this not only impacted this libraries but made some calendar projects outdated. ThreeTen and Joda already have alerts in their libraries and websites encouraging people to migrate to java.time.
> Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.
- https://www.joda.org/joda-time/
> Attention: Development on this library is winding down. Please consider switching to Android Gradle plugin 4.0, java.time.*, and its core library desugaring feature in the coming months. />
- https://github.com/JakeWharton/ThreeTenABP

# Trivia: java.utils.date drawbacks/flaws
Prior to the Java SE 8 release, the Java date and time mechanism was provided by the java.util.Date, java.util.Calendar, and java.util.TimeZone classes, as well as their subclasses, such as java.util.GregorianCalendar. These classes had several drawbacks, including: [^4]
* The Calendar class was not type safe.
* Because the classes were mutable, they could not be used in multithreaded applications.
* Bugs in application code were common due to the unusual numbering of months and the lack of type safety.

PS:: If you are reading Jake Warton's article, keep it in mind that it is from Dec 2019.
PSS: A link to the list of the backported types can also be found at the end of Warton's article .

# References:
[^1]: Java SE 8 Date and Time: https://www.oracle.com/technical-resources/articles/java/jf14-date-time.html
[^2]: Desugaring: https://developer.android.com/studio/write/java8-support#library-desugaring
[^3]: Deeper dive into desugaring: https://jakewharton.com/d8-library-desugaring/
[^4]: Legacy Date-Time code: https://docs.oracle.com/javase/tutorial/datetime/iso/legacy.html