[[deployment.efficient]]
== Efficient deployments



[[deployment.efficient.unpacking]]
=== Unpacking the Executable JAR
If you are running your application from a container, you can use an executable jar, but it is also often an advantage to explode it and run it in a different way.
Certain PaaS implementations may also choose to unpack archives before they run.
For example, Cloud Foundry operates this way.
One way to run an unpacked archive is by starting the appropriate launcher, as follows:

[source,shell,indent=0,subs="verbatim"]
----
	$ jar -xf myapp.jar
	$ java org.springframework.boot.loader.launch.JarLauncher
----

This is actually slightly faster on startup (depending on the size of the jar) than running from an unexploded archive.
After startup, you should not expect any differences.

Once you have unpacked the jar file, you can also get an extra boost to startup time by running the app with its "natural" main method instead of the `JarLauncher`. For example:

[source,shell,indent=0,subs="verbatim"]
----
	$ jar -xf myapp.jar
	$ java -cp "BOOT-INF/classes:BOOT-INF/lib/*" com.example.MyApplication
----

NOTE: Using the `JarLauncher` over the application's main method has the added benefit of a predictable classpath order.
The jar contains a `classpath.idx` file which is used by the `JarLauncher` when constructing the classpath.



[[deployment.efficient.aot]]
=== Using Ahead-of-time Processing With the JVM
It's beneficial for the startup time to run your application using the AOT generated initialization code.
First, you need to ensure that the jar you are building includes AOT generated code.

For Maven, this means that you should build with `-Pnative` to activate the `native` profile:

[source,shell,indent=0,subs="verbatim"]
----
    $ mvn -Pnative package
----

For Gradle, you need to ensure that your build includes the `org.springframework.boot.aot` plugin.

When the JAR has been built, run it with `spring.aot.enabled` system property set to `true`. For example:

[source,shell,indent=0,subs="verbatim"]
----
	$ java -Dspring.aot.enabled=true -jar myapplication.jar

	........ Starting AOT-processed MyApplication ...
----

Beware that using the ahead-of-time processing has drawbacks.
It implies the following restrictions:

* The classpath is fixed and fully defined at build time
* The beans defined in your application cannot change at runtime, meaning:
- The Spring `@Profile` annotation and profile-specific configuration <<howto#howto.aot.conditions,have limitations>>.
- Properties that change if a bean is created are not supported (for example, `@ConditionalOnProperty` and `.enable` properties).

To learn more about ahead-of-time processing, please see the <<native-image#native-image.introducing-graalvm-native-images.understanding-aot-processing,Understanding Spring Ahead-of-Time Processing section>>.



[[deployment.efficient.checkpoint-restore]]
=== Checkpoint and Restore With the JVM
https://wiki.openjdk.org/display/crac/Main[Coordinated Restore at Checkpoint] (CRaC) is an OpenJDK project that defines a new Java API to allow you to checkpoint and restore an application on the HotSpot JVM.
It is based on https://github.com/checkpoint-restore/criu[CRIU], a project that implements checkpoint/restore functionality on Linux.

The principle is the following: you start your application almost as usual but with a CRaC enabled version of the JDK like https://bell-sw.com/pages/downloads/?package=jdk-crac[Bellsoft Liberica JDK with CRaC] or https://www.azul.com/downloads/?package=jdk-crac#zulu[Azul Zulu JDK with CRaC].
Then at some point, potentially after some workloads that will warm up your JVM by executing all common code paths, you trigger a checkpoint using an API call, a `jcmd` command, an HTTP endpoint, or a different mechanism.

A memory representation of the running JVM, including its warmness, is then serialized to disk, allowing a fast restoration at a later point, potentially on another machine with a similar operating system and CPU architecture.
The restored process retains all the capabilities of the HotSpot JVM, including further JIT optimizations at runtime.

Based on the foundations provided by Spring Framework, Spring Boot provides support for checkpointing and restoring your application, and manages out-of-the-box the lifecycle of resources such as socket, files and thread pools https://github.com/spring-projects/spring-lifecycle-smoke-tests/blob/main/STATUS.adoc[on a limited scope].
Additional lifecycle management is expected for other dependencies and potentially for the application code dealing with such resources.

You can find more details about the two modes supported ("on demand checkpoint/restore of a running application" and "automatic checkpoint/restore at startup"), how to enable checkpoint and restore support and some guidelines in {spring-framework-docs}/integration/checkpoint-restore.html[the Spring Framework JVM Checkpoint Restore support documentation].
