From b36c8a7c2405e29192376b77bbd87ac9e550a4d6 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 2 Mar 2017 10:30:50 +0000 Subject: [PATCH] Polish "Tighten up PropertiesLauncher's contract" See gh-8346 Closes gh-7221 --- .../appendix-executable-jar-format.adoc | 22 +++++--- .../boot/loader/PropertiesLauncher.java | 54 +++++++++---------- .../boot/loader/PropertiesLauncherTests.java | 2 +- .../BOOT-INF/classes/application.properties | 2 +- .../placeholders/META-INF/MANIFEST.MF | 2 + 5 files changed, 45 insertions(+), 37 deletions(-) create mode 100644 spring-boot-tools/spring-boot-loader/src/test/resources/placeholders/META-INF/MANIFEST.MF diff --git a/spring-boot-docs/src/main/asciidoc/appendix-executable-jar-format.adoc b/spring-boot-docs/src/main/asciidoc/appendix-executable-jar-format.adoc index 89c9514061..7a57cd6471 100644 --- a/spring-boot-docs/src/main/asciidoc/appendix-executable-jar-format.adoc +++ b/spring-boot-docs/src/main/asciidoc/appendix-executable-jar-format.adoc @@ -214,7 +214,10 @@ NOTE: `PropertiesLauncher` supports loading properties from just like a regular `-classpath` on the `javac` command line. |`loader.home` -|Used to resolve relative paths in `loader.path`. E.g. `loader.path=lib` then `${loader.home}/lib` is a classpath location (along with all jar files in that directory). Also used to locate a `loader.properties file`. Example `file:///opt/app` (defaults to `${user.dir}`). +|Used to resolve relative paths in `loader.path`. E.g. `loader.path=lib` then + `${loader.home}/lib` is a classpath location (along with all jar files in that + directory). Also used to locate a `loader.properties file`. Example `file:///opt/app` + (defaults to `${user.dir}`). |`loader.args` |Default arguments for the main method (space separated) @@ -271,21 +274,24 @@ TIP: Build plugins automatically move the `Main-Class` attribute to `Start-Class the fat jar is built. If you are using that, specify the name of the class to launch using the `Main-Class` attribute and leave out `Start-Class`. -* `loader.properties` are searched for in `loader.home` then in the root of the classpath, - then in `classpath:/BOOT-INF/classes`. The first location that exists is used. -* `loader.home` is only the directory location of an additional properties file (overriding - the default) as long as `loader.config.location` is not specified. +* `loader.properties` are searched for in `loader.home` then in the root of the + classpath, then in `classpath:/BOOT-INF/classes`. The first location that exists is + used. +* `loader.home` is only the directory location of an additional properties file + (overriding the default) as long as `loader.config.location` is not specified. * `loader.path` can contain directories (scanned recursively for jar and zip files), archive paths, or wildcard patterns (for the default JVM behavior). * `loader.path` (if empty) defaults to `BOOT-INF/lib` (meaning a local directory or a nested one if running from an archive). Because of this `PropertiesLauncher` behaves the same as `JarLauncher` when no additional configuration is provided. -* `loader.path` can not be used to configure the location of `loader.properties` (the classpath - used to search for the latter is the JVM classpath when `PropertiesLauncher` is launched). +* `loader.path` can not be used to configure the location of `loader.properties` (the + classpath used to search for the latter is the JVM classpath when `PropertiesLauncher` + is launched). * Placeholder replacement is done from System and environment variables plus the properties file itself on all values before use. * The search order for properties (where it makes sense to look in more than one place) - is env vars, system properties, `loader.properties`, exploded archive manifest, archive manifest. + is env vars, system properties, `loader.properties`, exploded archive manifest, archive + manifest. 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 ea24044402..083f639214 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 @@ -167,7 +167,7 @@ public class PropertiesLauncher extends Launcher { for (String config : configs) { InputStream resource = getResource(config); if (resource != null) { - log("Found: " + config); + debug("Found: " + config); try { this.properties.load(resource); } @@ -177,7 +177,7 @@ public class PropertiesLauncher extends Launcher { for (Object key : Collections.list(this.properties.propertyNames())) { if (config.endsWith("application.properties") && ((String) key).startsWith("loader.")) { - warn("WARNING: use of application.properties for PropertiesLauncher is deprecated"); + warn("Use of application.properties for PropertiesLauncher is deprecated"); } String text = this.properties.getProperty((String) key); String value = SystemPropertyUtils @@ -187,7 +187,7 @@ public class PropertiesLauncher extends Launcher { } } if ("true".equals(getProperty(SET_SYSTEM_PROPERTIES))) { - log("Adding resolved properties to System properties"); + debug("Adding resolved properties to System properties"); for (Object key : Collections.list(this.properties.propertyNames())) { String value = this.properties.getProperty((String) key); System.setProperty((String) key, value); @@ -197,7 +197,7 @@ public class PropertiesLauncher extends Launcher { return; } else { - log("Not found: " + config); + debug("Not found: " + config); } } } @@ -232,13 +232,13 @@ public class PropertiesLauncher extends Launcher { config = config.substring(1); } config = "/" + config; - log("Trying classpath: " + config); + debug("Trying classpath: " + config); return getClass().getResourceAsStream(config); } private InputStream getFileResource(String config) throws Exception { File file = new File(config); - log("Trying file: " + config); + debug("Trying file: " + config); if (file.canRead()) { return new FileInputStream(file); } @@ -294,7 +294,7 @@ public class PropertiesLauncher extends Launcher { if (path != null) { this.paths = parsePathsProperty(path); } - log("Nested archive paths: " + this.paths); + debug("Nested archive paths: " + this.paths); } private List parsePathsProperty(String commaSeparatedPaths) { @@ -342,7 +342,7 @@ public class PropertiesLauncher extends Launcher { String customLoaderClassName = getProperty("loader.classLoader"); if (customLoaderClassName != null) { loader = wrapWithCustomClassLoader(loader, customLoaderClassName); - log("Using custom class loader: " + customLoaderClassName); + debug("Using custom class loader: " + customLoaderClassName); } return loader; } @@ -392,13 +392,13 @@ public class PropertiesLauncher extends Launcher { if (property != null) { String value = SystemPropertyUtils.resolvePlaceholders(this.properties, property); - log("Property '" + propertyKey + "' from environment: " + value); + debug("Property '" + propertyKey + "' from environment: " + value); return value; } if (this.properties.containsKey(propertyKey)) { String value = SystemPropertyUtils.resolvePlaceholders(this.properties, this.properties.getProperty(propertyKey)); - log("Property '" + propertyKey + "' from properties: " + value); + debug("Property '" + propertyKey + "' from properties: " + value); return value; } try { @@ -408,7 +408,7 @@ public class PropertiesLauncher extends Launcher { if (manifest != null) { String value = manifest.getMainAttributes().getValue(manifestKey); if (value != null) { - log("Property '" + manifestKey + debug("Property '" + manifestKey + "' from home directory manifest: " + value); return SystemPropertyUtils.resolvePlaceholders(this.properties, value); @@ -424,7 +424,7 @@ public class PropertiesLauncher extends Launcher { if (manifest != null) { String value = manifest.getMainAttributes().getValue(manifestKey); if (value != null) { - log("Property '" + manifestKey + "' from archive manifest: " + value); + debug("Property '" + manifestKey + "' from archive manifest: " + value); return SystemPropertyUtils.resolvePlaceholders(this.properties, value); } } @@ -460,19 +460,19 @@ public class PropertiesLauncher extends Launcher { file = new File(this.home, root); } if (file.isDirectory()) { - log("Adding classpath entries from " + file); + debug("Adding classpath entries from " + file); Archive archive = new ExplodedArchive(file, false); lib.add(archive); } Archive archive = getArchive(file); if (archive != null) { - log("Adding classpath entries from archive " + archive.getUrl() + root); + debug("Adding classpath entries from archive " + archive.getUrl() + root); lib.add(archive); } - List nested = getNestedArchive(root); + Archive nested = getNestedArchive(root); if (nested != null) { - log("Adding classpath entries from nested " + root); - lib.addAll(nested); + debug("Adding classpath entries from nested " + root); + lib.add(nested); } return lib; } @@ -490,21 +490,19 @@ public class PropertiesLauncher extends Launcher { return null; } - private List getNestedArchive(String root) throws Exception { - List list = new ArrayList(); + private Archive getNestedArchive(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 list; + return null; } EntryFilter filter = new PrefixMatchingArchiveFilter(root); if (this.parent.getNestedArchives(filter).isEmpty()) { - return list; + return null; } // 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 - list.add(new FilteredArchive(this.parent, filter)); - return list; + return new FilteredArchive(this.parent, filter); } private void addNestedEntries(List lib) { @@ -575,15 +573,17 @@ public class PropertiesLauncher extends Launcher { return Character.toUpperCase(str.charAt(0)) + str.substring(1); } - private void log(String message) { + private void debug(String message) { if (Boolean.getBoolean(DEBUG)) { - // We shouldn't use java.util.logging because of classpath issues so we - // just sysout log messages when "loader.debug" is true - System.out.println(message); + log(message); } } private void warn(String message) { + log("WARNING: " + message); + } + + private void log(String message) { // We shouldn't use java.util.logging because of classpath issues System.out.println(message); } diff --git a/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/PropertiesLauncherTests.java b/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/PropertiesLauncherTests.java index 20159f7042..3610844a85 100644 --- a/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/PropertiesLauncherTests.java +++ b/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/PropertiesLauncherTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * Copyright 2012-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-boot-tools/spring-boot-loader/src/test/resources/BOOT-INF/classes/application.properties b/spring-boot-tools/spring-boot-loader/src/test/resources/BOOT-INF/classes/application.properties index 217ba94f73..85a390f4d4 100644 --- a/spring-boot-tools/spring-boot-loader/src/test/resources/BOOT-INF/classes/application.properties +++ b/spring-boot-tools/spring-boot-loader/src/test/resources/BOOT-INF/classes/application.properties @@ -1 +1 @@ -loader.main: demo.NoSuchApplication +loader.main: demo.Application diff --git a/spring-boot-tools/spring-boot-loader/src/test/resources/placeholders/META-INF/MANIFEST.MF b/spring-boot-tools/spring-boot-loader/src/test/resources/placeholders/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..d95a13c528 --- /dev/null +++ b/spring-boot-tools/spring-boot-loader/src/test/resources/placeholders/META-INF/MANIFEST.MF @@ -0,0 +1,2 @@ +Manifest-Version: 1.0 +Start-Class: ${foo.main}