Java 8’s Time API significantly reduced the complexity of working with dates and times (Just look at the amount of code you need to write to accomplish a lot of common tasks using the old Date
class).
However, the Android SDK only added these classes in version 26 (Android 8.0 Oreo).
Trying to run an application that uses these classes on an older device will throw a java.lang.NoClassDefFoundError
exception which is caused by a java.lang.ClassNotFoundException
exception.
It’s worth remembering that you might not be directly using these classes yourself, you may be using a library that’s expecting them to be present (perhaps one that wasn’t designed explicitly for Android).
There have been several workarounds over the years to replace these classes, however now it’s as simple as switching on syntax desugaring.
Let’s take a look at some example code:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val now = LocalDateTime.now()
Log.d("MainActivity", now.toString())
}
This code simply creates a LocalDateTime
object using the current date and time and then prints a log message with the toString()
method.
Running the application on an ancient Moto G4 will predictably throw a java.lang.NoClassDefFoundError
exception as soon as it reaches LocalDateTime.now()
.
Enabling Syntax Desugaring
Head over to your module-level build.gradle
file (not the one that’s in the root directory- the one that’s typically in the app
directory).
Ensure your compileOptions
block looks like this:
android {
...
compileOptions {
coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
Running the application now will cause Gradle to tell you:
coreLibraryDesugaring configuration contains no dependencies. If you intend to enable core library desugaring, please add dependencies to coreLibraryDesugaring configuration.
You simply need to add the coreLibraryDesugaring
dependency to the dependencies
section of the same file.
dependencies {
...
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.1.1"
}
Now if you run the application on the same device, no NoClassDefFoundError
is thrown, and the log message is printed successfully.