Skip to content

Commit 542896b

Browse files
author
Dave Syer
committed
Support for non-executable JAR in addition to the repackaged one
Stretches the Gradle boot plugin a bit, so there's a sample build in the "profile" sample. Howto docs give examples. Fixes gh-1135
1 parent 1b97e8d commit 542896b

File tree

6 files changed

+259
-29
lines changed

6 files changed

+259
-29
lines changed

spring-boot-docs/src/main/asciidoc/build-tool-plugins.adoc

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,10 @@ The following configuration options are available:
404404
|===
405405
|Name |Description
406406

407+
|`enabled`
408+
|Boolean flag to switch the repackager off (sometimes useful if you
409+
want the other Boot features but not this one)
410+
407411
|`mainClass`
408412
|The main class that should be run. If not specified the `mainClassName` project property
409413
will be used or, if the no `mainClassName` id defined the archive will be searched for a
@@ -419,9 +423,10 @@ The following configuration options are available:
419423
the original jar as a dependency in another project, it's best to use an extension to
420424
define the executable archive.
421425

422-
|`withJarTask`
423-
|The name of the `Jar` task (defaults to all) which is used to locate the archive to
424-
repackage.
426+
|`withJarTask`
427+
|The name or value of the `Jar` task (defaults to all
428+
tasks of type `Jar`) which is used to locate the archive to
429+
repackage.
425430

426431
|`customConfiguration`
427432
|The name of the custom configuration whuch is used to populate the nested lib directory

spring-boot-docs/src/main/asciidoc/howto.adoc

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1579,6 +1579,122 @@ See the {spring-boot-maven-plugin-site}/usage.html[plugin documentation] for ful
15791579
details.
15801580

15811581

1582+
[[howto-create-an-additional-executable-jar]]
1583+
=== Create an additional executable JAR
1584+
1585+
If you want to use your project as a library jar for other projects to
1586+
depend on, and in addition have an executable (e.g. demo) version of
1587+
it, you will want to configure the build in a slightly different way.
1588+
1589+
For Maven the normal JAR plugin and the Spring Boot plugin both have a
1590+
"classifier" configuration that you can add to create an additional JAR.
1591+
Example (using the Spring Boot Starter Parent to manage the plugin
1592+
versions and other configuration defaults):
1593+
1594+
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
1595+
----
1596+
<build>
1597+
<plugins>
1598+
<plugin>
1599+
<groupId>org.springframework.boot</groupId>
1600+
<artifactId>spring-boot-maven-plugin</artifactId>
1601+
<configuration>
1602+
<classifier>exec</classifier>
1603+
</configuration>
1604+
</plugin>
1605+
</plugins>
1606+
</build>
1607+
----
1608+
1609+
Two jars are produced, the default one, and an executable one using
1610+
the Boot plugin with classifier "exec".
1611+
1612+
For Gradle users the steps are similar. Example:
1613+
1614+
[source,groovy,indent=0,subs="verbatim,attributes"]
1615+
----
1616+
bootRepackage {
1617+
classifier = 'exec'
1618+
}
1619+
----
1620+
1621+
[[howto-create-a-nonexecutable-jar]]
1622+
=== Create a non-executable JAR with exclusions
1623+
1624+
Often if you have an executable and a non-executable jar
1625+
as biuld products, the executable version will have additional
1626+
configuration files that ar enot needed in a library jar. E.g. the
1627+
`application.yml` configuration file might excluded from the
1628+
non-executable JAR.
1629+
1630+
Here's how to do that in Maven
1631+
1632+
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
1633+
----
1634+
<build>
1635+
<plugins>
1636+
<plugin>
1637+
<groupId>org.springframework.boot</groupId>
1638+
<artifactId>spring-boot-maven-plugin</artifactId>
1639+
<configuration>
1640+
<classifier>exec</classifier>
1641+
</configuration>
1642+
</plugin>
1643+
<plugin>
1644+
<artifactId>maven-jar-plugin</artifactId>
1645+
<executions>
1646+
<execution>
1647+
<id>exec</id>
1648+
<phase>package</phase>
1649+
<goals>
1650+
<goal>jar</goal>
1651+
</goals>
1652+
<configuration>
1653+
<classifier>exec</classifier>
1654+
</configuration>
1655+
</execution>
1656+
<execution>
1657+
<phase>package</phase>
1658+
<goals>
1659+
<goal>jar</goal>
1660+
</goals>
1661+
<configuration>
1662+
<!-- Need this to ensure application.yml is excluded -->
1663+
<forceCreation>true</forceCreation>
1664+
<excludes>
1665+
<exclude>application.yml</exclude>
1666+
</excludes>
1667+
</configuration>
1668+
</execution>
1669+
</executions>
1670+
</plugin>
1671+
</plugins>
1672+
</build>
1673+
----
1674+
1675+
In Gradle you can create a new JAR archive with standard task DSL
1676+
features, and then have the `bootRepackage` task depend on that one
1677+
using its `withJarTask` property:
1678+
1679+
[source,groovy,indent=0,subs="verbatim,attributes"]
1680+
----
1681+
jar {
1682+
baseName = 'spring-boot-sample-profile'
1683+
version = '0.0.0'
1684+
excludes = ['**/application.yml']
1685+
}
1686+
1687+
task('execJar', type:Jar, dependsOn: 'jar') {
1688+
baseName = 'spring-boot-sample-profile'
1689+
version = '0.0.0'
1690+
classifier = 'exec'
1691+
from sourceSets.main.output
1692+
}
1693+
1694+
bootRepackage {
1695+
withJarTask = tasks['execJar']
1696+
}
1697+
----
15821698

