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
pull/1779/head
Phillip Webb 10 years ago
parent 3c6c1d08e0
commit e0a0af436f

@ -48,6 +48,8 @@ public class SpringBootPluginExtension {
DIR(new Layouts.Expanded()),
MODULE(new Layouts.Module()),
NONE(new Layouts.None());
Layout layout;

@ -44,4 +44,9 @@ public interface Layout {
*/
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() {
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;
}
}
}

@ -177,7 +177,7 @@ public class Repackager {
}
});
if (!(this.layout instanceof Layouts.None)) {
if (this.layout.isExecutable()) {
writer.writeLoaderClasses();
}
}

@ -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/"));
}
}

@ -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 @@
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 {
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() {

@ -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 {
}
}
}

Loading…
Cancel
Save