Polish "Allow loader.path to refer to nested jars"

Closes gh-8334
Closes gh-8465
This commit is contained in:
Andy Wilkinson 2017-03-02 11:17:24 +00:00
parent 3701cce88f
commit 6673d8eebc
8 changed files with 152 additions and 23 deletions

View File

@ -147,7 +147,8 @@ files in directories (as opposed to explicitly on the classpath). In the case of
you just add extra jars in those locations if you want more. The `PropertiesLauncher`
looks in `BOOT-INF/lib/` in your application archive by default, but you can add
additional locations by setting an environment variable `LOADER_PATH` or `loader.path`
in `loader.properties` (comma-separated list of directories or archives).
in `loader.properties` (comma-separated list of directories, archives, or directories
within archives).
@ -280,7 +281,8 @@ the `Main-Class` attribute and leave out `Start-Class`.
* `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).
archive paths, a directory within an archive that is scanned for jar files (for
example, `dependencies.jar!/lib`), 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.

View File

@ -1 +1 @@
loader.path=jar:file:../executable-props/target/executable-props-0.0.1.BUILD-SNAPSHOT-full.jar/!BOOT-INF/lib
loader.path=jar:file:target/executable-props-lib-0.0.1.BUILD-SNAPSHOT-dependencies.jar/!BOOT-INF/lib

View File

@ -39,7 +39,17 @@
<type>jar</type>
</artifactItem>
</artifactItems>
<outputDirectory>${project.build.directory}/assembly</outputDirectory>
<outputDirectory>${project.build.directory}/app-assembly</outputDirectory>
</configuration>
</execution>
<execution>
<id>copy</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/dependencies-assembly/BOOT-INF/lib</outputDirectory>
</configuration>
</execution>
</executions>
@ -47,26 +57,38 @@
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<descriptors>
<descriptor>src/main/assembly/jar-with-dependencies.xml</descriptor>
</descriptors>
<archive>
<manifest>
<mainClass>org.springframework.boot.loader.PropertiesLauncher</mainClass>
</manifest>
<manifestEntries>
<Start-Class>org.springframework.boot.load.it.props.EmbeddedJarStarter</Start-Class>
</manifestEntries>
</archive>
</configuration>
<executions>
<execution>
<id>jar-with-dependencies</id>
<id>app</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>src/main/assembly/app.xml</descriptor>
</descriptors>
<archive>
<manifest>
<mainClass>org.springframework.boot.loader.PropertiesLauncher</mainClass>
</manifest>
<manifestEntries>
<Start-Class>org.springframework.boot.launcher.it.props.EmbeddedJarStarter</Start-Class>
</manifestEntries>
</archive>
</configuration>
</execution>
<execution>
<id>depedendencies</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>src/main/assembly/dependencies.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>

View File

@ -3,7 +3,7 @@
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>full</id>
<id>app</id>
<formats>
<format>jar</format>
</formats>
@ -20,7 +20,7 @@
</dependencySets>
<fileSets>
<fileSet>
<directory>${project.build.directory}/assembly</directory>
<directory>${project.build.directory}/app-assembly</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
</fileSets>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>dependencies</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${project.build.directory}/dependencies-assembly</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
</fileSets>
</assembly>

View File

@ -0,0 +1,34 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.launcher.it.props;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* Main class to start the embedded server.
*
* @author Dave Syer
*/
public final class EmbeddedJarStarter {
public static void main(String[] args) throws Exception {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfiguration.class);
context.getBean(SpringConfiguration.class).run(args);
context.close();
}
}

View File

@ -0,0 +1,54 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.launcher.it.props;
import java.io.IOException;
import java.util.Properties;
import javax.annotation.PostConstruct;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
/**
* Spring configuration.
*
* @author Dave Syer
*/
@Configuration
@ComponentScan
public class SpringConfiguration {
private String message = "Jar";
@PostConstruct
public void init() throws IOException {
Properties props = new Properties();
props.load(new ClassPathResource("application.properties").getInputStream());
String value = props.getProperty("message");
if (value!=null) {
this.message = value;
}
}
public void run(String... args) {
System.err.println("Hello Embedded " + this.message + "!");
}
}

View File

@ -1,4 +1,4 @@
def jarfile = './target/executable-props-lib-0.0.1.BUILD-SNAPSHOT-full.jar'
def jarfile = './target/executable-props-lib-0.0.1.BUILD-SNAPSHOT-app.jar'
new File("${basedir}/application.properties").delete()
@ -10,8 +10,8 @@ String exec(String command) {
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
'Using -jar my.jar should load dependencies from separate jar and 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
'Using -cp my.jar with PropertiesLauncher should load dependencies from separate jar and use the application.properties from the jar\n' + out