Minimize and centralize assumptions about build output
Closes gh-15471
This commit is contained in:
@@ -41,7 +41,7 @@ public class ResourceHandlingApplication {
|
||||
public static void main(String[] args) {
|
||||
new SpringApplicationBuilder(ResourceHandlingApplication.class)
|
||||
.properties("server.port:0")
|
||||
.listeners(new WebServerPortFileWriter("target/server.port")).run(args);
|
||||
.listeners(new WebServerPortFileWriter(args[0])).run(args);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -26,6 +26,7 @@ import java.util.List;
|
||||
|
||||
import org.junit.rules.ExternalResource;
|
||||
|
||||
import org.springframework.boot.testsupport.BuildOutput;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.util.StreamUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -40,12 +41,16 @@ abstract class AbstractApplicationLauncher extends ExternalResource {
|
||||
|
||||
private final ApplicationBuilder applicationBuilder;
|
||||
|
||||
private final BuildOutput buildOutput;
|
||||
|
||||
private Process process;
|
||||
|
||||
private int httpPort;
|
||||
|
||||
protected AbstractApplicationLauncher(ApplicationBuilder applicationBuilder) {
|
||||
protected AbstractApplicationLauncher(ApplicationBuilder applicationBuilder,
|
||||
BuildOutput buildOutput) {
|
||||
this.applicationBuilder = applicationBuilder;
|
||||
this.buildOutput = buildOutput;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -62,7 +67,7 @@ abstract class AbstractApplicationLauncher extends ExternalResource {
|
||||
return this.httpPort;
|
||||
}
|
||||
|
||||
protected abstract List<String> getArguments(File archive);
|
||||
protected abstract List<String> getArguments(File archive, File serverPortFile);
|
||||
|
||||
protected abstract File getWorkingDirectory();
|
||||
|
||||
@@ -70,14 +75,12 @@ abstract class AbstractApplicationLauncher extends ExternalResource {
|
||||
|
||||
private Process startApplication() throws Exception {
|
||||
File workingDirectory = getWorkingDirectory();
|
||||
File serverPortFile = (workingDirectory != null)
|
||||
? new File(workingDirectory, "target/server.port")
|
||||
: new File("target/server.port");
|
||||
File serverPortFile = new File(this.buildOutput.getRootLocation(), "server.port");
|
||||
serverPortFile.delete();
|
||||
File archive = this.applicationBuilder.buildApplication();
|
||||
List<String> arguments = new ArrayList<>();
|
||||
arguments.add(System.getProperty("java.home") + "/bin/java");
|
||||
arguments.addAll(getArguments(archive));
|
||||
arguments.addAll(getArguments(archive, serverPortFile));
|
||||
ProcessBuilder processBuilder = new ProcessBuilder(
|
||||
StringUtils.toStringArray(arguments));
|
||||
if (workingDirectory != null) {
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.junit.ClassRule;
|
||||
import org.junit.Rule;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
import org.springframework.boot.testsupport.BuildOutput;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.client.ResponseErrorHandler;
|
||||
@@ -48,6 +49,9 @@ public abstract class AbstractEmbeddedServletContainerIntegrationTests {
|
||||
|
||||
};
|
||||
|
||||
public static final BuildOutput buildOutput = new BuildOutput(
|
||||
AbstractEmbeddedServletContainerIntegrationTests.class);
|
||||
|
||||
@Rule
|
||||
public final AbstractApplicationLauncher launcher;
|
||||
|
||||
@@ -70,8 +74,9 @@ public abstract class AbstractEmbeddedServletContainerIntegrationTests {
|
||||
for (Class<? extends AbstractApplicationLauncher> launcherClass : applicationLaunchers) {
|
||||
try {
|
||||
AbstractApplicationLauncher launcher = launcherClass
|
||||
.getDeclaredConstructor(ApplicationBuilder.class)
|
||||
.newInstance(applicationBuilder);
|
||||
.getDeclaredConstructor(ApplicationBuilder.class,
|
||||
BuildOutput.class)
|
||||
.newInstance(applicationBuilder, buildOutput);
|
||||
String name = StringUtils.capitalize(container) + ": "
|
||||
+ launcher.getDescription(packaging);
|
||||
parameters.add(new Object[] { name, launcher });
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
* Copyright 2012-2018 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.
|
||||
@@ -27,6 +27,7 @@ import java.util.List;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
import org.springframework.boot.testsupport.BuildOutput;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.util.FileSystemUtils;
|
||||
import org.springframework.util.StreamUtils;
|
||||
@@ -40,14 +41,16 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
class BootRunApplicationLauncher extends AbstractApplicationLauncher {
|
||||
|
||||
private final File exploded = new File("target/run");
|
||||
private final File exploded;
|
||||
|
||||
BootRunApplicationLauncher(ApplicationBuilder applicationBuilder) {
|
||||
super(applicationBuilder);
|
||||
BootRunApplicationLauncher(ApplicationBuilder applicationBuilder,
|
||||
BuildOutput buildOutput) {
|
||||
super(applicationBuilder, buildOutput);
|
||||
this.exploded = new File(buildOutput.getRootLocation(), "run");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getArguments(File archive) {
|
||||
protected List<String> getArguments(File archive, File serverPortFile) {
|
||||
try {
|
||||
explodeArchive(archive);
|
||||
deleteLauncherClasses();
|
||||
@@ -64,7 +67,8 @@ class BootRunApplicationLauncher extends AbstractApplicationLauncher {
|
||||
return Arrays.asList("-cp",
|
||||
StringUtils.collectionToDelimitedString(classpath,
|
||||
File.pathSeparator),
|
||||
"com.example.ResourceHandlingApplication");
|
||||
"com.example.ResourceHandlingApplication",
|
||||
serverPortFile.getAbsolutePath());
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
@@ -76,12 +80,12 @@ class BootRunApplicationLauncher extends AbstractApplicationLauncher {
|
||||
}
|
||||
|
||||
private File populateTargetClasses(File archive) throws IOException {
|
||||
File targetClasses = new File(this.exploded, "target/classes");
|
||||
targetClasses.mkdirs();
|
||||
File builtClasses = new File(this.exploded, "built/classes");
|
||||
builtClasses.mkdirs();
|
||||
File source = new File(this.exploded, getClassesPath(archive));
|
||||
FileSystemUtils.copyRecursively(source, targetClasses);
|
||||
FileSystemUtils.copyRecursively(source, builtClasses);
|
||||
FileSystemUtils.deleteRecursively(source);
|
||||
return targetClasses;
|
||||
return builtClasses;
|
||||
}
|
||||
|
||||
private File populateDependencies(File archive) throws IOException {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
* Copyright 2012-2018 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.
|
||||
@@ -22,9 +22,11 @@ import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
import org.springframework.boot.testsupport.BuildOutput;
|
||||
import org.springframework.util.FileSystemUtils;
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
@@ -36,15 +38,17 @@ import org.springframework.util.StreamUtils;
|
||||
*/
|
||||
class ExplodedApplicationLauncher extends AbstractApplicationLauncher {
|
||||
|
||||
private final File exploded = new File("target/exploded");
|
||||
private final Supplier<File> exploded;
|
||||
|
||||
ExplodedApplicationLauncher(ApplicationBuilder applicationBuilder) {
|
||||
super(applicationBuilder);
|
||||
ExplodedApplicationLauncher(ApplicationBuilder applicationBuilder,
|
||||
BuildOutput buildOutput) {
|
||||
super(applicationBuilder, buildOutput);
|
||||
this.exploded = () -> new File(buildOutput.getRootLocation(), "exploded");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected File getWorkingDirectory() {
|
||||
return this.exploded;
|
||||
return this.exploded.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -53,13 +57,14 @@ class ExplodedApplicationLauncher extends AbstractApplicationLauncher {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getArguments(File archive) {
|
||||
protected List<String> getArguments(File archive, File serverPortFile) {
|
||||
String mainClass = (archive.getName().endsWith(".war")
|
||||
? "org.springframework.boot.loader.WarLauncher"
|
||||
: "org.springframework.boot.loader.JarLauncher");
|
||||
try {
|
||||
explodeArchive(archive);
|
||||
return Arrays.asList("-cp", this.exploded.getAbsolutePath(), mainClass);
|
||||
return Arrays.asList("-cp", this.exploded.get().getAbsolutePath(), mainClass,
|
||||
serverPortFile.getAbsolutePath());
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
@@ -67,12 +72,12 @@ class ExplodedApplicationLauncher extends AbstractApplicationLauncher {
|
||||
}
|
||||
|
||||
private void explodeArchive(File archive) throws IOException {
|
||||
FileSystemUtils.deleteRecursively(this.exploded);
|
||||
FileSystemUtils.deleteRecursively(this.exploded.get());
|
||||
JarFile jarFile = new JarFile(archive);
|
||||
Enumeration<JarEntry> entries = jarFile.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
JarEntry jarEntry = entries.nextElement();
|
||||
File extracted = new File(this.exploded, jarEntry.getName());
|
||||
File extracted = new File(this.exploded.get(), jarEntry.getName());
|
||||
if (jarEntry.isDirectory()) {
|
||||
extracted.mkdirs();
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import java.util.List;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
import org.springframework.boot.testsupport.BuildOutput;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.util.FileSystemUtils;
|
||||
import org.springframework.util.StreamUtils;
|
||||
@@ -40,10 +41,12 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
class IdeApplicationLauncher extends AbstractApplicationLauncher {
|
||||
|
||||
private final File exploded = new File("target/the+ide application");
|
||||
private final File exploded;
|
||||
|
||||
IdeApplicationLauncher(ApplicationBuilder applicationBuilder) {
|
||||
super(applicationBuilder);
|
||||
IdeApplicationLauncher(ApplicationBuilder applicationBuilder,
|
||||
BuildOutput buildOutput) {
|
||||
super(applicationBuilder, buildOutput);
|
||||
this.exploded = new File(buildOutput.getRootLocation(), "the+ide application");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -57,18 +60,18 @@ class IdeApplicationLauncher extends AbstractApplicationLauncher {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getArguments(File archive) {
|
||||
protected List<String> getArguments(File archive, File serverPortFile) {
|
||||
try {
|
||||
explodeArchive(archive, this.exploded);
|
||||
deleteLauncherClasses();
|
||||
File targetClasses = populateTargetClasses(archive);
|
||||
File builtClasses = populateBuiltClasses(archive);
|
||||
File dependencies = populateDependencies(archive);
|
||||
File resourcesProject = explodedResourcesProject(dependencies);
|
||||
if (archive.getName().endsWith(".war")) {
|
||||
populateSrcMainWebapp();
|
||||
}
|
||||
List<String> classpath = new ArrayList<>();
|
||||
classpath.add(targetClasses.getAbsolutePath());
|
||||
classpath.add(builtClasses.getAbsolutePath());
|
||||
for (File dependency : dependencies.listFiles()) {
|
||||
classpath.add(dependency.getAbsolutePath());
|
||||
}
|
||||
@@ -76,20 +79,21 @@ class IdeApplicationLauncher extends AbstractApplicationLauncher {
|
||||
return Arrays.asList("-cp",
|
||||
StringUtils.collectionToDelimitedString(classpath,
|
||||
File.pathSeparator),
|
||||
"com.example.ResourceHandlingApplication");
|
||||
"com.example.ResourceHandlingApplication",
|
||||
serverPortFile.getAbsolutePath());
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private File populateTargetClasses(File archive) throws IOException {
|
||||
File targetClasses = new File(this.exploded, "target/classes");
|
||||
targetClasses.mkdirs();
|
||||
private File populateBuiltClasses(File archive) throws IOException {
|
||||
File builtClasses = new File(this.exploded, "built/classes");
|
||||
builtClasses.mkdirs();
|
||||
File source = new File(this.exploded, getClassesPath(archive));
|
||||
FileSystemUtils.copyRecursively(source, targetClasses);
|
||||
FileSystemUtils.copyRecursively(source, builtClasses);
|
||||
FileSystemUtils.deleteRecursively(source);
|
||||
return targetClasses;
|
||||
return builtClasses;
|
||||
}
|
||||
|
||||
private File populateDependencies(File archive) throws IOException {
|
||||
@@ -108,7 +112,7 @@ class IdeApplicationLauncher extends AbstractApplicationLauncher {
|
||||
|
||||
private File explodedResourcesProject(File dependencies) throws IOException {
|
||||
File resourcesProject = new File(this.exploded,
|
||||
"resources-project/target/classes");
|
||||
"resources-project/built/classes");
|
||||
File resourcesJar = new File(dependencies, "resources-1.0.jar");
|
||||
explodeArchive(resourcesJar, resourcesProject);
|
||||
resourcesJar.delete();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
* Copyright 2012-2018 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.
|
||||
@@ -20,6 +20,8 @@ import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.boot.testsupport.BuildOutput;
|
||||
|
||||
/**
|
||||
* {@link AbstractApplicationLauncher} that launches a packaged Spring Boot application
|
||||
* using {@code java -jar}.
|
||||
@@ -28,8 +30,9 @@ import java.util.List;
|
||||
*/
|
||||
class PackagedApplicationLauncher extends AbstractApplicationLauncher {
|
||||
|
||||
PackagedApplicationLauncher(ApplicationBuilder applicationBuilder) {
|
||||
super(applicationBuilder);
|
||||
PackagedApplicationLauncher(ApplicationBuilder applicationBuilder,
|
||||
BuildOutput buildOutput) {
|
||||
super(applicationBuilder, buildOutput);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -43,8 +46,9 @@ class PackagedApplicationLauncher extends AbstractApplicationLauncher {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getArguments(File archive) {
|
||||
return Arrays.asList("-jar", archive.getAbsolutePath());
|
||||
protected List<String> getArguments(File archive, File serverPortFile) {
|
||||
return Arrays.asList("-jar", archive.getAbsolutePath(),
|
||||
serverPortFile.getAbsolutePath());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user