How to use AppCDS with Spring Boot

Transcript 


In this video, I will show you how to use Application Class Data Sharing (AppCDS) with Spring Boot applications. AppCDS is a JVM feature that reads and parses a set of system classes and application classes, stores the data in an archive, and then reads the data from the archive upon startup, resulting in faster application startups. AppCDS is compatible with all applications and doesn’t require any code changes. Additionally, using AppCDS with Ahead-of-Time (AOT) processing, supported by Spring, further reduces startup time. We will explore how to use AppCDS and AOT processing on a local machine and in containers by dockerizing our application using Dockerfiles and Buildpacks.

For this tutorial, you will need a Spring Boot application. I’ll use the Spring Petclinic application, available on GitHub. You will also need Docker, so make sure the engine is up and running. Let's begin by creating an archive on a local machine. While no application code changes are required, enabling AOT processing in the Maven plugin configuration is necessary. Using Liberica JDK 23 and Spring Boot version 3.3 or later, we start by creating an executable JAR file using the maven clean package command. Running the application with a standard java -jar command initially takes almost four seconds to start.

Next, we create a CDS archive. Instead of using the executable JAR directly, the Spring team recommends unpacking it into an exploded JAR for production. After extracting it, we use options like -Dspring.aot.enabled and ArchiveClassesAtExit to create the archive. The Dsprint.context.exit=onRefresh option ensures the application exits automatically after startup. While some older classes may not be archived, most are included. Once the archive is created, running the application with the SharedArchiveFile option results in a startup time of less than two seconds, a 40% improvement.

To enable AppCDS in a container, we use a Dockerfile. The first stage employs the Liberica Runtime Container with LibericaJDK Lite and Alpaquita Linux to build the project. The second stage extracts the JAR into layers, optimizing image updates. Finally, the container is built using Liberica Runtime Container with a prepackaged AppCDS archive. Using options like -Dspring.aot.enabled and ArchiveClassesAtExit, we create the archive during the build process. The resulting container image is 287MB and starts in under three seconds.

We also demonstrate using Buildpacks to build a container image with AppCDS and AOT enabled. Buildpacks automatically create layered JARs and can be configured by adding environment variables like BP_SPRING_AOT_ENABLED and BP_JVM_CDS_ENABLED to the Maven plugin. While Buildpacks produce slightly larger images (e.g., 538MB), they simplify the process. Running the Buildpack-based container shows startup times of just over two seconds, confirming that AppCDS and AOT are working as expected.

In this video, we explored using AppCDS and AOT processing with Spring Boot applications. Don't forget to like, subscribe, and see you next time!

Summary

This tutorial demonstrates how to use Application Class Data Sharing (AppCDS) and Ahead-of-Time (AOT) processing with Spring Boot applications to reduce startup time by 40–50%. AppCDS creates an archive of parsed classes for faster loading, requiring no code changes, and works both locally and in containers. The tutorial covers building optimized Docker images using Dockerfiles or Buildpacks for efficient deployment and improved performance.

About Catherine

Java developer passionate about Spring Boot. Writer. Developer Advocate at BellSoft

Social Media

Tags

Videos
card image
Jan 20, 2026
JDBC vs ORM vs jOOQ: Choose the Right Java Database Tool

Still unsure what is the difference between JPA, Hibernate, JDBC, or jOOQ and when to use which? This video clarifies the entire Java database access stack with real, production-oriented examples. We start at the foundation, which is JDBC, a low-level API every other tool eventually relies on for database communication. Then, we go through the ORM concept, JPA as a specification of ORM, Hibernate as the implementation and extension of JPA, and Blaze Persistence as a powerful upgrade to JPA Criteria API. From there, we take a different path with jOOQ: a database-first, SQL-centric approach that provides type-safe queries and catches many SQL errors at compile time instead of runtime. You’ll see when raw JDBC makes sense for small, focused services, when Hibernate fits CRUD-heavy domains, and when jOOQ excels at complex reporting and analytics. We discuss real performance pitfalls such as N+1 queries and lazy loading, and show practical combination strategies like “JPA for CRUD, jOOQ for reports.” The goal is to equip you with clarity so that you can make informed architectural decisions based on domain complexity, query patterns, and long-term maintainability.

Videos
card image
Jan 13, 2026
Hibernate: Ditch or Double Down? When ORM Isn't Enough

Every Java team debates Hibernate at some point: productivity champion or performance liability? Both are right. This video shows you when to rely on Hibernate's ORM magic and when to drop down to SQL. We walk through production scenarios: domain models with many-to-many relations where Hibernate excels, analytical reports with window functions where JDBC dominates, and hybrid architectures that use both in the same Spring Boot codebase. You'll see real code examples: the N+1 query trap that kills performance, complex window functions and anti-joins that Hibernate can't handle, equals/hashCode pitfalls with lazy loading, and practical two-level caching strategies. We also explore how Hibernate works under the hood—translating HQL to database-specific SQL dialects, managing sessions and transactions through JDBC, implementing JPA specifications. The strategic insight: modern applications need both ORM convenience for transactional business logic and SQL precision for data-intensive analytics. Use Hibernate for CRUD and relationship management. Use SQL where ORM abstractions leak or performance demands direct control.

Further watching

Videos
card image
Feb 6, 2026
Backend Developer Roadmap 2026: What You Need to Know

Backend complexity keeps growing, and frameworks can't keep up. In 2026, knowing React or Django isn't enough. You need fundamentals that hold up when systems break, traffic spikes, or your architecture gets rewritten for the third time.I've been building production systems for 15 years. This roadmap covers three areas that separate people who know frameworks from people who can actually architect backend systems: data, architecture, and infrastructure. This is about how to think, not what tools to install.

Videos
card image
Jan 29, 2026
JDBC Connection Pools in Microservices. Why They Break Down (and What to Do Instead)

In this livestream, Catherine is joined by Rogerio Robetti, the founder of Open J Proxy, to discuss why traditional JDBC connection pools break down when teams migrate to microservices, and what is a more efficient and reliable approach to organizing database access with microservice architecture.

Videos
card image
Jan 27, 2026
Sizing JDBC Connection Pools for Real Production Load

Many production outages start with connection pool exhaustion. Your app waits seconds for connections while queries take milliseconds; yet, most teams run default settings that collapse under load. This video shows how to configure connection pools that survive real production traffic: sizing based on database limits and thread counts, setting timeouts that prevent cascading failures, and implementing an open source database proxy Open J Proxy for centralized connection management with virtual connection handles, client-side load balancing, and slow query segregation. For senior Java developers, DevOps engineers, and architects who need database performance that holds under pressure.