Skip to content

Commit 0e1394e

Browse files
mbhavephilwebb
authored andcommitted
Update reference documentation for layer changes
Update the reference documentation following the jar format changes. See gh-20813
1 parent d61a79d commit 0e1394e

File tree

2 files changed

+31
-83
lines changed

2 files changed

+31
-83
lines changed

spring-boot-project/spring-boot-docs/src/docs/asciidoc/deployment.adoc

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -33,33 +33,10 @@ Once you have unpacked the jar file, you can also get an extra boost to startup
3333
$ java -cp BOOT-INF/classes:BOOT-INF/lib/* com.example.MyApplication
3434
----
3535

36-
More efficient container images can also be created by copying the dependencies to the image as a separate layer from the application classes and resources (which normally change more frequently).
37-
There is more than one way to achieve this layer separation.
38-
For example, using a `Dockerfile` you could express it in this form:
36+
NOTE: Using the `JarLauncher` over the application's main method has the added benefit of a predictable classpath order.
37+
The jar contains a `classpath.idx` file which is used by the `JarLauncher` when constructing the classpath.
3938

40-
[indent=0]
41-
----
42-
FROM openjdk:8-jdk-alpine AS builder
43-
WORKDIR target/dependency
44-
ARG APPJAR=target/*.jar
45-
COPY ${APPJAR} app.jar
46-
RUN jar -xf ./app.jar
47-
48-
FROM openjdk:8-jre-alpine
49-
VOLUME /tmp
50-
ARG DEPENDENCY=target/dependency
51-
COPY --from=builder ${DEPENDENCY}/BOOT-INF/lib /app/lib
52-
COPY --from=builder ${DEPENDENCY}/META-INF /app/META-INF
53-
COPY --from=builder ${DEPENDENCY}/BOOT-INF/classes /app
54-
ENTRYPOINT ["java","-cp","app:app/lib/*","com.example.MyApplication"]
55-
----
56-
57-
Assuming the above `Dockerfile` is in the current directory, your docker image can be built with `docker build .`, or optionally specifying the path to your application jar, as shown in the following example:
58-
59-
[indent=0]
60-
----
61-
docker build --build-arg APPJAR=path/to/myapp.jar .
62-
----
39+
More efficient container images can also be created by <<spring-boot-features.adoc#building-docker-images,creating separate layers>> for your dependencies and application classes and resources (which normally change more frequently).
6340

6441

6542

spring-boot-project/spring-boot-docs/src/docs/asciidoc/spring-boot-features.adoc

Lines changed: 28 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -7996,77 +7996,41 @@ The other issue is that putting your application's code and all its dependencies
79967996
Since you probably recompile your code more often than you upgrade the version of Spring Boot you use, it’s often better to separate things a bit more.
79977997
If you put jar files in the layer before your application classes, Docker often only needs to change the very bottom layer and can pick others up from its cache.
79987998

7999-
=== Layered Jars
8000-
To make it easier to create optimized Docker images that can be built with a dockerfile, Spring Boot supports "layered jars".
8001-
A regular fat jar that can be run with `java -jar` has the following structure:
8002-
8003-
[source]
8004-
----
8005-
META-INF/
8006-
MANIFEST.MF
8007-
org/
8008-
springframework/
8009-
boot/
8010-
loader/
8011-
...
8012-
BOOT-INF/
8013-
classes/
8014-
...
8015-
lib/
8016-
...
8017-
----
8018-
8019-
The jar is organized into three main parts:
8020-
8021-
* Classes used to bootstrap jar loading
8022-
* Your application classes in `BOOT-INF/classes`
8023-
* Dependencies in `BOOT-INF/lib`
8024-
8025-
Instead of the above jar, you can create a layered jar that looks something like this:
8026-
8027-
[source]
8028-
----
8029-
META-INF/
8030-
MANIFEST.MF
8031-
org/
8032-
springframework/
8033-
boot/
8034-
loader/
8035-
...
8036-
BOOT-INF/
8037-
layers/
8038-
<name>/
8039-
classes/
8040-
...
8041-
lib/
8042-
...
8043-
<name>/
8044-
classes/
8045-
...
8046-
lib/
8047-
...
8048-
layers.idx
8049-
----
8050-
8051-
You still see the bootstrap loader classes (you can still run `java -jar`) but now the `lib` and `classes` folders have been split up and categorized into layers.
8052-
There’s also a `layers.idx` file that provides the order in which layers should be added.
7999+
=== Layering Docker Images
8000+
To make it easier to create optimized Docker images that can be built with a dockerfile, Spring Boot supports adding a layer index file to the jar.
8001+
The `layers.idx` file lists all the files in the jar along with the layer that the file should go in.
8002+
The list of files in the index is ordered based on the order in which the layers should be added.
80538003
Out-of-the-box, the following layers are supported:
80548004

80558005
* `dependencies` (for regular released dependencies)
8006+
* `spring-boot-loader` (for everything under `org/springframework/boot/loader`)
80568007
* `snapshot-dependencies` (for snapshot dependencies)
8057-
* `resources` (for static resources)
80588008
* `application` (for application classes and resources)
80598009

8010+
The following shows an example of a `layers.idx` file:
8011+
8012+
[source]
8013+
----
8014+
dependencies BOOT-INF/lib/library1.jar
8015+
dependencies BOOT-INF/lib/library2.jar
8016+
spring-boot-loader org/springframework/boot/loader/JarLauncher.class
8017+
spring-boot-loader org/springframework/boot/loader/jar/JarEntry.class
8018+
...
8019+
snapshot-dependencies BOOT-INF/lib/library3-SNAPSHOT.jar
8020+
application META-INF/MANIFEST.MF
8021+
application BOOT-INF/classes/a/b/C.class
8022+
----
80608023

80618024
This layering is designed to separate code based on how likely it is to change between application builds.
80628025
Library code is less likely to change between builds, so it is placed in its own layers to allow tooling to re-use the layers from cache.
80638026
Application code is more likely to change between builds so it is isolated in a separate layer.
80648027

8065-
For Maven, refer to the {spring-boot-maven-plugin-docs}/#repackage-layered-jars[packaging layered jars section] for more details on creating a layered jar.
8028+
For Maven, refer to the {spring-boot-maven-plugin-docs}/#repackage-layered-jars[packaging layered jars section] for more details on adding a layer index to the jar.
80668029
For Gradle, refer to the {spring-boot-gradle-plugin-docs}/#packaging-layered-jars[packaging layered jars section] of the Gradle plugin documentation.
80678030

8068-
=== Writing the Dockerfile
80698031

8032+
8033+
=== Writing the Dockerfile
80708034
When you create a layered jar, the `spring-boot-jarmode-layertools` jar will be added as a dependency to your jar.
80718035
With this jar on the classpath, you can launch your application in a special mode which allows the bootstrap code to run something entirely different from your application, for example, something that extracts the layers.
80728036
Here’s how you can launch your jar with a `layertools` jar mode:
@@ -8109,6 +8073,13 @@ COPY --from=builder application/application/ ./
81098073
ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]
81108074
----
81118075

8076+
Assuming the above `Dockerfile` is in the current directory, your docker image can be built with `docker build .`, or optionally specifying the path to your application jar, as shown in the following example:
8077+
8078+
[indent=0]
8079+
----
8080+
docker build --build-arg JAR_FILE=path/to/myapp.jar .
8081+
----
8082+
81128083
This is a multi-stage dockerfile.
81138084
The builder stage extracts the folders that are needed later.
81148085
Each of the `COPY` commands relates to the layers extracted by the jarmode.

0 commit comments

Comments
 (0)