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 cd36bc8592..e031574119 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 @@ -38,7 +38,7 @@ import org.springframework.boot.loader.tools.Layouts public class SpringBootPluginExtension { static enum LayoutType { - JAR(new Layouts.Jar()), WAR(new Layouts.War()), ZIP(new Layouts.Expanded()), DIR(new Layouts.Expanded()); + JAR(new Layouts.Jar()), WAR(new Layouts.War()), ZIP(new Layouts.Expanded()), DIR(new Layouts.Expanded()), NONE(new Layouts.None()); Layout layout; private LayoutType(Layout layout) { this.layout = layout; 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 32ac121f60..70e97f1b05 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 @@ -25,6 +25,7 @@ import java.util.Map; * Common {@link Layout}s. * * @author Phillip Webb + * @author Dave Syer */ public class Layouts { @@ -82,6 +83,17 @@ public class Layouts { } + /** + * Executable expanded archive layout. + */ + public static class None extends Jar { + + @Override + public String getLauncherClassName() { + return null; + } + } + /** * Executable WAR layout. */ 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 87742d4d07..d243db39d2 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 @@ -172,12 +172,18 @@ public class Repackager { startClass = MainClassFinder.findMainClass(source, this.layout.getClassesLocation()); } - if (startClass == null) { - throw new IllegalStateException("Unable to find main class"); + String launcherClassName = this.layout.getLauncherClassName(); + if (launcherClassName != null) { + manifest.getMainAttributes() + .putValue(MAIN_CLASS_ATTRIBUTE, launcherClassName); + if (startClass == null) { + throw new IllegalStateException("Unable to find main class"); + } + manifest.getMainAttributes().putValue(START_CLASS_ATTRIBUTE, startClass); + } + else if (startClass != null) { + manifest.getMainAttributes().putValue(MAIN_CLASS_ATTRIBUTE, startClass); } - manifest.getMainAttributes().putValue(MAIN_CLASS_ATTRIBUTE, - this.layout.getLauncherClassName()); - manifest.getMainAttributes().putValue(START_CLASS_ATTRIBUTE, startClass); String bootVersion = getClass().getPackage().getImplementationVersion(); manifest.getMainAttributes().putValue(BOOT_VERSION_ATTRIBUTE, bootVersion); diff --git a/spring-boot-tools/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/RepackagerTests.java b/spring-boot-tools/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/RepackagerTests.java index 3cf4c69c4a..c2c4c9885e 100644 --- a/spring-boot-tools/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/RepackagerTests.java +++ b/spring-boot-tools/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/RepackagerTests.java @@ -138,6 +138,30 @@ public class RepackagerTests { new Repackager(this.testJarFile.getFile()).repackage(NO_LIBRARIES); } + @Test + public void noMainClassAndLayoutIsNone() throws Exception { + this.testJarFile.addClass("a/b/C.class", ClassWithMainMethod.class); + File file = this.testJarFile.getFile(); + Repackager repackager = new Repackager(file); + repackager.setLayout(new Layouts.None()); + repackager.repackage(file, NO_LIBRARIES); + Manifest actualManifest = getManifest(file); + assertThat(actualManifest.getMainAttributes().getValue("Main-Class"), + equalTo("a.b.C")); + } + + @Test + public void noMainClassAndLayoutIsNoneWithNoMain() throws Exception { + this.testJarFile.addClass("a/b/C.class", ClassWithoutMainMethod.class); + File file = this.testJarFile.getFile(); + Repackager repackager = new Repackager(file); + repackager.setLayout(new Layouts.None()); + repackager.repackage(file, NO_LIBRARIES); + Manifest actualManifest = getManifest(file); + assertThat(actualManifest.getMainAttributes().getValue("Main-Class"), + equalTo(null)); + } + @Test public void sameSourceAndDestinationWithBackup() throws Exception { this.testJarFile.addClass("a/b/C.class", ClassWithMainMethod.class); 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 aa020b47c4..447df033d0 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 @@ -36,7 +36,9 @@ import org.springframework.boot.loader.tools.Repackager; /** * MOJO that can can be used to repackage existing JAR and WAR archives so that they can - * be executed from the command line using {@literal java -jar}. + * be executed from the command line using {@literal java -jar}. With + * layout=NONE can also be used simply to package a JAR with nested + * dependencies (and no main class, so not executable). * * @author Phillip Webb * @author Dave Syer @@ -84,7 +86,7 @@ public class RepackageMojo extends AbstractMojo { private String mainClass; /** - * The layout to use (JAR, WAR, ZIP, DIR) in case it cannot be inferred. + * The layout to use (JAR, WAR, ZIP, DIR, NONE) in case it cannot be inferred. */ @Parameter private LayoutType layout; @@ -126,7 +128,7 @@ public class RepackageMojo extends AbstractMojo { public static enum LayoutType { JAR(new Layouts.Jar()), WAR(new Layouts.War()), ZIP(new Layouts.Expanded()), DIR( - new Layouts.Expanded()); + new Layouts.Expanded()), NONE(new Layouts.None()); private Layout layout; public Layout layout() {