Skip to content

Commit 59bc746

Browse files
Jay Bryantsnicoll
authored andcommitted
Make editorial changes to appendix-executable-jar-format.adoc
See gh-10878
1 parent 96e3976 commit 59bc746

File tree

1 file changed

+93
-91
lines changed

1 file changed

+93
-91
lines changed

spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-executable-jar-format.adoc

Lines changed: 93 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,35 @@
11
[appendix]
22
[[executable-jar]]
3-
== The executable jar format
4-
The `spring-boot-loader` modules allows Spring Boot to support executable jar and
5-
war files. If you're using the Maven or Gradle plugin, executable jars are
6-
automatically generated and you generally won't need to know the details of how
3+
== The Executable Jar Format
4+
The `spring-boot-loader` modules lets Spring Boot support executable jar and
5+
war files. If you use the Maven plugin or the Gradle plugin, executable jars are
6+
automatically generated, and you generally do not need to know the details of how
77
they work.
88

9-
If you need to create executable jars from a different build system, or if you are just
9+
If you need to create executable jars from a different build system or if you are just
1010
curious about the underlying technology, this section provides some background.
1111

1212

1313

1414
[[executable-jar-nested-jars]]
1515
=== Nested JARs
16-
Java does not provide any standard way to load nested jar files (i.e. jar files that
17-
are themselves contained within a jar). This can be problematic if you are looking
18-
to distribute a self-contained application that you can just run from the command line
16+
Java does not provide any standard way to load nested jar files (that is, jar files that
17+
are themselves contained within a jar). This can be problematic if you need
18+
to distribute a self-contained application that can be run from the command line
1919
without unpacking.
2020

21-
To solve this problem, many developers use "`shaded`" jars. A shaded jar simply packages
22-
all classes, from all jars, into a single 'uber jar'. The problem with shaded jars is
23-
that it becomes hard to see which libraries you are actually using in your application.
21+
To solve this problem, many developers use "`shaded`" jars. A shaded jar packages
22+
all classes, from all jars, into a single "`uber jar`". The problem with shaded jars is
23+
that it becomes hard to see which libraries are actually in your application.
2424
It can also be problematic if the same filename is used (but with different content)
25-
in multiple jars. Spring Boot takes a different approach and allows you to actually nest
25+
in multiple jars. Spring Boot takes a different approach and lets you actually nest
2626
jars directly.
2727

2828

2929

3030
[[executable-jar-jar-file-structure]]
31-
==== The executable jar file structure
32-
Spring Boot Loader compatible jar files should be structured in the following way:
31+
==== The Executable Jar File Structure
32+
Spring Boot Loader-compatible jar files should be structured in the following way:
3333

3434
[indent=0]
3535
----
@@ -58,8 +58,8 @@ Dependencies should be placed in a nested `BOOT-INF/lib` directory.
5858

5959

6060
[[executable-jar-war-file-structure]]
61-
==== The executable war file structure
62-
Spring Boot Loader compatible war files should be structured in the following way:
61+
==== The Executable War File Structure
62+
Spring Boot Loader-compatible war files should be structured in the following way:
6363

6464
[indent=0]
6565
----
@@ -93,11 +93,12 @@ a traditional web container should be placed in `WEB-INF/lib-provided`.
9393

9494

9595
[[executable-jar-jarfile]]
96-
=== Spring Boot's "`JarFile`" class
96+
=== Spring Boot's "`JarFile`" Class
9797
The core class used to support loading nested jars is
98-
`org.springframework.boot.loader.jar.JarFile`. It allows you to load jar
99-
content from a standard jar file, or from nested child jar data. When first loaded, the
100-
location of each `JarEntry` is mapped to a physical file offset of the outer jar:
98+
`org.springframework.boot.loader.jar.JarFile`. It lets you load jar
99+
content from a standard jar file or from nested child jar data. When first loaded, the
100+
location of each `JarEntry` is mapped to a physical file offset of the outer jar, as
101+
shown in the following example:
101102

102103
[indent=0]
103104
----
@@ -112,79 +113,79 @@ location of each `JarEntry` is mapped to a physical file offset of the outer jar
112113
0063 3452 3980
113114
----
114115

115-
The example above shows how `A.class` can be found in `/BOOT-INF/classes` in `myapp.jar`
116-
position `0063`. `B.class` from the nested jar can actually be found in `myapp.jar`
117-
position `3452` and `C.class` is at position `3980`.
116+
The preceding example shows how `A.class` can be found in `/BOOT-INF/classes` in `myapp.jar`
117+
at position `0063`. `B.class` from the nested jar can actually be found in `myapp.jar`
118+
at position `3452`, and `C.class` is at position `3980`.
118119

119-
Armed with this information, we can load specific nested entries by simply seeking to
120-
the appropriate part of the outer jar. We don't need to unpack the archive and we
121-
don't need to read all entry data into memory.
120+
Armed with this information, we can load specific nested entries by seeking to
121+
the appropriate part of the outer jar. We do not need to unpack the archive, and we
122+
do not need to read all entry data into memory.
122123

123124

124125

125126
[[executable-jar-jarfile-compatibility]]
126-
==== Compatibility with the standard Java "`JarFile`"
127+
==== Compatibility with the Standard Java "`JarFile`"
127128
Spring Boot Loader strives to remain compatible with existing code and libraries.
128129
`org.springframework.boot.loader.jar.JarFile` extends from `java.util.jar.JarFile` and
129-
should work as a drop-in replacement. The `getURL()` method will return a `URL` that
130-
opens a `java.net.JarURLConnection` compatible connection and can be used with Java's
130+
should work as a drop-in replacement. The `getURL()` method returns a `URL` that
131+
opens a connection compatible with `java.net.JarURLConnection` and can be used with Java's
131132
`URLClassLoader`.
132133

133134

134135

135136
[[executable-jar-launching]]
136-
=== Launching executable jars
137+
=== Launching Executable Jars
137138
The `org.springframework.boot.loader.Launcher` class is a special bootstrap class that
138-
is used as an executable jars main entry point. It is the actual `Main-Class` in your jar
139-
file and it's used to setup an appropriate `URLClassLoader` and ultimately call your
139+
is used as an executable jar's main entry point. It is the actual `Main-Class` in your jar
140+
file, and it is used to setup an appropriate `URLClassLoader` and ultimately call your
140141
`main()` method.
141142

142-
There are 3 launcher subclasses (`JarLauncher`, `WarLauncher` and `PropertiesLauncher`).
143-
Their purpose is to load resources (`.class` files etc.) from nested jar files or war
144-
files in directories (as opposed to explicitly on the classpath). In the case of
145-
`JarLauncher` and `WarLauncher` the nested paths are fixed. `JarLauncher` looks in
146-
`BOOT-INF/lib/` and `WarLauncher` looks in `WEB-INF/lib/` and `WEB-INF/lib-provided/` so
147-
you just add extra jars in those locations if you want more. The `PropertiesLauncher`
143+
There are three launcher subclasses (`JarLauncher`, `WarLauncher`, and `PropertiesLauncher`).
144+
Their purpose is to load resources (`.class` files and so on.) from nested jar files or war
145+
files in directories (as opposed to those explicitly on the classpath). In the case of
146+
`JarLauncher` and `WarLauncher`, the nested paths are fixed. `JarLauncher` looks in
147+
`BOOT-INF/lib/`, and `WarLauncher` looks in `WEB-INF/lib/` and `WEB-INF/lib-provided/`.
148+
You can add extra jars in those locations if you want more. The `PropertiesLauncher`
148149
looks in `BOOT-INF/lib/` in your application archive by default, but you can add
149-
additional locations by setting an environment variable `LOADER_PATH` or `loader.path`
150-
in `loader.properties` (comma-separated list of directories, archives, or directories
150+
additional locations by setting an environment variable called `LOADER_PATH` or `loader.path`
151+
in `loader.properties` (which is a comma-separated list of directories, archives, or directories
151152
within archives).
152153

153154

154155

155156
[[executable-jar-launcher-manifest]]
156-
==== Launcher manifest
157+
==== Launcher Manifest
157158
You need to specify an appropriate `Launcher` as the `Main-Class` attribute of
158-
`META-INF/MANIFEST.MF`. The actual class that you want to launch (i.e. the class that
159-
you wrote that contains a `main` method) should be specified in the `Start-Class`
159+
`META-INF/MANIFEST.MF`. The actual class that you want to launch (that is, the class that
160+
contains a `main` method) should be specified in the `Start-Class`
160161
attribute.
161162

162-
For example, here is a typical `MANIFEST.MF` for an executable jar file:
163+
The following example shows a typical `MANIFEST.MF` for an executable jar file:
163164

164165
[indent=0]
165166
----
166167
Main-Class: org.springframework.boot.loader.JarLauncher
167168
Start-Class: com.mycompany.project.MyApplication
168169
----
169170

170-
For a war file, it would be:
171+
For a war file, it would be as follows:
171172

172173
[indent=0]
173174
----
174175
Main-Class: org.springframework.boot.loader.WarLauncher
175176
Start-Class: com.mycompany.project.MyApplication
176177
----
177178

178-
NOTE: You do not need to specify `Class-Path` entries in your manifest file, the classpath
179-
will be deduced from the nested jars.
179+
NOTE: You need not specify `Class-Path` entries in your manifest file. The classpath
180+
is deduced from the nested jars.
180181

181182

182183

183184
[[executable-jar-exploded-archives]]
184-
==== Exploded archives
185+
==== Exploded Archives
185186
Certain PaaS implementations may choose to unpack archives before they run. For example,
186-
Cloud Foundry operates in this way. You can run an unpacked archive by simply starting
187-
the appropriate launcher:
187+
Cloud Foundry operates this way. You can run an unpacked archive by starting
188+
the appropriate launcher, as follows:
188189

189190
[indent=0]
190191
----
@@ -195,41 +196,42 @@ the appropriate launcher:
195196

196197

197198
[[executable-jar-property-launcher-features]]
198-
=== PropertiesLauncher Features
199+
=== `PropertiesLauncher` Features
199200

200201
`PropertiesLauncher` has a few special features that can be enabled with external
201-
properties (System properties, environment variables, manifest entries or
202-
`loader.properties`).
202+
properties (System properties, environment variables, manifest entries, or
203+
`loader.properties`). The following table describes these properties:
203204

204205
|===
205206
|Key |Purpose
206207

207208
|`loader.path`
208-
|Comma-separated Classpath, e.g. `lib,${HOME}/app/lib`. Earlier entries take precedence,
209-
just like a regular `-classpath` on the `javac` command line.
209+
|Comma-separated Classpath, such as `lib,${HOME}/app/lib`. Earlier entries take precedence,
210+
like a regular `-classpath` on the `javac` command line.
210211

211212
|`loader.home`
212-
|Used to resolve relative paths in `loader.path`. E.g. `loader.path=lib` then
213+
|Used to resolve relative paths in `loader.path`. For example, given `loader.path=lib`, then
213214
`${loader.home}/lib` is a classpath location (along with all jar files in that
214-
directory). Also used to locate a `loader.properties` file. Example `file:///opt/app`
215-
(defaults to `${user.dir}`).
215+
directory). This property is also used to locate a `loader.properties` file, as in the
216+
following example `file:///opt/app`
217+
It defaults to `${user.dir}`.
216218

217219
|`loader.args`
218-
|Default arguments for the main method (space separated)
220+
|Default arguments for the main method (space separated).
219221

220222
|`loader.main`
221-
|Name of main class to launch, e.g. `com.app.Application`.
223+
|Name of main class to launch (for example, `com.app.Application`).
222224

223225
|`loader.config.name`
224-
|Name of properties file, e.g. `launcher` (defaults to `loader`).
226+
|Name of properties file (for example, `launcher`) It defaults to `loader`.
225227

226228
|`loader.config.location`
227-
|Path to properties file, e.g. `classpath:loader.properties` (defaults to
228-
`loader.properties`).
229+
|Path to properties file (for example, `classpath:loader.properties`). It defaults to
230+
`loader.properties`.
229231

230232
|`loader.system`
231233
|Boolean flag to indicate that all properties should be added to System properties
232-
(defaults to `false`)
234+
It defaults to `false`.
233235

234236
|===
235237

@@ -266,66 +268,66 @@ be used:
266268
|===
267269

