diff --git a/spring-boot-tools/spring-boot-loader/src/it/executable-props-lib/loader.properties b/spring-boot-tools/spring-boot-loader/src/it/executable-props-lib/loader.properties new file mode 100644 index 0000000000..1099d67456 --- /dev/null +++ b/spring-boot-tools/spring-boot-loader/src/it/executable-props-lib/loader.properties @@ -0,0 +1 @@ +loader.path=jar:file:../executable-props/target/executable-props-0.0.1.BUILD-SNAPSHOT-full.jar/!BOOT-INF/lib \ No newline at end of file diff --git a/spring-boot-tools/spring-boot-loader/src/it/executable-props-lib/pom.xml b/spring-boot-tools/spring-boot-loader/src/it/executable-props-lib/pom.xml new file mode 100644 index 0000000000..972dfb4649 --- /dev/null +++ b/spring-boot-tools/spring-boot-loader/src/it/executable-props-lib/pom.xml @@ -0,0 +1,82 @@ + + + 4.0.0 + org.springframework.boot.launcher.it + executable-props-lib + 0.0.1.BUILD-SNAPSHOT + + UTF-8 + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + 1.6 + 1.6 + + + + org.apache.maven.plugins + maven-dependency-plugin + 2.10 + + + unpack + prepare-package + + unpack + + + + + @project.groupId@ + @project.artifactId@ + @project.version@ + jar + + + ${project.build.directory}/assembly + + + + + + maven-assembly-plugin + 2.4 + + + src/main/assembly/jar-with-dependencies.xml + + + + org.springframework.boot.loader.PropertiesLauncher + + + org.springframework.boot.load.it.props.EmbeddedJarStarter + + + + + + jar-with-dependencies + package + + single + + + + + + + + + org.springframework + spring-context + 4.1.4.RELEASE + + + diff --git a/spring-boot-tools/spring-boot-loader/src/it/executable-props-lib/src/main/assembly/jar-with-dependencies.xml b/spring-boot-tools/spring-boot-loader/src/it/executable-props-lib/src/main/assembly/jar-with-dependencies.xml new file mode 100644 index 0000000000..1120acb7e2 --- /dev/null +++ b/spring-boot-tools/spring-boot-loader/src/it/executable-props-lib/src/main/assembly/jar-with-dependencies.xml @@ -0,0 +1,27 @@ + + + full + + jar + + false + + + + + ${project.groupId}:${project.artifactId} + + BOOT-INF/classes + true + + + + + ${project.build.directory}/assembly + / + + + diff --git a/spring-boot-tools/spring-boot-loader/src/it/executable-props-lib/src/main/resources/application.properties b/spring-boot-tools/spring-boot-loader/src/it/executable-props-lib/src/main/resources/application.properties new file mode 100644 index 0000000000..c11051e347 --- /dev/null +++ b/spring-boot-tools/spring-boot-loader/src/it/executable-props-lib/src/main/resources/application.properties @@ -0,0 +1 @@ +message: World \ No newline at end of file diff --git a/spring-boot-tools/spring-boot-loader/src/it/executable-props-lib/verify.groovy b/spring-boot-tools/spring-boot-loader/src/it/executable-props-lib/verify.groovy new file mode 100644 index 0000000000..ccb2e78f68 --- /dev/null +++ b/spring-boot-tools/spring-boot-loader/src/it/executable-props-lib/verify.groovy @@ -0,0 +1,17 @@ +def jarfile = './target/executable-props-lib-0.0.1.BUILD-SNAPSHOT-full.jar' + +new File("${basedir}/application.properties").delete() + +String exec(String command) { + def proc = command.execute([], basedir) + proc.waitFor() + proc.err.text +} + +String out = exec("java -jar ${jarfile}") +assert out.contains('Hello Embedded World!'), + 'Using -jar my.jar should use the application.properties from the jar\n' + out + +out = exec("java -cp ${jarfile} org.springframework.boot.loader.PropertiesLauncher") +assert out.contains('Hello Embedded World!'), + 'Using -cp my.jar with PropertiesLauncher should use the application.properties from the jar\n' + out diff --git a/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/PropertiesLauncher.java b/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/PropertiesLauncher.java index 083f639214..01253279ac 100755 --- a/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/PropertiesLauncher.java +++ b/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/PropertiesLauncher.java @@ -21,12 +21,10 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; -import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; import java.util.Collections; -import java.util.Iterator; import java.util.List; import java.util.Properties; import java.util.jar.Manifest; @@ -469,10 +467,10 @@ public class PropertiesLauncher extends Launcher { debug("Adding classpath entries from archive " + archive.getUrl() + root); lib.add(archive); } - Archive nested = getNestedArchive(root); - if (nested != null) { + List nestedArchives = getNestedArchives(root); + if (nestedArchives != null) { debug("Adding classpath entries from nested " + root); - lib.add(nested); + lib.addAll(nestedArchives); } return lib; } @@ -490,19 +488,24 @@ public class PropertiesLauncher extends Launcher { return null; } - private Archive getNestedArchive(String root) throws Exception { + private List getNestedArchives(String root) throws Exception { if (root.startsWith("/") || this.parent.getUrl().equals(this.home.toURI().toURL())) { // If home dir is same as parent archive, no need to add it twice. return null; } - EntryFilter filter = new PrefixMatchingArchiveFilter(root); - if (this.parent.getNestedArchives(filter).isEmpty()) { - return null; + Archive parent = this.parent; + if (root.startsWith("jar:file:") && root.contains("!")) { + int index = root.indexOf("!"); + String file = root.substring("jar:file:".length(), index); + parent = new JarFileArchive(new File(file)); + root = root.substring(index + 1, root.length()); + while (root.startsWith("/")) { + root = root.substring(1); + } } - // If there are more archives nested in this subdirectory (root) then create a new - // virtual archive for them, and have it added to the classpath - return new FilteredArchive(this.parent, filter); + EntryFilter filter = new PrefixMatchingArchiveFilter(root); + return parent.getNestedArchives(filter); } private void addNestedEntries(List lib) { @@ -626,47 +629,4 @@ public class PropertiesLauncher extends Launcher { } - /** - * Decorator to apply an {@link Archive.EntryFilter} to an existing {@link Archive}. - */ - private static class FilteredArchive implements Archive { - - private final Archive parent; - - private final EntryFilter filter; - - FilteredArchive(Archive parent, EntryFilter filter) { - this.parent = parent; - this.filter = filter; - } - - @Override - public URL getUrl() throws MalformedURLException { - return this.parent.getUrl(); - } - - @Override - public Manifest getManifest() throws IOException { - return this.parent.getManifest(); - } - - @Override - public Iterator iterator() { - throw new UnsupportedOperationException(); - } - - @Override - public List getNestedArchives(final EntryFilter filter) - throws IOException { - return this.parent.getNestedArchives(new EntryFilter() { - @Override - public boolean matches(Entry entry) { - return FilteredArchive.this.filter.matches(entry) - && filter.matches(entry); - } - }); - } - - } - }