15831699
[[howto-remote-debug-maven-run]]
15841700
=== Remote debug a Spring Boot application started with Maven
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
buildscript {
2+
ext {
3+
springBootVersion = '1.1.2.BUILD-SNAPSHOT'
4+
}
5+
repositories {
6+
// NOTE: You should declare only repositories that you need here
7+
mavenLocal()
8+
mavenCentral()
9+
maven { url "http://repo.spring.io/release" }
10+
maven { url "http://repo.spring.io/milestone" }
11+
maven { url "http://repo.spring.io/snapshot" }
12+
}
13+
dependencies {
14+
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
15+
}
16+
}
17+
18+
apply plugin: 'java'
19+
apply plugin: 'eclipse'
20+
apply plugin: 'idea'
21+
apply plugin: 'spring-boot'
22+
23+
jar {
24+
baseName = 'spring-boot-sample-profile'
25+
version = '0.0.0'
26+
excludes = ['**/application.yml']
27+
}
28+
29+
task('execJar', type:Jar, dependsOn: 'jar') {
30+
baseName = 'spring-boot-sample-profile'
31+
version = '0.0.0'
32+
classifier = 'exec'
33+
from sourceSets.main.output
34+
}
35+
36+
bootRepackage {
37+
withJarTask = tasks['execJar']
38+
}
39+
40+
repositories {
41+
// NOTE: You should declare only repositories that you need here
42+
mavenLocal()
43+
mavenCentral()
44+
maven { url "http://repo.spring.io/release" }
45+
maven { url "http://repo.spring.io/milestone" }
46+
maven { url "http://repo.spring.io/snapshot" }
47+
}
48+
49+
dependencies {
50+
compile("org.springframework.boot:spring-boot-starter")
51+
testCompile("org.springframework.boot:spring-boot-starter-test")
52+
}
53+
54+
task wrapper(type: Wrapper) {
55+
gradleVersion = '1.6'
56+
}

spring-boot-samples/spring-boot-sample-profile/pom.xml

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
34
<modelVersion>4.0.0</modelVersion>
45
<parent>
56
<!-- Your own application should inherit from spring-boot-starter-parent -->
@@ -34,6 +35,37 @@
3435
<plugin>
3536
<groupId>org.springframework.boot</groupId>
3637
<artifactId>spring-boot-maven-plugin</artifactId>
38+
<configuration>
39+
<classifier>exec</classifier>
40+
</configuration>
41+
</plugin>
42+
<plugin>
43+
<artifactId>maven-jar-plugin</artifactId>
44+
<executions>
45+
<execution>
46+
<id>exec</id>
47+
<phase>package</phase>
48+
<goals>
49+
<goal>jar</goal>
50+
</goals>
51+
<configuration>
52+
<classifier>exec</classifier>
53+
</configuration>
54+
</execution>
55+
<execution>
56+
<phase>package</phase>
57+
<goals>
58+
<goal>jar</goal>
59+
</goals>
60+
<configuration>
61+
<!-- Need this to ensure application.yml is excluded -->
62+
<forceCreation>true</forceCreation>
63+
<excludes>
64+
<exclude>application.yml</exclude>
65+
</excludes>
66+
</configuration>
67+
</execution>
68+
</executions>
3769
</plugin>
3870
</plugins>
3971
</build>

spring-boot-tools/spring-boot-gradle-plugin/src/main/groovy/org/springframework/boot/gradle/repackage/RepackagePluginFeatures.java

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,18 +50,22 @@ private void addRepackageTask(Project project) {
5050
+ "archives so that they can be executed from the command "
5151
+ "line using 'java -jar'");
5252
task.setGroup(BasePlugin.BUILD_GROUP);
53-
task.dependsOn(project.getConfigurations()
54-
.getByName(Dependency.ARCHIVES_CONFIGURATION).getAllArtifacts()
55-
.getBuildDependencies());
53+
task.dependsOn(project.getConfigurations().getByName(
54+
Dependency.ARCHIVES_CONFIGURATION).getAllArtifacts().getBuildDependencies());
5655
registerOutput(project, task);
5756
ensureTaskRunsOnAssembly(project, task);
5857
}
5958

6059
private void registerOutput(Project project, final RepackageTask task) {
6160
project.afterEvaluate(new Action<Project>() {
61+
6262
@Override
6363
public void execute(Project project) {
6464
project.getTasks().withType(Jar.class, new OutputAction(task));
65+
Object withJar = task.getWithJarTask();
66+
if (withJar!=null) {
67+
task.dependsOn(withJar);
68+
}
6569
}
6670
});
6771
}
@@ -74,8 +78,8 @@ private void ensureTaskRunsOnAssembly(Project project, Task task) {
7478
* Register BootRepackage so that we can use task {@code foo(type: BootRepackage)}.
7579
*/
7680
private void registerRepackageTaskProperty(Project project) {
77-
project.getExtensions().getExtraProperties()
78-
.set("BootRepackage", RepackageTask.class);
81+
project.getExtensions().getExtraProperties().set("BootRepackage",
82+
RepackageTask.class);
7983
}
8084

8185
private class OutputAction implements Action<Jar> {
@@ -115,8 +119,7 @@ private void setClassifier(Jar archive) {
115119
SpringBootPluginExtension.class);
116120
if (task.getClassifier() != null) {
117121
classifier = task.getClassifier();
118-
}
119-
else if (extension.getClassifier() != null) {
122+
} else if (extension.getClassifier() != null) {
120123
classifier = extension.getClassifier();
121124
}
122125
if (classifier != null) {

0 commit comments

Comments
 (0)