Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in / Register
Toggle navigation
S
spring-boot
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
DEMO
spring-boot
Commits
34e60265
Commit
34e60265
authored
Apr 03, 2020
by
Andy Wilkinson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Polish new layered jar support
parent
3e936dd7
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
182 additions
and
34 deletions
+182
-34
boot-jar-layered-custom.gradle
.../src/docs/gradle/packaging/boot-jar-layered-custom.gradle
+1
-1
boot-jar-layered-custom.gradle.kts
.../docs/gradle/packaging/boot-jar-layered-custom.gradle.kts
+6
-2
boot-jar-layered-exclude-tools.gradle
...cs/gradle/packaging/boot-jar-layered-exclude-tools.gradle
+1
-1
boot-jar-layered-exclude-tools.gradle.kts
...radle/packaging/boot-jar-layered-exclude-tools.gradle.kts
+2
-2
BootJar.java
...g/springframework/boot/gradle/tasks/bundling/BootJar.java
+25
-14
LayeredSpec.java
...ringframework/boot/gradle/tasks/bundling/LayeredSpec.java
+112
-12
PackagingDocumentationTests.java
...amework/boot/gradle/docs/PackagingDocumentationTests.java
+31
-0
BootJarTests.java
...ingframework/boot/gradle/tasks/bundling/BootJarTests.java
+1
-1
BootJarIntegrationTests-customLayers.gradle
...asks/bundling/BootJarIntegrationTests-customLayers.gradle
+1
-1
StandardLayers.java
...org/springframework/boot/loader/tools/StandardLayers.java
+2
-0
No files found.
spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/boot-jar-layered-custom.gradle
View file @
34e60265
...
...
@@ -22,7 +22,7 @@ bootJar {
}
intoLayer
(
"dependencies"
)
}
layerOrder
"dependencies"
,
"spring-boot-loader"
,
"snapshot-dependencies"
,
"application"
layerOrder
=
[
"dependencies"
,
"spring-boot-loader"
,
"snapshot-dependencies"
,
"application"
]
}
}
// end::layered[]
spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/boot-jar-layered-custom.gradle.kts
View file @
34e60265
...
...
@@ -5,6 +5,10 @@ plugins {
id
(
"org.springframework.boot"
)
version
"{version}"
}
tasks
.
getByName
<
BootJar
>(
"bootJar"
)
{
mainClassName
=
"com.example.ExampleApplication"
}
// tag::layered[]
tasks
.
getByName
<
BootJar
>(
"bootJar"
)
{
layered
{
...
...
@@ -18,9 +22,9 @@ tasks.getByName<BootJar>("bootJar") {
intoLayer
(
"snapshot-dependencies"
)
{
include
(
"*:*:*SNAPSHOT"
)
}
intoLayer
(
"dependencies"
)
{
intoLayer
(
"dependencies"
)
}
layer
sOrder
(
"dependencies"
,
"spring-boot-loader"
,
"snapshot-dependencies"
,
"application"
)
layer
Order
=
listOf
(
"dependencies"
,
"spring-boot-loader"
,
"snapshot-dependencies"
,
"application"
)
}
}
// end::layered[]
spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/boot-jar-layered-exclude-tools.gradle
View file @
34e60265
...
...
@@ -9,7 +9,7 @@ bootJar {
// tag::layered[]
bootJar
{
layer
s
{
layer
ed
{
includeLayerTools
=
false
}
}
...
...
spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/docs/gradle/packaging/boot-jar-layered-exclude-tools.gradle.kts
View file @
34e60265
...
...
@@ -11,8 +11,8 @@ tasks.getByName<BootJar>("bootJar") {
// tag::layered[]
tasks
.
getByName
<
BootJar
>(
"bootJar"
)
{
layer
s
{
includeLayerTools
=
false
layer
ed
{
i
sI
ncludeLayerTools
=
false
}
}
// end::layered[]
spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootJar.java
View file @
34e60265
...
...
@@ -20,7 +20,6 @@ import java.io.File;
import
java.util.Collections
;
import
java.util.concurrent.Callable
;
import
groovy.lang.Closure
;
import
org.gradle.api.Action
;
import
org.gradle.api.artifacts.Configuration
;
import
org.gradle.api.file.CopySpec
;
...
...
@@ -33,7 +32,6 @@ import org.gradle.api.tasks.Internal;
import
org.gradle.api.tasks.Nested
;
import
org.gradle.api.tasks.Optional
;
import
org.gradle.api.tasks.bundling.Jar
;
import
org.gradle.util.ConfigureUtil
;
/**
* A custom {@link Jar} task that produces a Spring Boot executable jar.
...
...
@@ -158,28 +156,33 @@ public class BootJar extends Jar implements BootArchive {
action
.
execute
(
enableLaunchScriptIfNecessary
());
}
/**
* Returns the spec that describes the layers in a layerd jar.
* @return the spec for the layers or {@code null}.
* @since 2.3.0
*/
@Nested
@Optional
public
LayeredSpec
getLayered
()
{
return
this
.
layered
;
}
/**
* Configures the jar to be layered using the default layering.
* @since 2.3.0
*/
public
void
layered
()
{
layered
(
true
);
}
public
void
layered
(
boolean
layered
)
{
this
.
layered
=
layered
?
new
LayeredSpec
()
:
null
;
}
public
void
layered
(
Closure
<?>
closure
)
{
layered
(
ConfigureUtil
.
configureUsing
(
closure
));
enableLayeringIfNecessary
();
}
/**
* Configures the jar to be layered, customizing the layers using the given
* {@code action}.
* @param action the action to apply
* @since 2.3.0
*/
public
void
layered
(
Action
<
LayeredSpec
>
action
)
{
LayeredSpec
layered
=
new
LayeredSpec
();
action
.
execute
(
layered
);
this
.
layered
=
layered
;
action
.
execute
(
enableLayeringIfNecessary
());
}
@Override
...
...
@@ -258,6 +261,7 @@ public class BootJar extends Jar implements BootArchive {
* {@code BOOT-INF/lib} is considered to be a library.
* @param details the file copy details
* @return {@code true} if the details are for a library
* @since 2.3.0
*/
protected
boolean
isLibrary
(
FileCopyDetails
details
)
{
String
path
=
details
.
getRelativePath
().
getPathString
();
...
...
@@ -273,6 +277,13 @@ public class BootJar extends Jar implements BootArchive {
return
launchScript
;
}
private
LayeredSpec
enableLayeringIfNecessary
()
{
if
(
this
.
layered
==
null
)
{
this
.
layered
=
new
LayeredSpec
();
}
return
this
.
layered
;
}
/**
* Syntactic sugar that makes {@link CopySpec#into} calls a little easier to read.
* @param <T> the result type
...
...
spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/LayeredSpec.java
View file @
34e60265
...
...
@@ -61,59 +61,117 @@ public class LayeredSpec {
private
Layers
layers
;
/**
* Returns whether the layer tools should be included as a dependency in the layered
* jar.
* @return whether the layer tools should be included
*/
@Input
public
boolean
isIncludeLayerTools
()
{
return
this
.
includeLayerTools
;
}
/**
* Sets whether the layer tools should be included as a dependency in the layered jar.
* @param includeLayerTools {@code true} if the layer tools should be included,
* otherwise {@code false}
*/
public
void
setIncludeLayerTools
(
boolean
includeLayerTools
)
{
this
.
includeLayerTools
=
includeLayerTools
;
}
/**
* Returns the {@link ApplicationSpec} that controls the layers to which application
* classes and resources belong.
* @return the application spec
*/
@Input
public
ApplicationSpec
getApplication
()
{
return
this
.
application
;
}
public
void
application
(
ApplicationSpec
spec
)
{
/**
* Sets the {@link ApplicationSpec} that controls the layers to which application
* classes are resources belong.
* @param spec the application spec
*/
public
void
setApplication
(
ApplicationSpec
spec
)
{
this
.
application
=
spec
;
}
public
void
application
(
Closure
<?>
closure
)
{
application
(
ConfigureUtil
.
configureUsing
(
closure
));
}
/**
* Customizes the {@link ApplicationSpec} using the given {@code action}.
* @param action the action
*/
public
void
application
(
Action
<
ApplicationSpec
>
action
)
{
action
.
execute
(
this
.
application
);
}
/**
* Customizes the {@link ApplicationSpec} using the given {@code closure}.
* @param closure the closure
*/
public
void
application
(
Closure
<?>
closure
)
{
application
(
ConfigureUtil
.
configureUsing
(
closure
));
}
/**
* Returns the {@link DependenciesSpec} that controls the layers to which dependencies
* belong.
* @return the dependencies spec
*/
@Input
public
DependenciesSpec
getDependencies
()
{
return
this
.
dependencies
;
}
public
void
dependencies
(
DependenciesSpec
spec
)
{
/**
* Sets the {@link DependenciesSpec} that controls the layers to which dependencies
* belong.
* @param spec the dependencies spec
*/
public
void
setDependencies
(
DependenciesSpec
spec
)
{
this
.
dependencies
=
spec
;
}
public
void
dependencies
(
Closure
<?>
closure
)
{
dependencies
(
ConfigureUtil
.
configureUsing
(
closure
));
}
/**
* Customizes the {@link DependenciesSpec} using the given {@code action}.
* @param action the action
*/
public
void
dependencies
(
Action
<
DependenciesSpec
>
action
)
{
action
.
execute
(
this
.
dependencies
);
}
/**
* Customizes the {@link DependenciesSpec} using the given {@code closure}.
* @param closure the closure
*/
public
void
dependencies
(
Closure
<?>
closure
)
{
dependencies
(
ConfigureUtil
.
configureUsing
(
closure
));
}
/**
* Returns the order of the layers in the jar from least to most frequently changing.
* @return the layer order
*/
@Input
public
List
<
String
>
getLayerOrder
()
{
return
this
.
layerOrder
;
}
public
void
layerOrder
(
String
...
layerOrder
)
{
/**
* Sets to order of the layers in the jar from least to most frequently changing.
* @param layerOrder the layer order
*/
public
void
setLayerOrder
(
String
...
layerOrder
)
{
this
.
layerOrder
=
Arrays
.
asList
(
layerOrder
);
}
public
void
layerOrder
(
List
<
String
>
layerOrder
)
{
/**
* Sets to order of the layers in the jar from least to most frequently changing.
* @param layerOrder the layer order
*/
public
void
setLayerOrder
(
List
<
String
>
layerOrder
)
{
this
.
layerOrder
=
layerOrder
;
}
...
...
@@ -141,6 +199,10 @@ public class LayeredSpec {
return
new
CustomLayers
(
layers
,
this
.
application
.
asSelectors
(),
this
.
dependencies
.
asSelectors
());
}
/**
* Base class for specs that control the layers to which a category of content should
* belong.
*/
public
abstract
static
class
IntoLayersSpec
implements
Serializable
{
private
final
List
<
IntoLayerSpec
>
intoLayers
;
...
...
@@ -174,6 +236,9 @@ public class LayeredSpec {
}
/**
* Spec that controls the content that should be part of a particular layer.
*/
public
static
class
IntoLayerSpec
implements
Serializable
{
private
final
String
intoLayer
;
...
...
@@ -182,14 +247,33 @@ public class LayeredSpec {
private
final
List
<
String
>
excludes
=
new
ArrayList
<>();
/**
* Creates a new {@code IntoLayerSpec} that will control the content of the given
* layer.
* @param intoLayer the layer
*/
public
IntoLayerSpec
(
String
intoLayer
)
{
this
.
intoLayer
=
intoLayer
;
}
/**
* Adds patterns that control the content that is included in the layer. If no
* includes are specified then all content is included. If includes are specified
* then content must match an inclusion pattern and not match any exclusion
* patterns to be included.
* @param patterns the patterns to be included
*/
public
void
include
(
String
...
patterns
)
{
this
.
includes
.
addAll
(
Arrays
.
asList
(
patterns
));
}
/**
* Adds patterns that control the content that is excluded from the layer. If no
* excludes a specified no content is excluded. If exclusions are specified then
* any content that matches an exclusion will be excluded irrespective of whether
* it matches an include pattern.
* @param patterns the patterns to be excluded
*/
public
void
exclude
(
String
...
patterns
)
{
this
.
includes
.
addAll
(
Arrays
.
asList
(
patterns
));
}
...
...
@@ -201,8 +285,17 @@ public class LayeredSpec {
}
/**
* An {@link IntoLayersSpec} that controls the layers to which application classes and
* resources belong.
*/
public
static
class
ApplicationSpec
extends
IntoLayersSpec
{
/**
* Creates a new {@code ApplicationSpec} with the given {@code contents}.
* @param contents specs for the layers in which application content should be
* included
*/
public
ApplicationSpec
(
IntoLayerSpec
...
contents
)
{
super
(
contents
);
}
...
...
@@ -213,8 +306,15 @@ public class LayeredSpec {
}
/**
* An {@link IntoLayersSpec} that controls the layers to which dependencies belong.
*/
public
static
class
DependenciesSpec
extends
IntoLayersSpec
{
/**
* Creates a new {@code DependenciesSpec} with the given {@code contents}.
* @param contents specs for the layers in which dependencies should be included
*/
public
DependenciesSpec
(
IntoLayerSpec
...
contents
)
{
super
(
contents
);
}
...
...
spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/docs/PackagingDocumentationTests.java
View file @
34e60265
...
...
@@ -21,6 +21,7 @@ import java.io.FileOutputStream;
import
java.io.FileReader
;
import
java.io.FileWriter
;
import
java.io.IOException
;
import
java.util.Collections
;
import
java.util.jar.JarEntry
;
import
java.util.jar.JarFile
;
import
java.util.jar.JarOutputStream
;
...
...
@@ -187,6 +188,36 @@ class PackagingDocumentationTests {
try
(
JarFile
jar
=
new
JarFile
(
file
))
{
JarEntry
entry
=
jar
.
getJarEntry
(
"BOOT-INF/layers.idx"
);
assertThat
(
entry
).
isNotNull
();
assertThat
(
Collections
.
list
(
jar
.
entries
()).
stream
().
map
(
JarEntry:
:
getName
)
.
filter
((
name
)
->
name
.
startsWith
(
"BOOT-INF/lib/spring-boot"
))).
isNotEmpty
();
}
}
@TestTemplate
void
bootJarLayeredCustom
()
throws
IOException
{
this
.
gradleBuild
.
script
(
"src/docs/gradle/packaging/boot-jar-layered-custom"
).
build
(
"bootJar"
);
File
file
=
new
File
(
this
.
gradleBuild
.
getProjectDir
(),
"build/libs/"
+
this
.
gradleBuild
.
getProjectDir
().
getName
()
+
".jar"
);
assertThat
(
file
).
isFile
();
try
(
JarFile
jar
=
new
JarFile
(
file
))
{
JarEntry
entry
=
jar
.
getJarEntry
(
"BOOT-INF/layers.idx"
);
assertThat
(
entry
).
isNotNull
();
assertThat
(
Collections
.
list
(
jar
.
entries
()).
stream
().
map
(
JarEntry:
:
getName
)
.
filter
((
name
)
->
name
.
startsWith
(
"BOOT-INF/lib/spring-boot"
))).
isNotEmpty
();
}
}
@TestTemplate
void
bootJarLayeredExcludeTools
()
throws
IOException
{
this
.
gradleBuild
.
script
(
"src/docs/gradle/packaging/boot-jar-layered-exclude-tools"
).
build
(
"bootJar"
);
File
file
=
new
File
(
this
.
gradleBuild
.
getProjectDir
(),
"build/libs/"
+
this
.
gradleBuild
.
getProjectDir
().
getName
()
+
".jar"
);
assertThat
(
file
).
isFile
();
try
(
JarFile
jar
=
new
JarFile
(
file
))
{
JarEntry
entry
=
jar
.
getJarEntry
(
"BOOT-INF/layers.idx"
);
assertThat
(
entry
).
isNotNull
();
assertThat
(
Collections
.
list
(
jar
.
entries
()).
stream
().
map
(
JarEntry:
:
getName
)
.
filter
((
name
)
->
name
.
startsWith
(
"BOOT-INF/lib/spring-boot"
))).
isEmpty
();
}
}
...
...
spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootJarTests.java
View file @
34e60265
...
...
@@ -124,7 +124,7 @@ class BootJarTests extends AbstractBootArchiveTests<TestBootJar> {
dependencies
.
intoLayer
(
"my-internal-deps"
,
(
spec
)
->
spec
.
include
(
"com.example:*:*"
));
dependencies
.
intoLayer
(
"my-deps"
);
});
layered
.
l
ayerOrder
(
"my-deps"
,
"my-internal-deps"
,
"my-snapshot-deps"
,
"resources"
,
"application"
);
layered
.
setL
ayerOrder
(
"my-deps"
,
"my-internal-deps"
,
"my-snapshot-deps"
,
"resources"
,
"application"
);
});
try
(
JarFile
jarFile
=
new
JarFile
(
jar
))
{
List
<
String
>
entryNames
=
getEntryNames
(
jar
);
...
...
spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/bundling/BootJarIntegrationTests-customLayers.gradle
View file @
34e60265
...
...
@@ -21,7 +21,7 @@ bootJar {
}
intoLayer
(
"dependencies"
)
}
layerOrder
"dependencies"
,
"commons-dependencies"
,
"snapshot-dependencies"
,
"static"
,
"app"
layerOrder
=
[
"dependencies"
,
"commons-dependencies"
,
"snapshot-dependencies"
,
"static"
,
"app"
]
}
}
...
...
spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/StandardLayers.java
View file @
34e60265
...
...
@@ -26,6 +26,8 @@ import java.util.stream.Stream;
* Base class for the standard set of {@link Layers}. Defines the following layers:
* <ol>
* <li>"dependencies" - For non snapshot dependencies</li>
* <li>"spring-boot-loader" - For classes from {@code spring-boot-loader} used to launch a
* fat jar</li>
* <li>"snapshot-dependencies" - For snapshot dependencies</li>
* <li>"application" - For application classes and resources</li>
* </ol>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment