Support for custom layout types to change loader classes
A layout can also optionally change the loader jar that is unpacked in the root of the repackaged archive by implementing a new method in Layout.
This commit is contained in:
parent
500a3df6e9
commit
537e0c12c2
|
@ -493,7 +493,7 @@ The following configuration options are available:
|
||||||
|
|
||||||
|
|
||||||
[[build-tool-plugins-gradle-configuration-layouts]]
|
[[build-tool-plugins-gradle-configuration-layouts]]
|
||||||
==== Available layouts
|
==== Available built-in layouts
|
||||||
|
|
||||||
The `layout` attribute configures the format of the archive and whether the bootstrap
|
The `layout` attribute configures the format of the archive and whether the bootstrap
|
||||||
loader should be included or not. The following layouts are available:
|
loader should be included or not. The following layouts are available:
|
||||||
|
@ -530,6 +530,37 @@ loader should be included or not. The following layouts are available:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[[build-tool-plugins-gradle-configuration-custom-layout]]
|
||||||
|
==== Using a custom layout
|
||||||
|
If you have custom requirements for how to arrange the dependencies and loader classes
|
||||||
|
inside the repackaged jar, you can use a custom layout in addition to the built-in values.
|
||||||
|
Any library which defines one or more `LayoutFactory` implementations and
|
||||||
|
lists them in `META-INF/spring.factories` can be added to the build script dependencies
|
||||||
|
and then the layout type becomes available in the `springBoot` configuration. For example
|
||||||
|
|
||||||
|
[source,groovy,indent=0,subs="verbatim,attributes"]
|
||||||
|
----
|
||||||
|
buildscript {
|
||||||
|
ext {
|
||||||
|
springBootVersion = '1.5.0.BUILD-SNAPSHOT'
|
||||||
|
customVersion = '0.0.1.BUILD-SNAPSHOT'
|
||||||
|
}
|
||||||
|
repositories {
|
||||||
|
mavenLocal()
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath("com.example:custom-layout:${customVersion}")
|
||||||
|
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
springBoot {
|
||||||
|
layout = 'CUSTOM'
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
[[build-tool-plugins-understanding-the-gradle-plugin]]
|
[[build-tool-plugins-understanding-the-gradle-plugin]]
|
||||||
=== Understanding how the Gradle plugin works
|
=== Understanding how the Gradle plugin works
|
||||||
When `spring-boot` is applied to your Gradle project a default task named `bootRepackage`
|
When `spring-boot` is applied to your Gradle project a default task named `bootRepackage`
|
||||||
|
|
|
@ -20,6 +20,8 @@ import java.io.File;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import groovy.lang.Closure;
|
||||||
|
|
||||||
import org.gradle.api.Project;
|
import org.gradle.api.Project;
|
||||||
import org.gradle.api.plugins.JavaPlugin;
|
import org.gradle.api.plugins.JavaPlugin;
|
||||||
|
|
||||||
|
@ -27,8 +29,6 @@ import org.springframework.boot.gradle.buildinfo.BuildInfo;
|
||||||
import org.springframework.boot.loader.tools.Layout;
|
import org.springframework.boot.loader.tools.Layout;
|
||||||
import org.springframework.boot.loader.tools.LayoutType;
|
import org.springframework.boot.loader.tools.LayoutType;
|
||||||
|
|
||||||
import groovy.lang.Closure;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gradle DSL Extension for 'Spring Boot'. Most of the time Spring Boot can guess the
|
* Gradle DSL Extension for 'Spring Boot'. Most of the time Spring Boot can guess the
|
||||||
* settings in this extension, but occasionally you might need to explicitly set one or
|
* settings in this extension, but occasionally you might need to explicitly set one or
|
||||||
|
|
|
@ -53,8 +53,6 @@ import org.springframework.lang.UsesJava7;
|
||||||
*/
|
*/
|
||||||
public class JarWriter {
|
public class JarWriter {
|
||||||
|
|
||||||
private static final String NESTED_LOADER_JAR = "META-INF/loader/spring-boot-loader.jar";
|
|
||||||
|
|
||||||
private static final int BUFFER_SIZE = 32 * 1024;
|
private static final int BUFFER_SIZE = 32 * 1024;
|
||||||
|
|
||||||
private final JarOutputStream jarOutput;
|
private final JarOutputStream jarOutput;
|
||||||
|
@ -206,9 +204,20 @@ public class JarWriter {
|
||||||
/**
|
/**
|
||||||
* Write the required spring-boot-loader classes to the JAR.
|
* Write the required spring-boot-loader classes to the JAR.
|
||||||
* @throws IOException if the classes cannot be written
|
* @throws IOException if the classes cannot be written
|
||||||
|
* @deprecated us {@link #writeLoaderClasses(String)} instead
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public void writeLoaderClasses() throws IOException {
|
public void writeLoaderClasses() throws IOException {
|
||||||
URL loaderJar = getClass().getClassLoader().getResource(NESTED_LOADER_JAR);
|
writeLoaderClasses(Layouts.DEFAULT_LOADER_JAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write the required spring-boot-loader classes to the JAR.
|
||||||
|
* @param loaderJarPath the path to the loader jar (in the classpath)
|
||||||
|
* @throws IOException if the classes cannot be written
|
||||||
|
*/
|
||||||
|
public void writeLoaderClasses(String loaderJarPath) throws IOException {
|
||||||
|
URL loaderJar = getClass().getClassLoader().getResource(loaderJarPath);
|
||||||
JarInputStream inputStream = new JarInputStream(
|
JarInputStream inputStream = new JarInputStream(
|
||||||
new BufferedInputStream(loaderJar.openStream()));
|
new BufferedInputStream(loaderJar.openStream()));
|
||||||
JarEntry entry;
|
JarEntry entry;
|
||||||
|
|
|
@ -40,15 +40,25 @@ public interface Layout {
|
||||||
String getLibraryDestination(String libraryName, LibraryScope scope);
|
String getLibraryDestination(String libraryName, LibraryScope scope);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the location of classes within the archive.
|
* Returns the location of classes within the archive. Empty if the location is the
|
||||||
|
* root path, otherwise ends with a slash ('/').
|
||||||
* @return the classes location
|
* @return the classes location
|
||||||
*/
|
*/
|
||||||
String getClassesLocation();
|
String getClassesLocation();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns if loader classes should be included to make the archive executable.
|
* Returns if loader classes should be included to make the archive executable. If
|
||||||
|
* true, then {@link #getLoaderJarPath()} should point to a valid jar file that
|
||||||
|
* contains the loader classes.
|
||||||
* @return if the layout is executable
|
* @return if the layout is executable
|
||||||
*/
|
*/
|
||||||
boolean isExecutable();
|
boolean isExecutable();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the path to a nested jar that contains the loader, and which will be
|
||||||
|
* unpacked into the root of the repackaged jar.
|
||||||
|
* @return the path to a nested jar that contains the loader
|
||||||
|
*/
|
||||||
|
String getLoaderJarPath();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,8 @@ import org.springframework.core.io.support.SpringFactoriesLoader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Archive layout types.
|
* Archive layout types.
|
||||||
|
*
|
||||||
|
* @author Dave Syer
|
||||||
*/
|
*/
|
||||||
public enum LayoutType {
|
public enum LayoutType {
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,11 @@ import java.util.Set;
|
||||||
*/
|
*/
|
||||||
public final class Layouts {
|
public final class Layouts {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default value for {@link #getLoaderJarPath()}.
|
||||||
|
*/
|
||||||
|
public static final String DEFAULT_LOADER_JAR = "META-INF/loader/spring-boot-loader.jar";
|
||||||
|
|
||||||
private Layouts() {
|
private Layouts() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,6 +92,11 @@ public final class Layouts {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLoaderJarPath() {
|
||||||
|
return DEFAULT_LOADER_JAR;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -116,6 +126,11 @@ public final class Layouts {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLoaderJarPath() {
|
||||||
|
return DEFAULT_LOADER_JAR;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -154,6 +169,11 @@ public final class Layouts {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLoaderJarPath() {
|
||||||
|
return DEFAULT_LOADER_JAR;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -188,6 +208,11 @@ public final class Layouts {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLoaderJarPath() {
|
||||||
|
return DEFAULT_LOADER_JAR;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -217,7 +217,7 @@ public class Repackager {
|
||||||
}
|
}
|
||||||
writeNestedLibraries(standardLibraries, seen, writer);
|
writeNestedLibraries(standardLibraries, seen, writer);
|
||||||
if (this.layout.isExecutable()) {
|
if (this.layout.isExecutable()) {
|
||||||
writer.writeLoaderClasses();
|
writer.writeLoaderClasses(this.layout.getLoaderJarPath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
|
|
@ -28,7 +28,8 @@ public class LayoutTypeTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void standardType() {
|
public void standardType() {
|
||||||
assertThat(LayoutType.layout("DIR")).isEqualTo(LayoutType.valueOf("DIR").layout());
|
assertThat(LayoutType.layout("DIR"))
|
||||||
|
.isEqualTo(LayoutType.valueOf("DIR").layout());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -46,6 +47,7 @@ public class LayoutTypeTests {
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return "CUSTOM";
|
return "CUSTOM";
|
||||||
}}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -227,6 +227,7 @@ public class RepackageMojo extends AbstractDependencyFilterMojo {
|
||||||
repackager.setMainClass(this.mainClass);
|
repackager.setMainClass(this.mainClass);
|
||||||
if (this.layout != null) {
|
if (this.layout != null) {
|
||||||
getLog().info("Layout: " + this.layout);
|
getLog().info("Layout: " + this.layout);
|
||||||
|
repackager.setLayout(LayoutType.layout(this.layout));
|
||||||
}
|
}
|
||||||
return repackager;
|
return repackager;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
-----
|
||||||
|
Use a custom layout
|
||||||
|
-----
|
||||||
|
Dave Syer
|
||||||
|
-----
|
||||||
|
2016-10-30
|
||||||
|
-----
|
||||||
|
|
||||||
|
Spring Boot repackages the jar file for this project using a custom
|
||||||
|
layout defined in the additional jar file, provided as a dependency
|
||||||
|
to the build plugin:
|
||||||
|
|
||||||
|
---
|
||||||
|
<project>
|
||||||
|
...
|
||||||
|
<build>
|
||||||
|
...
|
||||||
|
<plugins>
|
||||||
|
...
|
||||||
|
<plugin>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>${project.artifactId}</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>repackage</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<layout>CUSTOM</layout>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.example</groupid>
|
||||||
|
<artifactId>custom-layout</artifactId>
|
||||||
|
<version>0.0.1.BUILD-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
...
|
||||||
|
</plugin>
|
||||||
|
...
|
||||||
|
</plugins>
|
||||||
|
...
|
||||||
|
</build>
|
||||||
|
...
|
||||||
|
</project>
|
||||||
|
---
|
||||||
|
|
||||||
|
The layout is provided as an implementation of <<LayoutFactory>>
|
||||||
|
(from spring-boot-loader-tools) listed in
|
||||||
|
<<META-INF/spring-factories>> inside the <<custom-layout>> jar.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,8 @@ Spring Boot Maven Plugin
|
||||||
|
|
||||||
* {{{./examples/repackage-disable-attach.html}Local repackaged artifact}}
|
* {{{./examples/repackage-disable-attach.html}Local repackaged artifact}}
|
||||||
|
|
||||||
|
* {{{./examples/custom-layout.html}Custom layout}}
|
||||||
|
|
||||||
* {{{./examples/exclude-dependency.html}Exclude a dependency}}
|
* {{{./examples/exclude-dependency.html}Exclude a dependency}}
|
||||||
|
|
||||||
* {{{./examples/run-debug.html}Debug the application}}
|
* {{{./examples/run-debug.html}Debug the application}}
|
||||||
|
|
Loading…
Reference in New Issue