DEV Community

Cover image for nowinandroid builds with Gradle 8.5 and JDK 21
Iñaki Villar
Iñaki Villar

Posted on

nowinandroid builds with Gradle 8.5 and JDK 21

Gradle 8.5 fully supports compiling, testing and running on Java 21. Java updates frequently include optimizations that improve the performance of both the JVM and the Java applications running on it.
At the Devoxx Belgium presentation "With Java 21, Your Code Runs Even Faster But How is that Possible?", Per Minborg explains some of the optimizations shipped in Java 21 like Perform I/O operations in bulk for RandomAccessFile highlighting or Unroll by hand StringUTF16 and StringLatin1 polynomial hash loops, and what is better, these optimizations have an immediate impact without changing the java application because by direct usage or by transitive dependency use.

Following the previous Java 17 article, in this article we share the results of measuring an Android project with Java 21.


The project used is nowinandroid. The experiment is based on the commit f5b3ae5 of the main branch(12/22). At this point, the project was already using Gradle 8.5.
The only change applied was to update the AGP to 8.2.1 because it included the fix for the issue: JdkImageTransform fails when using JDK 21

Experiment methodology

  • Two variants
    • JDK 17
    • JDK 21
  • Scenarios:
    • assembleDebug
    • assembleRelease
    • testDemoDebug
    • lintDemoRelease
  • Each variant/scenario runs 100 clean builds in GHA runners
  • Memory configuration for all builds: -Xmx6g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -XX:+UseParallelGC -XX:MaxMetaspaceSize=1g


First, we explore the overall build time for the different scenarios:

JDK 17 - Median (secs) JDK 21 - Median (secs) Improvement
assembleDebug 448 433 3.4%
assembleRelease 659 591 10.2%
testDemoDebug 334 320 4.3%
lintDemoRelease 306 296 3.3%

In four evaluated scenarios, we are observing modest improvements in three of them, while the assembleRelease scenario shows a significant reduction of 10% in build time.

Next, we explore where the improvements came from at the task level:


Task Diff Median (seconds) Improvement
:app:mergeExtDexDemoDebug 8.5 5.4%
:app-nia-catalog:mergeExtDexDebug 2.8 3.4%
:app:mergeExtDexProdDebug 2.3 10.2%
:app:l8DexDesugarLibDemoDebug 2.4 8.1%
:app:hiltJavaCompileProdDebug 1.7 7.3%


Task Diff Median (seconds) Improvement
:app:minifyDemoReleaseWithR8 49 18.2%
:app-nia-catalog:mergeReleaseGlobalSynthetics 35 29.6%
:app-nia-catalog:mergeExtDexRelease 29 19.9%
:app-nia-catalog:l8DexDesugarLibRelease 8 24.7%
:app:minifyProdReleaseWithR8 7 9.9%


Task Diff Median (seconds) Improvement
:feature:foryou:testDemoDebugUnitTest 3.4 7.6%
:app:testDemoDebugUnitTest 2.5 6.8%
:core:designsystem:testDemoDebugUnitTest 2.4 4.9%
:core:data:testDemoDebugUnitTest 1 10.2%
:app:hiltJavaCompileDemoDebug 1 9.6%


Task Diff Median (seconds) Improvement
:core:data:lintAnalyzeDemoRelease 1.9 9.1%
:core:designsystem:compileDemoReleaseKotlin 1.5 6%
:core:designsystem:lintAnalyzeDemoRelease 1.2 6.2%
:core:analytics:lintAnalyzeDemoRelease 1.1 8%
:core:datastore:lintAnalyzeDemoRelease 0.9 12%

Again the release scenario shows a significant improvement in the expensive R8 tasks.

Finally, we aggregated the absolute diff of the median for the tasks in each scenario providing the "serial" improvement using JDK 21:

Aggregated diff (seconds)
assembleDebug 37
assembleRelease 158
testDebugUnitTest 32
lintDemoRelease 27


Experiments spreadsheet:

Final words

In this article, we explored how using JDK 21 enhances build efficiency in an Android project, particularly noting reduced build times. While some improvements were moderate, the assembleRelease tasks demonstrated notably greater enhancements.
The outcomes may differ based on the specific project, but considering the minimal adjustments needed, it's certainly worthwhile to experiment with this approach if you're utilizing Gradle 8.5.

Happy building!

Top comments (0)