Update JarCommand to use Repackager to add nested jars
Closes gh-2099
This commit is contained in:
@@ -56,10 +56,11 @@ import org.springframework.boot.cli.compiler.RepositoryConfigurationFactory;
|
||||
import org.springframework.boot.cli.compiler.grape.RepositoryConfiguration;
|
||||
import org.springframework.boot.cli.jar.PackagedSpringApplicationLauncher;
|
||||
import org.springframework.boot.loader.tools.JarWriter;
|
||||
import org.springframework.boot.loader.tools.Layout;
|
||||
import org.springframework.boot.loader.tools.Layouts;
|
||||
import org.springframework.boot.loader.tools.Libraries;
|
||||
import org.springframework.boot.loader.tools.Library;
|
||||
import org.springframework.boot.loader.tools.LibraryCallback;
|
||||
import org.springframework.boot.loader.tools.LibraryScope;
|
||||
import org.springframework.boot.loader.tools.Repackager;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -72,10 +73,6 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public class JarCommand extends OptionParsingCommand {
|
||||
|
||||
private static final Layout LAYOUT = new Layouts.Jar();
|
||||
|
||||
private static final byte[] ZIP_FILE_HEADER = new byte[] { 'P', 'K', 3, 4 };
|
||||
|
||||
public JarCommand() {
|
||||
super("jar", "Create a self-contained "
|
||||
+ "executable jar file from a Spring Groovy script",
|
||||
@@ -169,6 +166,7 @@ public class JarCommand extends OptionParsingCommand {
|
||||
private void writeJar(File file, Class<?>[] compiledClasses,
|
||||
List<MatchedResource> classpathEntries, List<URL> dependencies)
|
||||
throws FileNotFoundException, IOException, URISyntaxException {
|
||||
final List<Library> libraries;
|
||||
JarWriter writer = new JarWriter(file);
|
||||
try {
|
||||
addManifest(writer, compiledClasses);
|
||||
@@ -176,23 +174,39 @@ public class JarCommand extends OptionParsingCommand {
|
||||
for (Class<?> compiledClass : compiledClasses) {
|
||||
addClass(writer, compiledClass);
|
||||
}
|
||||
addClasspathEntries(writer, classpathEntries);
|
||||
addDependencies(writer, dependencies);
|
||||
writer.writeLoaderClasses();
|
||||
libraries = addClasspathEntries(writer, classpathEntries);
|
||||
}
|
||||
finally {
|
||||
writer.close();
|
||||
}
|
||||
libraries.addAll(createLibraries(dependencies));
|
||||
Repackager repackager = new Repackager(file);
|
||||
repackager.setMainClass(PackagedSpringApplicationLauncher.class.getName());
|
||||
repackager.repackage(new Libraries() {
|
||||
|
||||
@Override
|
||||
public void doWithLibraries(LibraryCallback callback) throws IOException {
|
||||
for (Library library : libraries) {
|
||||
callback.library(library);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private List<Library> createLibraries(List<URL> dependencies)
|
||||
throws URISyntaxException {
|
||||
List<Library> libraries = new ArrayList<Library>();
|
||||
for (URL dependency : dependencies) {
|
||||
File file = new File(dependency.toURI());
|
||||
libraries.add(new Library(file, LibraryScope.COMPILE));
|
||||
}
|
||||
return libraries;
|
||||
}
|
||||
|
||||
private void addManifest(JarWriter writer, Class<?>[] compiledClasses)
|
||||
throws IOException {
|
||||
Manifest manifest = new Manifest();
|
||||
manifest.getMainAttributes().putValue("Manifest-Version", "1.0");
|
||||
manifest.getMainAttributes().putValue("Main-Class",
|
||||
LAYOUT.getLauncherClassName());
|
||||
manifest.getMainAttributes().putValue("Start-Class",
|
||||
PackagedSpringApplicationLauncher.class.getName());
|
||||
manifest.getMainAttributes().putValue(
|
||||
PackagedSpringApplicationLauncher.SOURCE_ENTRY,
|
||||
commaDelimitedClassNames(compiledClasses));
|
||||
@@ -232,56 +246,19 @@ public class JarCommand extends OptionParsingCommand {
|
||||
writer.writeEntry(name, stream);
|
||||
}
|
||||
|
||||
private void addClasspathEntries(JarWriter writer, List<MatchedResource> entries)
|
||||
throws IOException {
|
||||
private List<Library> addClasspathEntries(JarWriter writer,
|
||||
List<MatchedResource> entries) throws IOException {
|
||||
List<Library> libraries = new ArrayList<Library>();
|
||||
for (MatchedResource entry : entries) {
|
||||
if (entry.isRoot()) {
|
||||
addDependency(writer, entry.getFile());
|
||||
libraries.add(new Library(entry.getFile(), LibraryScope.COMPILE));
|
||||
}
|
||||
else {
|
||||
writer.writeEntry(entry.getName(),
|
||||
new FileInputStream(entry.getFile()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addDependencies(JarWriter writer, List<URL> urls)
|
||||
throws IOException, URISyntaxException, FileNotFoundException {
|
||||
for (URL url : urls) {
|
||||
addDependency(writer, new File(url.toURI()));
|
||||
}
|
||||
}
|
||||
|
||||
private void addDependency(JarWriter writer, File dependency)
|
||||
throws FileNotFoundException, IOException {
|
||||
if (dependency.isFile() && isZip(dependency)) {
|
||||
writer.writeNestedLibrary("lib/", new Library(dependency,
|
||||
LibraryScope.COMPILE));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isZip(File file) {
|
||||
try {
|
||||
FileInputStream fileInputStream = new FileInputStream(file);
|
||||
try {
|
||||
return isZip(fileInputStream);
|
||||
}
|
||||
finally {
|
||||
fileInputStream.close();
|
||||
}
|
||||
}
|
||||
catch (IOException ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isZip(InputStream inputStream) throws IOException {
|
||||
for (int i = 0; i < ZIP_FILE_HEADER.length; i++) {
|
||||
if (inputStream.read() != ZIP_FILE_HEADER[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return libraries;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user