diff --git a/spring-boot-tools/spring-boot-gradle-plugin/src/main/groovy/org/springframework/boot/gradle/SpringBootPluginExtension.groovy b/spring-boot-tools/spring-boot-gradle-plugin/src/main/groovy/org/springframework/boot/gradle/SpringBootPluginExtension.groovy index bac7f934ef..86abbc3a74 100644 --- a/spring-boot-tools/spring-boot-gradle-plugin/src/main/groovy/org/springframework/boot/gradle/SpringBootPluginExtension.groovy +++ b/spring-boot-tools/spring-boot-gradle-plugin/src/main/groovy/org/springframework/boot/gradle/SpringBootPluginExtension.groovy @@ -48,6 +48,8 @@ public class SpringBootPluginExtension { DIR(new Layouts.Expanded()), + MODULE(new Layouts.Module()), + NONE(new Layouts.None()); Layout layout; diff --git a/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Layout.java b/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Layout.java index 07323cdef1..8d70c55864 100644 --- a/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Layout.java +++ b/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Layout.java @@ -44,4 +44,9 @@ public interface Layout { */ String getClassesLocation(); + /** + * Returns if loader classes should be included to make the archive executable. + */ + boolean isExecutable(); + } diff --git a/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Layouts.java b/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Layouts.java index 64291d8443..fe38cb383a 100644 --- a/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Layouts.java +++ b/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Layouts.java @@ -69,6 +69,12 @@ public class Layouts { public String getClassesLocation() { return ""; } + + @Override + public boolean isExecutable() { + return true; + } + } /** @@ -84,7 +90,7 @@ public class Layouts { } /** - * Executable expanded archive layout. + * No layout. */ public static class None extends Jar { @@ -92,6 +98,12 @@ public class Layouts { public String getLauncherClassName() { return null; } + + @Override + public boolean isExecutable() { + return false; + } + } /** @@ -122,6 +134,42 @@ public class Layouts { public String getClassesLocation() { return "WEB-INF/classes/"; } + + @Override + public boolean isExecutable() { + return true; + } + + } + + /** + * Module layout (designed to be used as a "plug-in") + */ + public static class Module implements Layout { + + @Override + public String getLauncherClassName() { + return null; + } + + @Override + public String getLibraryDestination(String libraryName, LibraryScope scope) { + if (LibraryScope.COMPILE.equals(scope) || LibraryScope.RUNTIME.equals(scope)) { + return "lib/"; + } + return null; + } + + @Override + public String getClassesLocation() { + return ""; + } + + @Override + public boolean isExecutable() { + return false; + } + } } diff --git a/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Repackager.java b/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Repackager.java index de3dddc09c..7c826d73bf 100644 --- a/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Repackager.java +++ b/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Repackager.java @@ -177,7 +177,7 @@ public class Repackager { } }); - if (!(this.layout instanceof Layouts.None)) { + if (this.layout.isExecutable()) { writer.writeLoaderClasses(); } } diff --git a/spring-boot-tools/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/LayoutsTests.java b/spring-boot-tools/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/LayoutsTests.java index dc7f0d4fca..95b4ac4efe 100644 --- a/spring-boot-tools/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/LayoutsTests.java +++ b/spring-boot-tools/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/LayoutsTests.java @@ -24,6 +24,7 @@ import org.junit.rules.ExpectedException; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.nullValue; import static org.junit.Assert.assertThat; /** @@ -81,4 +82,15 @@ public class LayoutsTests { equalTo("WEB-INF/lib/")); } + @Test + public void moduleLayout() throws Exception { + Layout layout = new Layouts.Module(); + assertThat(layout.getLibraryDestination("lib.jar", LibraryScope.COMPILE), + equalTo("lib/")); + assertThat(layout.getLibraryDestination("lib.jar", LibraryScope.PROVIDED), + nullValue()); + assertThat(layout.getLibraryDestination("lib.jar", LibraryScope.RUNTIME), + equalTo("lib/")); + } + } diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/it/module/pom.xml b/spring-boot-tools/spring-boot-maven-plugin/src/it/module/pom.xml new file mode 100644 index 0000000000..7c78404a8b --- /dev/null +++ b/spring-boot-tools/spring-boot-maven-plugin/src/it/module/pom.xml @@ -0,0 +1,48 @@ + + + 4.0.0 + org.springframework.boot.maven.it + module + 0.0.1.BUILD-SNAPSHOT + + UTF-8 + + + + + @project.groupId@ + @project.artifactId@ + @project.version@ + + + + repackage + + + MODULE + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + + + + org.springframework + spring-context + @spring.version@ + + + javax.servlet + javax.servlet-api + @servlet-api.version@ + provided + + + diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/it/module/src/main/java/org/test/SampleModule.java b/spring-boot-tools/spring-boot-maven-plugin/src/it/module/src/main/java/org/test/SampleModule.java new file mode 100644 index 0000000000..e71223375d --- /dev/null +++ b/spring-boot-tools/spring-boot-maven-plugin/src/it/module/src/main/java/org/test/SampleModule.java @@ -0,0 +1,5 @@ +package org.test; + +public class SampleModule { + +} diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/it/module/verify.groovy b/spring-boot-tools/spring-boot-maven-plugin/src/it/module/verify.groovy new file mode 100644 index 0000000000..3f52437add --- /dev/null +++ b/spring-boot-tools/spring-boot-maven-plugin/src/it/module/verify.groovy @@ -0,0 +1,5 @@ +import java.io.*; +import org.springframework.boot.maven.*; + +Verify.verifyModule(new File( basedir, "target/module-0.0.1.BUILD-SNAPSHOT.jar" )); + diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RepackageMojo.java b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RepackageMojo.java index a46a281846..fee5481c32 100644 --- a/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RepackageMojo.java +++ b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RepackageMojo.java @@ -191,8 +191,37 @@ public class RepackageMojo extends AbstractDependencyFilterMojo { } public static enum LayoutType { - JAR(new Layouts.Jar()), WAR(new Layouts.War()), ZIP(new Layouts.Expanded()), DIR( - new Layouts.Expanded()), NONE(new Layouts.None()); + + /** + * Jar Layout + */ + JAR(new Layouts.Jar()), + + /** + * War Layout + */ + WAR(new Layouts.War()), + + /** + * Zip Layout + */ + ZIP(new Layouts.Expanded()), + + /** + * Dir Layout + */ + DIR(new Layouts.Expanded()), + + /** + * Module Layout + */ + MODULE(new Layouts.Module()), + + /** + * No Layout + */ + NONE(new Layouts.None()); + private final Layout layout; public Layout layout() { diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/test/java/org/springframework/boot/maven/Verify.java b/spring-boot-tools/spring-boot-maven-plugin/src/test/java/org/springframework/boot/maven/Verify.java index 53c20e8432..d4a86375fa 100644 --- a/spring-boot-tools/spring-boot-maven-plugin/src/test/java/org/springframework/boot/maven/Verify.java +++ b/spring-boot-tools/spring-boot-maven-plugin/src/test/java/org/springframework/boot/maven/Verify.java @@ -27,6 +27,7 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; /** @@ -54,6 +55,10 @@ public class Verify { new ZipArchiveVerification(file).verify(); } + public static void verifyModule(File file) throws Exception { + new ModuleArchiveVerification(file).verify(); + } + public static class ArchiveVerifier { private final ZipFile zipFile; @@ -235,4 +240,28 @@ public class Verify { } } + private static class ModuleArchiveVerification extends AbstractArchiveVerification { + + public ModuleArchiveVerification(File file) { + super(file); + } + + @Override + protected void verifyZipEntries(ArchiveVerifier verifier) throws Exception { + super.verifyZipEntries(verifier); + verifier.assertHasEntryNameStartingWith("lib/spring-context"); + verifier.assertHasEntryNameStartingWith("lib/spring-core"); + verifier.assertHasNoEntryNameStartingWith("lib/javax.servlet-api-3"); + assertFalse("Unpacked launcher classes", verifier.hasEntry("org/" + + "springframework/boot/loader/JarLauncher.class")); + assertTrue("Own classes", verifier.hasEntry("org/" + + "test/SampleModule.class")); + } + + @Override + protected void verifyManifest(Manifest manifest) throws Exception { + } + + } + }