268270
TIP: Build plugins automatically move the `Main-Class` attribute to `Start-Class` when
269-
the fat jar is built. If you are using that, specify the name of the class to launch using
270-
the `Main-Class` attribute and leave out `Start-Class`.
271-
272-
* `loader.properties` are searched for in `loader.home` then in the root of the
273-
classpath, then in `classpath:/BOOT-INF/classes`. The first location that exists is
274-
used.
275-
* `loader.home` is only the directory location of an additional properties file
276-
(overriding the default) as long as `loader.config.location` is not specified.
277-
* `loader.path` can contain directories (scanned recursively for jar and zip files),
271+
the fat jar is built. If you use that, specify the name of the class to launch by using
272+
the `Main-Class` attribute and leaving out `Start-Class`.
273+
274+
The following rules apply to working with `PropertiesLauncher`:
275+
276+
* `loader.properties` is searched for in `loader.home`, then in the root of the
277+
classpath, and then in `classpath:/BOOT-INF/classes`. The first location where a file
278+
with that name exists is used.
279+
* `loader.home` is the directory location of an additional properties file
280+
(overriding the default) only when `loader.config.location` is not specified.
281+
* `loader.path` can contain directories (which are scanned recursively for jar and zip files),
278282
archive paths, a directory within an archive that is scanned for jar files (for
279283
example, `dependencies.jar!/lib`), or wildcard patterns (for the default JVM behavior).
280-
Archive paths can be relative to `loader.home`, or anywhere in the file system with a
284+
Archive paths can be relative to `loader.home` or anywhere in the file system with a
281285
`jar:file:` prefix.
282286
* `loader.path` (if empty) defaults to `BOOT-INF/lib` (meaning a local directory or a
283-
nested one if running from an archive). Because of this `PropertiesLauncher` behaves the
287+
nested one if running from an archive). Because of this, `PropertiesLauncher` behaves the
284288
same as `JarLauncher` when no additional configuration is provided.
285289
* `loader.path` can not be used to configure the location of `loader.properties` (the
286290
classpath used to search for the latter is the JVM classpath when `PropertiesLauncher`
287291
is launched).
288292
* Placeholder replacement is done from System and environment variables plus the
289293
properties file itself on all values before use.
290294
* The search order for properties (where it makes sense to look in more than one place)
291-
is env vars, system properties, `loader.properties`, exploded archive manifest, archive
292-
manifest.
295+
is environment variables, system properties, `loader.properties`, the exploded archive
296+
manifest, and the archive manifest.
293297

294298

295299

296300
[[executable-jar-restrictions]]
297-
=== Executable jar restrictions
298-
There are a number of restrictions that you need to consider when working with a Spring
299-
Boot Loader packaged application.
301+
=== Executable Jar Restrictions
302+
You need to consider the following restrictions when working with a Spring
303+
Boot Loader packaged application:
300304

301305

302306

303307
[[executable-jar-zip-entry-compression]]
304-
==== Zip entry compression
305-
The `ZipEntry` for a nested jar must be saved using the `ZipEntry.STORED` method. This
308+
* Zip entry compression:
309+
The `ZipEntry` for a nested jar must be saved by using the `ZipEntry.STORED` method. This
306310
is required so that we can seek directly to individual content within the nested jar.
307311
The content of the nested jar file itself can still be compressed, as can any other
308312
entries in the outer jar.
309313

310314

311315

312316
[[executable-jar-system-classloader]]
313-
==== System ClassLoader
317+
* System classLoader:
314318
Launched applications should use `Thread.getContextClassLoader()` when loading classes
315-
(most libraries and frameworks will do this by default). Trying to load nested jar
316-
classes via `ClassLoader.getSystemClassLoader()` will fail. Please be aware that
317-
`java.util.Logging` always uses the system classloader, for this reason you should
319+
(most libraries and frameworks do so by default). Trying to load nested jar
320+
classes with `ClassLoader.getSystemClassLoader()` fails.
321+
`java.util.Logging` always uses the system classloader. For this reason, you should
318322
consider a different logging implementation.
319323

320324

321325

322326
[[executable-jar-alternatives]]
323-
=== Alternative single jar solutions
324-
If the above restrictions mean that you cannot use Spring Boot Loader the following
325-
alternatives could be considered:
327+
=== Alternative Single Jar Solutions
328+
If the preceding restrictions mean that you cannot use Spring Boot Loader, consider the following
329+
alternatives:
326330

327331
* http://maven.apache.org/plugins/maven-shade-plugin/[Maven Shade Plugin]
328332
* http://www.jdotsoft.com/JarClassLoader.php[JarClassLoader]
329333
* http://one-jar.sourceforge.net[OneJar]
330-
331-

0 commit comments

Comments
 (0)