Add 'module' repacker layout
Add a 'module' layout for the repackager which includes all 'compile' and 'runtime' scope dependencies and does not require a main class. Fixes gh-1941
This commit is contained in:
		
							parent
							
								
									3c6c1d08e0
								
							
						
					
					
						commit
						e0a0af436f
					
				| 
						 | 
					@ -48,6 +48,8 @@ public class SpringBootPluginExtension {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		DIR(new Layouts.Expanded()),
 | 
							DIR(new Layouts.Expanded()),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							MODULE(new Layouts.Module()),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		NONE(new Layouts.None());
 | 
							NONE(new Layouts.None());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Layout layout;
 | 
							Layout layout;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,4 +44,9 @@ public interface Layout {
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	String getClassesLocation();
 | 
						String getClassesLocation();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Returns if loader classes should be included to make the archive executable.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						boolean isExecutable();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -69,6 +69,12 @@ public class Layouts {
 | 
				
			||||||
		public String getClassesLocation() {
 | 
							public String getClassesLocation() {
 | 
				
			||||||
			return "";
 | 
								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 {
 | 
						public static class None extends Jar {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -92,6 +98,12 @@ public class Layouts {
 | 
				
			||||||
		public String getLauncherClassName() {
 | 
							public String getLauncherClassName() {
 | 
				
			||||||
			return null;
 | 
								return null;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							@Override
 | 
				
			||||||
 | 
							public boolean isExecutable() {
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
| 
						 | 
					@ -122,6 +134,42 @@ public class Layouts {
 | 
				
			||||||
		public String getClassesLocation() {
 | 
							public String getClassesLocation() {
 | 
				
			||||||
			return "WEB-INF/classes/";
 | 
								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;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -177,7 +177,7 @@ public class Repackager {
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (!(this.layout instanceof Layouts.None)) {
 | 
								if (this.layout.isExecutable()) {
 | 
				
			||||||
				writer.writeLoaderClasses();
 | 
									writer.writeLoaderClasses();
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,6 +24,7 @@ import org.junit.rules.ExpectedException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import static org.hamcrest.Matchers.equalTo;
 | 
					import static org.hamcrest.Matchers.equalTo;
 | 
				
			||||||
import static org.hamcrest.Matchers.instanceOf;
 | 
					import static org.hamcrest.Matchers.instanceOf;
 | 
				
			||||||
 | 
					import static org.hamcrest.Matchers.nullValue;
 | 
				
			||||||
import static org.junit.Assert.assertThat;
 | 
					import static org.junit.Assert.assertThat;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -81,4 +82,15 @@ public class LayoutsTests {
 | 
				
			||||||
				equalTo("WEB-INF/lib/"));
 | 
									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/"));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,48 @@
 | 
				
			||||||
 | 
					<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
 | 
					<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">
 | 
				
			||||||
 | 
						<modelVersion>4.0.0</modelVersion>
 | 
				
			||||||
 | 
						<groupId>org.springframework.boot.maven.it</groupId>
 | 
				
			||||||
 | 
						<artifactId>module</artifactId>
 | 
				
			||||||
 | 
						<version>0.0.1.BUILD-SNAPSHOT</version>
 | 
				
			||||||
 | 
						<properties>
 | 
				
			||||||
 | 
							<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 | 
				
			||||||
 | 
						</properties>
 | 
				
			||||||
 | 
						<build>
 | 
				
			||||||
 | 
							<plugins>
 | 
				
			||||||
 | 
								<plugin>
 | 
				
			||||||
 | 
									<groupId>@project.groupId@</groupId>
 | 
				
			||||||
 | 
									<artifactId>@project.artifactId@</artifactId>
 | 
				
			||||||
 | 
									<version>@project.version@</version>
 | 
				
			||||||
 | 
									<executions>
 | 
				
			||||||
 | 
										<execution>
 | 
				
			||||||
 | 
											<goals>
 | 
				
			||||||
 | 
												<goal>repackage</goal>
 | 
				
			||||||
 | 
											</goals>
 | 
				
			||||||
 | 
											<configuration>
 | 
				
			||||||
 | 
												<layout>MODULE</layout>
 | 
				
			||||||
 | 
											</configuration>
 | 
				
			||||||
 | 
										</execution>
 | 
				
			||||||
 | 
									</executions>
 | 
				
			||||||
 | 
								</plugin>
 | 
				
			||||||
 | 
								<plugin>
 | 
				
			||||||
 | 
									<groupId>org.apache.maven.plugins</groupId>
 | 
				
			||||||
 | 
									<artifactId>maven-jar-plugin</artifactId>
 | 
				
			||||||
 | 
									<version>2.4</version>
 | 
				
			||||||
 | 
								</plugin>
 | 
				
			||||||
 | 
							</plugins>
 | 
				
			||||||
 | 
						</build>
 | 
				
			||||||
 | 
						<dependencies>
 | 
				
			||||||
 | 
							<dependency>
 | 
				
			||||||
 | 
								<groupId>org.springframework</groupId>
 | 
				
			||||||
 | 
								<artifactId>spring-context</artifactId>
 | 
				
			||||||
 | 
								<version>@spring.version@</version>
 | 
				
			||||||
 | 
							</dependency>
 | 
				
			||||||
 | 
							<dependency>
 | 
				
			||||||
 | 
								<groupId>javax.servlet</groupId>
 | 
				
			||||||
 | 
								<artifactId>javax.servlet-api</artifactId>
 | 
				
			||||||
 | 
								<version>@servlet-api.version@</version>
 | 
				
			||||||
 | 
								<scope>provided</scope>
 | 
				
			||||||
 | 
							</dependency>
 | 
				
			||||||
 | 
						</dependencies>
 | 
				
			||||||
 | 
					</project>
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,5 @@
 | 
				
			||||||
 | 
					package org.test;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class SampleModule {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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" ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -191,8 +191,37 @@ public class RepackageMojo extends AbstractDependencyFilterMojo {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public static enum LayoutType {
 | 
						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;
 | 
							private final Layout layout;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public Layout layout() {
 | 
							public Layout layout() {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,6 +27,7 @@ import java.util.zip.ZipEntry;
 | 
				
			||||||
import java.util.zip.ZipFile;
 | 
					import java.util.zip.ZipFile;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import static org.junit.Assert.assertEquals;
 | 
					import static org.junit.Assert.assertEquals;
 | 
				
			||||||
 | 
					import static org.junit.Assert.assertFalse;
 | 
				
			||||||
import static org.junit.Assert.assertTrue;
 | 
					import static org.junit.Assert.assertTrue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -54,6 +55,10 @@ public class Verify {
 | 
				
			||||||
		new ZipArchiveVerification(file).verify();
 | 
							new ZipArchiveVerification(file).verify();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public static void verifyModule(File file) throws Exception {
 | 
				
			||||||
 | 
							new ModuleArchiveVerification(file).verify();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public static class ArchiveVerifier {
 | 
						public static class ArchiveVerifier {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private final ZipFile zipFile;
 | 
							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 {
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue