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
+
+
+
+ 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);
- }
- });
- }
-
- }
-
}