Rework spring-boot-server-tests to avoid using Maven
Closes gh-27476
This commit is contained in:
parent
ee07d6c3ca
commit
d9a24f32b4
|
@ -1,29 +1,24 @@
|
|||
plugins {
|
||||
id "java"
|
||||
id "org.springframework.boot.conventions"
|
||||
id "org.springframework.boot.integration-test"
|
||||
}
|
||||
|
||||
description = "Spring Boot Server Tests"
|
||||
description = "Spring Boot Server Integration Tests"
|
||||
|
||||
configurations {
|
||||
testRepository
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-test"))
|
||||
testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support"))
|
||||
testImplementation("com.samskivert:jmustache")
|
||||
testImplementation("jakarta.servlet:jakarta.servlet-api")
|
||||
testImplementation("org.apache.httpcomponents:httpasyncclient")
|
||||
testImplementation("org.apache.maven.shared:maven-invoker:3.0.0")
|
||||
testImplementation("org.awaitility:awaitility")
|
||||
testImplementation("org.eclipse.jetty:jetty-webapp") {
|
||||
exclude group: "javax.servlet", module: "javax-servlet-api"
|
||||
}
|
||||
testImplementation("org.springframework:spring-web")
|
||||
intTestImplementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-test"))
|
||||
intTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support"))
|
||||
intTestImplementation("org.apache.httpcomponents:httpasyncclient")
|
||||
intTestImplementation("org.awaitility:awaitility")
|
||||
intTestImplementation("org.springframework:spring-web")
|
||||
|
||||
testRepository(project(path: ":spring-boot-project:spring-boot-dependencies", configuration: "mavenRepository"))
|
||||
testRepository(project(path: ":spring-boot-project:spring-boot-tools:spring-boot-maven-plugin", configuration: "mavenRepository"))
|
||||
testRepository(project(path: ":spring-boot-project:spring-boot-tools:spring-boot-gradle-plugin", configuration: "mavenRepository"))
|
||||
testRepository(project(path: ":spring-boot-project:spring-boot-starters:spring-boot-starter", configuration: "mavenRepository"))
|
||||
testRepository(project(path: ":spring-boot-project:spring-boot-starters:spring-boot-starter-jetty", configuration: "mavenRepository"))
|
||||
testRepository(project(path: ":spring-boot-project:spring-boot-starters:spring-boot-starter-json", configuration: "mavenRepository"))
|
||||
|
@ -34,11 +29,6 @@ dependencies {
|
|||
testRuntimeOnly(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-logging"))
|
||||
}
|
||||
|
||||
task prepareMavenBinaries(type: org.springframework.boot.build.mavenplugin.PrepareMavenBinaries) {
|
||||
outputDir = file("${buildDir}/maven-binaries")
|
||||
versions "3.6.2"
|
||||
}
|
||||
|
||||
task syncTestRepository(type: Sync) {
|
||||
destinationDir = file("${buildDir}/test-repository")
|
||||
from {
|
||||
|
@ -46,6 +36,28 @@ task syncTestRepository(type: Sync) {
|
|||
}
|
||||
}
|
||||
|
||||
test {
|
||||
dependsOn prepareMavenBinaries, syncTestRepository
|
||||
task syncAppSource(type: Sync) {
|
||||
from "spring-boot-server-tests-app"
|
||||
into "${buildDir}/spring-boot-server-tests-app"
|
||||
filter { line ->
|
||||
line.replace("id \"org.springframework.boot\"", "id \"org.springframework.boot\" version \"${project.version}\"")
|
||||
}
|
||||
}
|
||||
|
||||
task buildApps(type: GradleBuild) {
|
||||
dependsOn syncAppSource, syncTestRepository
|
||||
dir = "${buildDir}/spring-boot-server-tests-app"
|
||||
startParameter.buildCacheEnabled = false
|
||||
tasks = [
|
||||
"jettyBootJar",
|
||||
"jettyBootWar",
|
||||
"tomcatBootJar",
|
||||
"tomcatBootWar",
|
||||
"undertowBootJar",
|
||||
"undertowBootWar"
|
||||
]
|
||||
}
|
||||
|
||||
intTest {
|
||||
dependsOn buildApps
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
import org.springframework.boot.gradle.tasks.bundling.BootJar
|
||||
import org.springframework.boot.gradle.tasks.bundling.BootWar
|
||||
|
||||
plugins {
|
||||
id "java"
|
||||
id "org.springframework.boot"
|
||||
id "war"
|
||||
}
|
||||
|
||||
apply plugin: "io.spring.dependency-management"
|
||||
|
||||
repositories {
|
||||
maven { url "file:${rootDir}/../test-repository"}
|
||||
mavenCentral()
|
||||
maven {
|
||||
url "https://repo.spring.io/milestone"
|
||||
content {
|
||||
excludeGroup "org.springframework.boot"
|
||||
}
|
||||
}
|
||||
maven {
|
||||
url "https://repo.spring.io/snapshot"
|
||||
content {
|
||||
excludeGroup "org.springframework.boot"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
configurations {
|
||||
jetty
|
||||
tomcat
|
||||
undertow
|
||||
}
|
||||
|
||||
tasks.register("resourcesJar", Jar) { jar ->
|
||||
def nested = project.resources.text.fromString("nested")
|
||||
from(nested) {
|
||||
into "META-INF/resources/"
|
||||
rename (".*", "nested-meta-inf-resource.txt")
|
||||
}
|
||||
if (!isWindows()) {
|
||||
def encodedName = project.resources.text.fromString("encoded-name")
|
||||
from(encodedName) {
|
||||
into "META-INF/resources/"
|
||||
rename (".*", 'nested-reserved-!#\\$%&()*+,:=?@[]-meta-inf-resource.txt')
|
||||
}
|
||||
}
|
||||
classifier = 'resources'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly("org.eclipse.jetty:jetty-server")
|
||||
|
||||
implementation("org.springframework.boot:spring-boot-starter")
|
||||
implementation("org.springframework:spring-web")
|
||||
|
||||
jetty("org.springframework.boot:spring-boot-starter-jetty")
|
||||
jetty files(resourcesJar)
|
||||
tomcat("org.springframework.boot:spring-boot-starter-tomcat")
|
||||
tomcat files(resourcesJar)
|
||||
undertow("org.springframework.boot:spring-boot-starter-undertow")
|
||||
undertow files(resourcesJar)
|
||||
}
|
||||
|
||||
def boolean isWindows() {
|
||||
return File.separatorChar == '\\';
|
||||
}
|
||||
|
||||
["jetty", "tomcat", "undertow"].each { container ->
|
||||
def configurer = { task ->
|
||||
task.dependsOn resourcesJar
|
||||
task.mainClass = "com.example.ResourceHandlingApplication"
|
||||
task.classpath = sourceSets.main.runtimeClasspath.plus(configurations.getByName(container))
|
||||
task.classifier = container
|
||||
}
|
||||
tasks.register("${container}BootJar", BootJar, configurer)
|
||||
tasks.register("${container}BootWar", BootWar, configurer)
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
pluginManagement {
|
||||
repositories {
|
||||
maven { url "file:${rootDir}/../test-repository"}
|
||||
mavenCentral()
|
||||
maven {
|
||||
url "https://repo.spring.io/milestone"
|
||||
content {
|
||||
excludeGroup "org.springframework.boot"
|
||||
}
|
||||
}
|
||||
maven {
|
||||
url "https://repo.spring.io/snapshot"
|
||||
content {
|
||||
excludeGroup "org.springframework.boot"
|
||||
}
|
||||
}
|
||||
}
|
||||
resolutionStrategy {
|
||||
eachPlugin {
|
||||
if (requested.id.id == "org.springframework.boot") {
|
||||
useModule "org.springframework.boot:spring-boot-gradle-plugin:${requested.version}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,6 +18,7 @@ package com.example;
|
|||
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
@ -28,6 +29,7 @@ import org.springframework.context.annotation.Configuration;
|
|||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
@ConditionalOnClass(name = {"org.eclipse.jetty.server.handler.ContextHandler"})
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public class JettyServerCustomizerConfig {
|
||||
|
|
@ -0,0 +1 @@
|
|||
webapp resource
|
|
@ -41,7 +41,7 @@ import org.springframework.util.StringUtils;
|
|||
*/
|
||||
abstract class AbstractApplicationLauncher implements BeforeEachCallback {
|
||||
|
||||
private final ApplicationBuilder applicationBuilder;
|
||||
private final Application application;
|
||||
|
||||
private final BuildOutput buildOutput;
|
||||
|
||||
|
@ -49,8 +49,8 @@ abstract class AbstractApplicationLauncher implements BeforeEachCallback {
|
|||
|
||||
private int httpPort;
|
||||
|
||||
protected AbstractApplicationLauncher(ApplicationBuilder applicationBuilder, BuildOutput buildOutput) {
|
||||
this.applicationBuilder = applicationBuilder;
|
||||
protected AbstractApplicationLauncher(Application application, BuildOutput buildOutput) {
|
||||
this.application = application;
|
||||
this.buildOutput = buildOutput;
|
||||
}
|
||||
|
||||
|
@ -87,7 +87,8 @@ abstract class AbstractApplicationLauncher implements BeforeEachCallback {
|
|||
File workingDirectory = getWorkingDirectory();
|
||||
File serverPortFile = new File(this.buildOutput.getRootLocation(), "server.port");
|
||||
serverPortFile.delete();
|
||||
File archive = this.applicationBuilder.buildApplication();
|
||||
File archive = new File("build/spring-boot-server-tests-app/build/libs/spring-boot-server-tests-app-"
|
||||
+ this.application.getContainer() + "." + this.application.getPackaging());
|
||||
List<String> arguments = new ArrayList<>();
|
||||
arguments.add(System.getProperty("java.home") + "/bin/java");
|
||||
arguments.addAll(getArguments(archive, serverPortFile));
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2021 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.
|
||||
|
@ -16,29 +16,35 @@
|
|||
|
||||
package org.springframework.boot.context.embedded;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Provides access to the current Boot version by referring to {@code gradle.properties}.
|
||||
* An pre-built application that can be launched.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
final class Versions {
|
||||
class Application {
|
||||
|
||||
private Versions() {
|
||||
private final String packaging;
|
||||
|
||||
private final String container;
|
||||
|
||||
Application(String packaging, String container) {
|
||||
this.packaging = packaging;
|
||||
this.container = container;
|
||||
}
|
||||
|
||||
static String getBootVersion() {
|
||||
Properties gradleProperties = new Properties();
|
||||
try (FileInputStream input = new FileInputStream("../../../gradle.properties")) {
|
||||
gradleProperties.load(input);
|
||||
return gradleProperties.getProperty("version");
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
String getPackaging() {
|
||||
return this.packaging;
|
||||
}
|
||||
|
||||
String getContainer() {
|
||||
return this.container;
|
||||
}
|
||||
|
||||
File getArchive() {
|
||||
return new File("build/spring-boot-server-tests-app/build/libs/spring-boot-server-tests-app-" + this.container
|
||||
+ "." + this.packaging);
|
||||
}
|
||||
|
||||
}
|
|
@ -43,8 +43,8 @@ class BootRunApplicationLauncher extends AbstractApplicationLauncher {
|
|||
|
||||
private final File exploded;
|
||||
|
||||
BootRunApplicationLauncher(ApplicationBuilder applicationBuilder, BuildOutput buildOutput) {
|
||||
super(applicationBuilder, buildOutput);
|
||||
BootRunApplicationLauncher(Application application, BuildOutput buildOutput) {
|
||||
super(application, buildOutput);
|
||||
this.exploded = new File(buildOutput.getRootLocation(), "run");
|
||||
}
|
||||
|
||||
|
@ -112,7 +112,7 @@ class BootRunApplicationLauncher extends AbstractApplicationLauncher {
|
|||
|
||||
private List<String> getLibPaths(File archive) {
|
||||
return (archive.getName().endsWith(".jar") ? Collections.singletonList("BOOT-INF/lib")
|
||||
: Arrays.asList("WEB-INF/lib", "WEB-INF/lib-provided"));
|
||||
: Arrays.asList("WEB-INF/lib"));
|
||||
}
|
||||
|
||||
private void explodeArchive(File archive) throws IOException {
|
|
@ -63,8 +63,6 @@ class EmbeddedServerContainerInvocationContextProvider
|
|||
private static final BuildOutput buildOutput = new BuildOutput(
|
||||
EmbeddedServerContainerInvocationContextProvider.class);
|
||||
|
||||
private final Map<String, ApplicationBuilder> builderCache = new HashMap<>();
|
||||
|
||||
private final Map<String, AbstractApplicationLauncher> launcherCache = new HashMap<>();
|
||||
|
||||
private final Path tempDir;
|
||||
|
@ -84,7 +82,7 @@ class EmbeddedServerContainerInvocationContextProvider
|
|||
.getAnnotation(EmbeddedServletContainerTest.class);
|
||||
return CONTAINERS
|
||||
.stream().map(
|
||||
(container) -> getApplicationBuilder(annotation, container))
|
||||
(container) -> getApplication(annotation, container))
|
||||
.flatMap(
|
||||
(builder) -> Stream
|
||||
.of(annotation.launchers()).map(
|
||||
|
@ -104,28 +102,21 @@ class EmbeddedServerContainerInvocationContextProvider
|
|||
private void cleanupCaches() {
|
||||
this.launcherCache.values().forEach(AbstractApplicationLauncher::destroyProcess);
|
||||
this.launcherCache.clear();
|
||||
this.builderCache.clear();
|
||||
}
|
||||
|
||||
private AbstractApplicationLauncher getAbstractApplicationLauncher(ApplicationBuilder builder,
|
||||
private AbstractApplicationLauncher getAbstractApplicationLauncher(Application application,
|
||||
Class<? extends AbstractApplicationLauncher> launcherClass) {
|
||||
String cacheKey = builder.getContainer() + ":" + builder.getPackaging() + ":" + launcherClass.getName();
|
||||
String cacheKey = application.getContainer() + ":" + application.getPackaging() + ":" + launcherClass.getName();
|
||||
if (this.launcherCache.containsKey(cacheKey)) {
|
||||
return this.launcherCache.get(cacheKey);
|
||||
}
|
||||
AbstractApplicationLauncher launcher = ReflectionUtils.newInstance(launcherClass, builder, buildOutput);
|
||||
AbstractApplicationLauncher launcher = ReflectionUtils.newInstance(launcherClass, application, buildOutput);
|
||||
this.launcherCache.put(cacheKey, launcher);
|
||||
return launcher;
|
||||
}
|
||||
|
||||
private ApplicationBuilder getApplicationBuilder(EmbeddedServletContainerTest annotation, String container) {
|
||||
String cacheKey = container + ":" + annotation.packaging();
|
||||
if (this.builderCache.containsKey(cacheKey)) {
|
||||
return this.builderCache.get(cacheKey);
|
||||
}
|
||||
ApplicationBuilder builder = new ApplicationBuilder(this.tempDir, annotation.packaging(), container);
|
||||
this.builderCache.put(cacheKey, builder);
|
||||
return builder;
|
||||
private Application getApplication(EmbeddedServletContainerTest annotation, String container) {
|
||||
return new Application(annotation.packaging(), container);
|
||||
}
|
||||
|
||||
static class EmbeddedServletContainerInvocationContext implements TestTemplateInvocationContext, ParameterResolver {
|
|
@ -40,8 +40,8 @@ class ExplodedApplicationLauncher extends AbstractApplicationLauncher {
|
|||
|
||||
private final Supplier<File> exploded;
|
||||
|
||||
ExplodedApplicationLauncher(ApplicationBuilder applicationBuilder, BuildOutput buildOutput) {
|
||||
super(applicationBuilder, buildOutput);
|
||||
ExplodedApplicationLauncher(Application application, BuildOutput buildOutput) {
|
||||
super(application, buildOutput);
|
||||
this.exploded = () -> new File(buildOutput.getRootLocation(), "exploded");
|
||||
}
|
||||
|
|
@ -43,8 +43,8 @@ class IdeApplicationLauncher extends AbstractApplicationLauncher {
|
|||
|
||||
private final File exploded;
|
||||
|
||||
IdeApplicationLauncher(ApplicationBuilder applicationBuilder, BuildOutput buildOutput) {
|
||||
super(applicationBuilder, buildOutput);
|
||||
IdeApplicationLauncher(Application application, BuildOutput buildOutput) {
|
||||
super(application, buildOutput);
|
||||
this.exploded = new File(buildOutput.getRootLocation(), "the+ide application");
|
||||
}
|
||||
|
||||
|
@ -108,7 +108,7 @@ class IdeApplicationLauncher extends AbstractApplicationLauncher {
|
|||
|
||||
private File explodedResourcesProject(File dependencies) throws IOException {
|
||||
File resourcesProject = new File(this.exploded, "resources-project/built/classes");
|
||||
File resourcesJar = new File(dependencies, "resources-1.0.jar");
|
||||
File resourcesJar = new File(dependencies, "spring-boot-server-tests-app-resources.jar");
|
||||
explodeArchive(resourcesJar, resourcesProject);
|
||||
resourcesJar.delete();
|
||||
return resourcesProject;
|
||||
|
@ -132,7 +132,7 @@ class IdeApplicationLauncher extends AbstractApplicationLauncher {
|
|||
|
||||
private List<String> getLibPaths(File archive) {
|
||||
return (archive.getName().endsWith(".jar") ? Collections.singletonList("BOOT-INF/lib")
|
||||
: Arrays.asList("WEB-INF/lib", "WEB-INF/lib-provided"));
|
||||
: Arrays.asList("WEB-INF/lib"));
|
||||
}
|
||||
|
||||
private void explodeArchive(File archive, File destination) throws IOException {
|
|
@ -30,8 +30,8 @@ import org.springframework.boot.testsupport.BuildOutput;
|
|||
*/
|
||||
class PackagedApplicationLauncher extends AbstractApplicationLauncher {
|
||||
|
||||
PackagedApplicationLauncher(ApplicationBuilder applicationBuilder, BuildOutput buildOutput) {
|
||||
super(applicationBuilder, buildOutput);
|
||||
PackagedApplicationLauncher(Application application, BuildOutput buildOutput) {
|
||||
super(application, buildOutput);
|
||||
}
|
||||
|
||||
@Override
|
|
@ -1,184 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-2021 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
|
||||
*
|
||||
* https://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.context.embedded;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.jar.JarOutputStream;
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
import com.samskivert.mustache.Mustache;
|
||||
import org.apache.maven.shared.invoker.DefaultInvocationRequest;
|
||||
import org.apache.maven.shared.invoker.DefaultInvoker;
|
||||
import org.apache.maven.shared.invoker.InvocationRequest;
|
||||
import org.apache.maven.shared.invoker.InvocationResult;
|
||||
import org.apache.maven.shared.invoker.MavenInvocationException;
|
||||
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Builds a Spring Boot application using Maven.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
class ApplicationBuilder {
|
||||
|
||||
private final Path temp;
|
||||
|
||||
private final String packaging;
|
||||
|
||||
private final String container;
|
||||
|
||||
ApplicationBuilder(Path temp, String packaging, String container) {
|
||||
this.temp = temp;
|
||||
this.packaging = packaging;
|
||||
this.container = container;
|
||||
}
|
||||
|
||||
File buildApplication() throws Exception {
|
||||
File containerDirectory = new File(this.temp.toFile(), this.container);
|
||||
if (containerDirectory.exists()) {
|
||||
return new File(containerDirectory, "app/target/app-0.0.1." + this.packaging);
|
||||
}
|
||||
return doBuildApplication(containerDirectory);
|
||||
}
|
||||
|
||||
String getPackaging() {
|
||||
return this.packaging;
|
||||
}
|
||||
|
||||
String getContainer() {
|
||||
return this.container;
|
||||
}
|
||||
|
||||
private File doBuildApplication(File containerDirectory) throws IOException, MavenInvocationException {
|
||||
File resourcesJar = createResourcesJar();
|
||||
File appDirectory = new File(containerDirectory, "app");
|
||||
appDirectory.mkdirs();
|
||||
File settingsXml = writeSettingsXml(appDirectory);
|
||||
writePom(appDirectory, resourcesJar);
|
||||
copyApplicationSource(appDirectory);
|
||||
packageApplication(appDirectory, settingsXml);
|
||||
return new File(appDirectory, "target/app-0.0.1." + this.packaging);
|
||||
}
|
||||
|
||||
private File createResourcesJar() throws IOException {
|
||||
File resourcesJar = new File(this.temp.toFile(), "resources.jar");
|
||||
if (resourcesJar.exists()) {
|
||||
return resourcesJar;
|
||||
}
|
||||
try (JarOutputStream resourcesJarStream = new JarOutputStream(new FileOutputStream(resourcesJar))) {
|
||||
resourcesJarStream.putNextEntry(new ZipEntry("META-INF/resources/"));
|
||||
resourcesJarStream.closeEntry();
|
||||
resourcesJarStream.putNextEntry(new ZipEntry("META-INF/resources/nested-meta-inf-resource.txt"));
|
||||
resourcesJarStream.write("nested".getBytes());
|
||||
resourcesJarStream.closeEntry();
|
||||
if (!isWindows()) {
|
||||
resourcesJarStream.putNextEntry(
|
||||
new ZipEntry("META-INF/resources/nested-reserved-!#$%&()*+,:=?@[]-meta-inf-resource.txt"));
|
||||
resourcesJarStream.write("encoded-name".getBytes());
|
||||
resourcesJarStream.closeEntry();
|
||||
}
|
||||
return resourcesJar;
|
||||
}
|
||||
}
|
||||
|
||||
private void writePom(File appDirectory, File resourcesJar) throws IOException {
|
||||
Map<String, Object> context = new HashMap<>();
|
||||
context.put("packaging", this.packaging);
|
||||
context.put("container", this.container);
|
||||
context.put("bootVersion", Versions.getBootVersion());
|
||||
context.put("resourcesJarPath", resourcesJar.getAbsolutePath());
|
||||
try (FileWriter out = new FileWriter(new File(appDirectory, "pom.xml"));
|
||||
FileReader templateReader = new FileReader("src/test/resources/pom-template.xml")) {
|
||||
Mustache.compiler().escapeHTML(false).compile(templateReader).execute(context, out);
|
||||
}
|
||||
}
|
||||
|
||||
private File writeSettingsXml(File appDirectory) throws IOException {
|
||||
Map<String, Object> context = new HashMap<>();
|
||||
context.put("repository", new File("build/test-repository").toURI().toURL());
|
||||
context.put("localRepository", new File("build/local-m2-repository").getAbsolutePath());
|
||||
File settingsXml = new File(appDirectory, "settings.xml");
|
||||
try (FileWriter out = new FileWriter(settingsXml);
|
||||
FileReader templateReader = new FileReader("src/test/resources/settings-template.xml")) {
|
||||
Mustache.compiler().escapeHTML(false).compile(templateReader).execute(context, out);
|
||||
}
|
||||
return settingsXml;
|
||||
}
|
||||
|
||||
private void copyApplicationSource(File appDirectory) throws IOException {
|
||||
File examplePackage = new File(appDirectory, "src/main/java/com/example");
|
||||
examplePackage.mkdirs();
|
||||
FileCopyUtils.copy(new File("src/test/java/com/example/ResourceHandlingApplication.java"),
|
||||
new File(examplePackage, "ResourceHandlingApplication.java"));
|
||||
// To allow aliased resources on Concourse Windows CI (See gh-15553) to be served
|
||||
// as static resources.
|
||||
if (this.container.equals("jetty")) {
|
||||
FileCopyUtils.copy(new File("src/test/java/com/example/JettyServerCustomizerConfig.java"),
|
||||
new File(examplePackage, "JettyServerCustomizerConfig.java"));
|
||||
}
|
||||
if ("war".equals(this.packaging)) {
|
||||
File srcMainWebapp = new File(appDirectory, "src/main/webapp");
|
||||
srcMainWebapp.mkdirs();
|
||||
FileCopyUtils.copy("webapp resource", new FileWriter(new File(srcMainWebapp, "webapp-resource.txt")));
|
||||
}
|
||||
copyAutoConfigurationFiles(appDirectory);
|
||||
return;
|
||||
}
|
||||
|
||||
private void copyAutoConfigurationFiles(File appDirectory) throws IOException {
|
||||
File autoConfigPackage = new File(appDirectory, "src/main/java/com/autoconfig");
|
||||
autoConfigPackage.mkdirs();
|
||||
FileCopyUtils.copy(new File("src/test/java/com/autoconfig/ExampleAutoConfiguration.java"),
|
||||
new File(autoConfigPackage, "ExampleAutoConfiguration.java"));
|
||||
File srcMainResources = new File(appDirectory, "src/main/resources");
|
||||
srcMainResources.mkdirs();
|
||||
File metaInf = new File(srcMainResources, "META-INF");
|
||||
metaInf.mkdirs();
|
||||
FileCopyUtils.copy(new File("src/test/resources/META-INF/spring.factories"),
|
||||
new File(metaInf, "spring.factories"));
|
||||
}
|
||||
|
||||
private void packageApplication(File appDirectory, File settingsXml) throws MavenInvocationException {
|
||||
InvocationRequest invocation = new DefaultInvocationRequest();
|
||||
invocation.setBaseDirectory(appDirectory);
|
||||
invocation.setGoals(Collections.singletonList("package"));
|
||||
if (settingsXml != null) {
|
||||
invocation.setUserSettingsFile(settingsXml);
|
||||
}
|
||||
invocation.setUpdateSnapshots(true);
|
||||
DefaultInvoker invoker = new DefaultInvoker();
|
||||
invoker.setMavenHome(new File("build/maven-binaries/apache-maven-3.6.2"));
|
||||
InvocationResult execute = invoker.execute(invocation);
|
||||
assertThat(execute.getExitCode()).isEqualTo(0);
|
||||
}
|
||||
|
||||
private boolean isWindows() {
|
||||
return File.separatorChar == '\\';
|
||||
}
|
||||
|
||||
}
|
|
@ -1,87 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>{{bootVersion}}</version>
|
||||
<relativePath />
|
||||
</parent>
|
||||
<groupId>com.example</groupId>
|
||||
<artifactId>app</artifactId>
|
||||
<version>0.0.1</version>
|
||||
<packaging>{{packaging}}</packaging>
|
||||
<properties>
|
||||
<resourcesJarPath>{{resourcesJarPath}}</resourcesJarPath>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-{{container}}</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.example</groupId>
|
||||
<artifactId>resources</artifactId>
|
||||
<version>1.0</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${resourcesJarPath}</systemPath>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<includeSystemScope>true</includeSystemScope>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-snapshots</id>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spring-milestones</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>spring-snapshots</id>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
<pluginRepository>
|
||||
<id>spring-milestones</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
</project>
|
|
@ -1,31 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
|
||||
<localRepository>{{localRepository}}</localRepository>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>repository</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>repository</id>
|
||||
<url>{{repository}}</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>repository</id>
|
||||
<url>{{repository}}</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
</profile>
|
||||
</profiles>
|
||||
</settings>
|
Loading…
Reference in New Issue