Merge branch 'gradle-plugin-configuration-cache'
Closes gh-22922
This commit is contained in:
@@ -43,6 +43,7 @@ The Spring Boot Gradle Plugin provides Spring Boot support in https://gradle.org
|
||||
It allows you to package executable jar or war archives, run Spring Boot applications, and use the dependency management provided by `spring-boot-dependencies`.
|
||||
Spring Boot's Gradle plugin requires Gradle 6 (6.3 or later).
|
||||
Gradle 5.6 is also supported but this support is deprecated and will be removed in a future release.
|
||||
Gradle's {gradle-userguide}/configuration_cache.html[configuration cache] is supported when using Gradle 6.7 or later.
|
||||
|
||||
In addition to this user guide, {api-documentation}[API documentation] is also available.
|
||||
|
||||
|
||||
@@ -10,8 +10,3 @@ application {
|
||||
}
|
||||
// end::main-class[]
|
||||
|
||||
task configuredMainClass {
|
||||
doLast {
|
||||
println bootRun.main
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,9 +11,3 @@ application {
|
||||
mainClass.set("com.example.ExampleApplication")
|
||||
}
|
||||
// end::main-class[]
|
||||
|
||||
task("configuredMainClass") {
|
||||
doLast {
|
||||
println(tasks.getByName<BootRun>("bootRun").main)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,9 +9,3 @@ springBoot {
|
||||
mainClass = 'com.example.ExampleApplication'
|
||||
}
|
||||
// end::main-class[]
|
||||
|
||||
task configuredMainClass {
|
||||
doLast {
|
||||
println bootRun.main
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,9 +11,3 @@ springBoot {
|
||||
mainClass.set("com.example.ExampleApplication")
|
||||
}
|
||||
// end::main-class[]
|
||||
|
||||
task("configuredMainClass") {
|
||||
doLast {
|
||||
println(tasks.getByName<BootRun>("bootRun").main)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import org.gradle.api.Action;
|
||||
import org.gradle.api.Plugin;
|
||||
@@ -39,6 +38,7 @@ import org.gradle.api.plugins.ApplicationPlugin;
|
||||
import org.gradle.api.plugins.BasePlugin;
|
||||
import org.gradle.api.plugins.JavaPlugin;
|
||||
import org.gradle.api.plugins.JavaPluginConvention;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.SourceSet;
|
||||
import org.gradle.api.tasks.TaskProvider;
|
||||
import org.gradle.api.tasks.compile.JavaCompile;
|
||||
@@ -93,25 +93,25 @@ final class JavaPluginAction implements PluginApplicationAction {
|
||||
}
|
||||
|
||||
private TaskProvider<BootJar> configureBootJarTask(Project project) {
|
||||
SourceSet mainSourceSet = javaPluginConvention(project).getSourceSets()
|
||||
.getByName(SourceSet.MAIN_SOURCE_SET_NAME);
|
||||
Configuration developmentOnly = project.getConfigurations()
|
||||
.getByName(SpringBootPlugin.DEVELOPMENT_ONLY_CONFIGURATION_NAME);
|
||||
Configuration productionRuntimeClasspath = project.getConfigurations()
|
||||
.getByName(SpringBootPlugin.PRODUCTION_RUNTIME_CLASSPATH_NAME);
|
||||
FileCollection classpath = mainSourceSet.getRuntimeClasspath()
|
||||
.minus((developmentOnly.minus(productionRuntimeClasspath))).filter(new JarTypeFileSpec());
|
||||
TaskProvider<ResolveMainClassName> resolveMainClassName = ResolveMainClassName
|
||||
.registerForTask(SpringBootPlugin.BOOT_JAR_TASK_NAME, project, classpath);
|
||||
return project.getTasks().register(SpringBootPlugin.BOOT_JAR_TASK_NAME, BootJar.class, (bootJar) -> {
|
||||
bootJar.setDescription(
|
||||
"Assembles an executable jar archive containing the main classes and their dependencies.");
|
||||
bootJar.setGroup(BasePlugin.BUILD_GROUP);
|
||||
SourceSet mainSourceSet = javaPluginConvention(project).getSourceSets()
|
||||
.getByName(SourceSet.MAIN_SOURCE_SET_NAME);
|
||||
bootJar.classpath((Callable<FileCollection>) () -> {
|
||||
Configuration developmentOnly = project.getConfigurations()
|
||||
.getByName(SpringBootPlugin.DEVELOPMENT_ONLY_CONFIGURATION_NAME);
|
||||
Configuration productionRuntimeClasspath = project.getConfigurations()
|
||||
.getByName(SpringBootPlugin.PRODUCTION_RUNTIME_CLASSPATH_NAME);
|
||||
return mainSourceSet.getRuntimeClasspath().minus((developmentOnly.minus(productionRuntimeClasspath)))
|
||||
.filter(new JarTypeFileSpec());
|
||||
});
|
||||
bootJar.getMainClass().convention(project.provider(() -> {
|
||||
String manifestStartClass = (String) bootJar.getManifest().getAttributes().get("Start-Class");
|
||||
return (manifestStartClass != null) ? manifestStartClass
|
||||
: new MainClassConvention(project, bootJar::getClasspath).call();
|
||||
}));
|
||||
bootJar.classpath(classpath);
|
||||
Provider<String> manifestStartClass = project
|
||||
.provider(() -> (String) bootJar.getManifest().getAttributes().get("Start-Class"));
|
||||
bootJar.getMainClass().convention(resolveMainClassName.flatMap((resolver) -> manifestStartClass.isPresent()
|
||||
? manifestStartClass : resolveMainClassName.get().readMainClassName()));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -130,18 +130,28 @@ final class JavaPluginAction implements PluginApplicationAction {
|
||||
}
|
||||
|
||||
private void configureBootRunTask(Project project) {
|
||||
FileCollection classpath = javaPluginConvention(project).getSourceSets()
|
||||
.findByName(SourceSet.MAIN_SOURCE_SET_NAME).getRuntimeClasspath().filter(new JarTypeFileSpec());
|
||||
TaskProvider<ResolveMainClassName> resolveProvider = ResolveMainClassName.registerForTask("bootRun", project,
|
||||
classpath);
|
||||
project.getTasks().register("bootRun", BootRun.class, (run) -> {
|
||||
run.setDescription("Runs this project as a Spring Boot application.");
|
||||
run.setGroup(ApplicationPlugin.APPLICATION_GROUP);
|
||||
run.classpath(javaPluginConvention(project).getSourceSets().findByName(SourceSet.MAIN_SOURCE_SET_NAME)
|
||||
.getRuntimeClasspath().filter(new JarTypeFileSpec()));
|
||||
run.classpath(classpath);
|
||||
run.getConventionMapping().map("jvmArgs", () -> {
|
||||
if (project.hasProperty("applicationDefaultJvmArgs")) {
|
||||
return project.property("applicationDefaultJvmArgs");
|
||||
}
|
||||
return Collections.emptyList();
|
||||
});
|
||||
run.conventionMapping("main", new MainClassConvention(project, run::getClasspath));
|
||||
try {
|
||||
run.getMainClass().convention(resolveProvider.flatMap(ResolveMainClassName::readMainClassName));
|
||||
}
|
||||
catch (NoSuchMethodError ex) {
|
||||
run.getInputs().file(resolveProvider.map((task) -> task.getOutputFile()));
|
||||
run.conventionMapping("main",
|
||||
() -> resolveProvider.flatMap(ResolveMainClassName::readMainClassName).get());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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.gradle.plugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.gradle.api.InvalidUserDataException;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.file.FileCollection;
|
||||
import org.gradle.api.plugins.JavaApplication;
|
||||
import org.gradle.api.provider.Property;
|
||||
|
||||
import org.springframework.boot.gradle.dsl.SpringBootExtension;
|
||||
import org.springframework.boot.loader.tools.MainClassFinder;
|
||||
|
||||
/**
|
||||
* A {@link Callable} that provides a convention for the project's main class name.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
final class MainClassConvention implements Callable<String> {
|
||||
|
||||
private static final String SPRING_BOOT_APPLICATION_CLASS_NAME = "org.springframework.boot.autoconfigure.SpringBootApplication";
|
||||
|
||||
private final Project project;
|
||||
|
||||
private final Supplier<FileCollection> classpathSupplier;
|
||||
|
||||
MainClassConvention(Project project, Supplier<FileCollection> classpathSupplier) {
|
||||
this.project = project;
|
||||
this.classpathSupplier = classpathSupplier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String call() throws Exception {
|
||||
SpringBootExtension springBootExtension = this.project.getExtensions().findByType(SpringBootExtension.class);
|
||||
if (springBootExtension != null) {
|
||||
String mainClass = springBootExtension.getMainClass().getOrNull();
|
||||
if (mainClass != null) {
|
||||
return mainClass;
|
||||
}
|
||||
}
|
||||
String javaApplicationMainClass = getJavaApplicationMainClass();
|
||||
return (javaApplicationMainClass != null) ? javaApplicationMainClass : resolveMainClass();
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "deprecation" })
|
||||
private String getJavaApplicationMainClass() {
|
||||
JavaApplication javaApplication = this.project.getConvention().findByType(JavaApplication.class);
|
||||
if (javaApplication == null) {
|
||||
return null;
|
||||
}
|
||||
Method getMainClass = findMethod(JavaApplication.class, "getMainClass");
|
||||
if (getMainClass != null) {
|
||||
try {
|
||||
Property<String> mainClass = (Property<String>) getMainClass.invoke(javaApplication);
|
||||
return mainClass.getOrElse(null);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Continue
|
||||
}
|
||||
}
|
||||
return javaApplication.getMainClassName();
|
||||
}
|
||||
|
||||
private static Method findMethod(Class<?> type, String name) {
|
||||
for (Method candidate : type.getMethods()) {
|
||||
if (candidate.getName().equals(name)) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String resolveMainClass() {
|
||||
return this.classpathSupplier.get().filter(File::isDirectory).getFiles().stream().map(this::findMainClass)
|
||||
.filter(Objects::nonNull).findFirst().orElseThrow(() -> new InvalidUserDataException(
|
||||
"Main class name has not been configured and it could not be resolved"));
|
||||
}
|
||||
|
||||
private String findMainClass(File file) {
|
||||
try {
|
||||
return MainClassFinder.findSingleMainClass(file, SPRING_BOOT_APPLICATION_CLASS_NAME);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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.gradle.plugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.gradle.api.DefaultTask;
|
||||
import org.gradle.api.InvalidUserDataException;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.Task;
|
||||
import org.gradle.api.file.FileCollection;
|
||||
import org.gradle.api.file.RegularFileProperty;
|
||||
import org.gradle.api.plugins.BasePlugin;
|
||||
import org.gradle.api.plugins.Convention;
|
||||
import org.gradle.api.plugins.JavaApplication;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.Classpath;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.Optional;
|
||||
import org.gradle.api.tasks.OutputFile;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
import org.gradle.api.tasks.TaskProvider;
|
||||
|
||||
import org.springframework.boot.gradle.dsl.SpringBootExtension;
|
||||
import org.springframework.boot.loader.tools.MainClassFinder;
|
||||
|
||||
/**
|
||||
* {@link Task} for resolving the name of the application's main class.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 2.4
|
||||
*/
|
||||
public class ResolveMainClassName extends DefaultTask {
|
||||
|
||||
private static final String SPRING_BOOT_APPLICATION_CLASS_NAME = "org.springframework.boot.autoconfigure.SpringBootApplication";
|
||||
|
||||
private final RegularFileProperty outputFile;
|
||||
|
||||
private final Property<String> configuredMainClass;
|
||||
|
||||
private FileCollection classpath;
|
||||
|
||||
/**
|
||||
* Creates a new instance of the {@code ResolveMainClassName} task.
|
||||
*/
|
||||
public ResolveMainClassName() {
|
||||
this.outputFile = getProject().getObjects().fileProperty();
|
||||
this.configuredMainClass = getProject().getObjects().property(String.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the classpath that the task will examine when resolving the main class
|
||||
* name.
|
||||
* @return the classpath
|
||||
*/
|
||||
@Classpath
|
||||
public FileCollection getClasspath() {
|
||||
return this.classpath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the classpath that the task will examine when resolving the main class name.
|
||||
* @param classpath the classpath
|
||||
*/
|
||||
public void setClasspath(FileCollection classpath) {
|
||||
this.classpath = classpath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the property for the task's output file that will contain the name of the
|
||||
* main class.
|
||||
* @return the output file
|
||||
*/
|
||||
@OutputFile
|
||||
public RegularFileProperty getOutputFile() {
|
||||
return this.outputFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the property for the explicitly configured main class name that should be
|
||||
* used in favour of resolving the main class name from the classpath.
|
||||
* @return the configured main class name property
|
||||
*/
|
||||
@Input
|
||||
@Optional
|
||||
public Property<String> getConfiguredMainClassName() {
|
||||
return this.configuredMainClass;
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
void resolveAndStoreMainClassName() throws IOException {
|
||||
File outputFile = this.outputFile.getAsFile().get();
|
||||
outputFile.getParentFile().mkdirs();
|
||||
String mainClassName = resolveMainClassName();
|
||||
Files.write(outputFile.toPath(), mainClassName.getBytes(StandardCharsets.UTF_8), StandardOpenOption.WRITE,
|
||||
StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
|
||||
}
|
||||
|
||||
private String resolveMainClassName() {
|
||||
String configuredMainClass = this.configuredMainClass.getOrNull();
|
||||
if (configuredMainClass != null) {
|
||||
return configuredMainClass;
|
||||
}
|
||||
return getClasspath().filter(File::isDirectory).getFiles().stream().map(this::findMainClass)
|
||||
.filter(Objects::nonNull).findFirst().orElse("");
|
||||
}
|
||||
|
||||
private String findMainClass(File file) {
|
||||
try {
|
||||
return MainClassFinder.findSingleMainClass(file, SPRING_BOOT_APPLICATION_CLASS_NAME);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Provider<String> readMainClassName() {
|
||||
return this.outputFile.map((file) -> {
|
||||
if (file.getAsFile().length() == 0) {
|
||||
throw new InvalidUserDataException(
|
||||
"Main class name has not been configured and it could not be resolved");
|
||||
}
|
||||
Path output = file.getAsFile().toPath();
|
||||
try {
|
||||
return new String(Files.readAllBytes(output), StandardCharsets.UTF_8);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new RuntimeException("Failed to read main class name from '" + output + "'");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static TaskProvider<ResolveMainClassName> registerForTask(String taskName, Project project,
|
||||
FileCollection classpath) {
|
||||
TaskProvider<ResolveMainClassName> resolveMainClassNameProvider = project.getTasks()
|
||||
.register(taskName + "MainClassName", ResolveMainClassName.class, (resolveMainClassName) -> {
|
||||
Convention convention = project.getConvention();
|
||||
resolveMainClassName.setDescription(
|
||||
"Resolves the name of the application's main class for the " + taskName + " task.");
|
||||
resolveMainClassName.setGroup(BasePlugin.BUILD_GROUP);
|
||||
resolveMainClassName.setClasspath(classpath);
|
||||
resolveMainClassName.getConfiguredMainClassName().convention(project.provider(() -> {
|
||||
String javaApplicationMainClass = getJavaApplicationMainClass(convention);
|
||||
if (javaApplicationMainClass != null) {
|
||||
return javaApplicationMainClass;
|
||||
}
|
||||
SpringBootExtension springBootExtension = project.getExtensions()
|
||||
.findByType(SpringBootExtension.class);
|
||||
return springBootExtension.getMainClass().getOrNull();
|
||||
}));
|
||||
resolveMainClassName.getOutputFile()
|
||||
.set(project.getLayout().getBuildDirectory().file(taskName + "MainClassName"));
|
||||
});
|
||||
return resolveMainClassNameProvider;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private static String getJavaApplicationMainClass(Convention convention) {
|
||||
JavaApplication javaApplication = convention.findByType(JavaApplication.class);
|
||||
if (javaApplication == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return javaApplication.getMainClass().getOrNull();
|
||||
}
|
||||
catch (NoSuchMethodError ex) {
|
||||
return javaApplication.getMainClassName();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -25,6 +25,9 @@ import org.gradle.api.file.FileCollection;
|
||||
import org.gradle.api.internal.artifacts.dsl.LazyPublishArtifact;
|
||||
import org.gradle.api.plugins.BasePlugin;
|
||||
import org.gradle.api.plugins.WarPlugin;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.SourceSet;
|
||||
import org.gradle.api.tasks.SourceSetContainer;
|
||||
import org.gradle.api.tasks.TaskProvider;
|
||||
|
||||
import org.springframework.boot.gradle.tasks.bundling.BootWar;
|
||||
@@ -60,23 +63,31 @@ class WarPluginAction implements PluginApplicationAction {
|
||||
}
|
||||
|
||||
private TaskProvider<BootWar> configureBootWarTask(Project project) {
|
||||
return project.getTasks().register(SpringBootPlugin.BOOT_WAR_TASK_NAME, BootWar.class, (bootWar) -> {
|
||||
bootWar.setGroup(BasePlugin.BUILD_GROUP);
|
||||
bootWar.setDescription("Assembles an executable war archive containing webapp"
|
||||
+ " content, and the main classes and their dependencies.");
|
||||
bootWar.providedClasspath(providedRuntimeConfiguration(project));
|
||||
Configuration developmentOnly = project.getConfigurations()
|
||||
.getByName(SpringBootPlugin.DEVELOPMENT_ONLY_CONFIGURATION_NAME);
|
||||
Configuration productionRuntimeClasspath = project.getConfigurations()
|
||||
.getByName(SpringBootPlugin.PRODUCTION_RUNTIME_CLASSPATH_NAME);
|
||||
bootWar.setClasspath(bootWar.getClasspath().minus((developmentOnly.minus(productionRuntimeClasspath)))
|
||||
.filter(new JarTypeFileSpec()));
|
||||
bootWar.getMainClass().convention(project.provider(() -> {
|
||||
String manifestStartClass = (String) bootWar.getManifest().getAttributes().get("Start-Class");
|
||||
return (manifestStartClass != null) ? manifestStartClass
|
||||
: new MainClassConvention(project, bootWar::getClasspath).call();
|
||||
}));
|
||||
});
|
||||
Configuration developmentOnly = project.getConfigurations()
|
||||
.getByName(SpringBootPlugin.DEVELOPMENT_ONLY_CONFIGURATION_NAME);
|
||||
Configuration productionRuntimeClasspath = project.getConfigurations()
|
||||
.getByName(SpringBootPlugin.PRODUCTION_RUNTIME_CLASSPATH_NAME);
|
||||
FileCollection classpath = project.getConvention().getByType(SourceSetContainer.class)
|
||||
.getByName(SourceSet.MAIN_SOURCE_SET_NAME).getRuntimeClasspath()
|
||||
.minus(providedRuntimeConfiguration(project)).minus((developmentOnly.minus(productionRuntimeClasspath)))
|
||||
.filter(new JarTypeFileSpec());
|
||||
TaskProvider<ResolveMainClassName> resolveMainClassName = ResolveMainClassName
|
||||
.registerForTask(SpringBootPlugin.BOOT_WAR_TASK_NAME, project, classpath);
|
||||
TaskProvider<BootWar> bootWarProvider = project.getTasks().register(SpringBootPlugin.BOOT_WAR_TASK_NAME,
|
||||
BootWar.class, (bootWar) -> {
|
||||
bootWar.setGroup(BasePlugin.BUILD_GROUP);
|
||||
bootWar.setDescription("Assembles an executable war archive containing webapp"
|
||||
+ " content, and the main classes and their dependencies.");
|
||||
bootWar.providedClasspath(providedRuntimeConfiguration(project));
|
||||
bootWar.setClasspath(classpath);
|
||||
Provider<String> manifestStartClass = project
|
||||
.provider(() -> (String) bootWar.getManifest().getAttributes().get("Start-Class"));
|
||||
bootWar.getMainClass()
|
||||
.convention(resolveMainClassName.flatMap((resolver) -> manifestStartClass.isPresent()
|
||||
? manifestStartClass : resolveMainClassName.get().readMainClassName()));
|
||||
});
|
||||
bootWarProvider.map((bootWar) -> bootWar.getClasspath());
|
||||
return bootWarProvider;
|
||||
}
|
||||
|
||||
private FileCollection providedRuntimeConfiguration(Project project) {
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.Map;
|
||||
import org.gradle.api.Action;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.Task;
|
||||
import org.gradle.api.file.DirectoryProperty;
|
||||
import org.gradle.api.internal.ConventionTask;
|
||||
import org.gradle.api.tasks.Nested;
|
||||
import org.gradle.api.tasks.OutputDirectory;
|
||||
@@ -44,7 +45,12 @@ public class BuildInfo extends ConventionTask {
|
||||
|
||||
private final BuildInfoProperties properties = new BuildInfoProperties(getProject());
|
||||
|
||||
private File destinationDir;
|
||||
private final DirectoryProperty destinationDir;
|
||||
|
||||
public BuildInfo() {
|
||||
this.destinationDir = getProject().getObjects().directoryProperty()
|
||||
.convention(getProject().getLayout().getBuildDirectory());
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the {@code build-info.properties} file in the configured
|
||||
@@ -73,7 +79,7 @@ public class BuildInfo extends ConventionTask {
|
||||
*/
|
||||
@OutputDirectory
|
||||
public File getDestinationDir() {
|
||||
return (this.destinationDir != null) ? this.destinationDir : getProject().getBuildDir();
|
||||
return this.destinationDir.getAsFile().get();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,7 +87,7 @@ public class BuildInfo extends ConventionTask {
|
||||
* @param destinationDir the destination directory
|
||||
*/
|
||||
public void setDestinationDir(File destinationDir) {
|
||||
this.destinationDir = destinationDir;
|
||||
this.destinationDir.set(destinationDir);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.boot.gradle.tasks.buildinfo;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.HashMap;
|
||||
@@ -23,6 +25,7 @@ import java.util.Map;
|
||||
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.Optional;
|
||||
|
||||
@@ -35,6 +38,8 @@ import org.gradle.api.tasks.Optional;
|
||||
@SuppressWarnings("serial")
|
||||
public class BuildInfoProperties implements Serializable {
|
||||
|
||||
private transient Instant creationTime = Instant.now();
|
||||
|
||||
private final Property<String> group;
|
||||
|
||||
private final Property<String> artifact;
|
||||
@@ -43,22 +48,35 @@ public class BuildInfoProperties implements Serializable {
|
||||
|
||||
private final Property<String> name;
|
||||
|
||||
private final Property<Instant> time;
|
||||
private final Property<Long> time;
|
||||
|
||||
private boolean timeConfigured = false;
|
||||
|
||||
private Map<String, Object> additionalProperties = new HashMap<>();
|
||||
|
||||
BuildInfoProperties(Project project) {
|
||||
this.time = project.getObjects().property(Instant.class);
|
||||
this.time.set(Instant.now());
|
||||
this.time = project.getObjects().property(Long.class);
|
||||
this.group = project.getObjects().property(String.class);
|
||||
this.group.set(project.provider(() -> project.getGroup().toString()));
|
||||
this.artifact = project.getObjects().property(String.class);
|
||||
this.version = project.getObjects().property(String.class);
|
||||
this.version.set(project.provider(() -> project.getVersion().toString()));
|
||||
this.version.set(projectVersion(project));
|
||||
this.name = project.getObjects().property(String.class);
|
||||
this.name.set(project.provider(project::getName));
|
||||
}
|
||||
|
||||
private Provider<String> projectVersion(Project project) {
|
||||
try {
|
||||
Provider<String> externalVersionProperty = project.getProviders().gradleProperty("version")
|
||||
.forUseAtConfigurationTime();
|
||||
externalVersionProperty.getOrNull();
|
||||
}
|
||||
catch (NoSuchMethodError ex) {
|
||||
// Gradle < 6.5
|
||||
}
|
||||
return project.provider(() -> project.getVersion().toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value used for the {@code build.group} property. Defaults to the
|
||||
* {@link Project#getGroup() Project's group}.
|
||||
@@ -142,7 +160,14 @@ public class BuildInfoProperties implements Serializable {
|
||||
@Input
|
||||
@Optional
|
||||
public Instant getTime() {
|
||||
return this.time.getOrNull();
|
||||
Long epochMillis = this.time.getOrNull();
|
||||
if (epochMillis != null) {
|
||||
return Instant.ofEpochMilli(epochMillis);
|
||||
}
|
||||
if (this.timeConfigured) {
|
||||
return null;
|
||||
}
|
||||
return this.creationTime;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -150,7 +175,8 @@ public class BuildInfoProperties implements Serializable {
|
||||
* @param time the build time
|
||||
*/
|
||||
public void setTime(Instant time) {
|
||||
this.time.set(time);
|
||||
this.timeConfigured = true;
|
||||
this.time.set((time != null) ? time.toEpochMilli() : null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -173,4 +199,9 @@ public class BuildInfoProperties implements Serializable {
|
||||
this.additionalProperties = additionalProperties;
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream input) throws ClassNotFoundException, IOException {
|
||||
input.defaultReadObject();
|
||||
this.creationTime = Instant.now();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -59,6 +59,10 @@ public class BootBuildImage extends DefaultTask {
|
||||
|
||||
private static final String BUILDPACK_JVM_VERSION_KEY = "BP_JVM_VERSION";
|
||||
|
||||
private final String projectName;
|
||||
|
||||
private final Property<String> projectVersion;
|
||||
|
||||
private RegularFileProperty jar;
|
||||
|
||||
private Property<JavaVersion> targetJavaVersion;
|
||||
@@ -84,6 +88,9 @@ public class BootBuildImage extends DefaultTask {
|
||||
public BootBuildImage() {
|
||||
this.jar = getProject().getObjects().fileProperty();
|
||||
this.targetJavaVersion = getProject().getObjects().property(JavaVersion.class);
|
||||
this.projectName = getProject().getName();
|
||||
this.projectVersion = getProject().getObjects().property(String.class);
|
||||
this.projectVersion.set(getProject().provider(() -> getProject().getVersion().toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -318,12 +325,11 @@ public class BootBuildImage extends DefaultTask {
|
||||
if (StringUtils.hasText(this.imageName)) {
|
||||
return ImageReference.of(this.imageName);
|
||||
}
|
||||
ImageName imageName = ImageName.of(getProject().getName());
|
||||
String version = getProject().getVersion().toString();
|
||||
if ("unspecified".equals(version)) {
|
||||
ImageName imageName = ImageName.of(this.projectName);
|
||||
if ("unspecified".equals(this.projectVersion.get())) {
|
||||
return ImageReference.of(imageName);
|
||||
}
|
||||
return ImageReference.of(imageName, version);
|
||||
return ImageReference.of(imageName, this.projectVersion.get());
|
||||
}
|
||||
|
||||
private BuildRequest customize(BuildRequest request) {
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.boot.gradle.tasks.bundling;
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.gradle.api.Action;
|
||||
import org.gradle.api.Project;
|
||||
@@ -72,7 +73,7 @@ public class BootJar extends Jar implements BootArchive {
|
||||
* Creates a new {@code BootJar} task.
|
||||
*/
|
||||
public BootJar() {
|
||||
this.support = new BootArchiveSupport(LAUNCHER, this::isLibrary, this::resolveZipCompression);
|
||||
this.support = new BootArchiveSupport(LAUNCHER, new LibrarySpec(), new ZipCompressionResolver());
|
||||
this.bootInfSpec = getProject().copySpec().into("BOOT-INF");
|
||||
this.mainClass = getProject().getObjects().property(String.class);
|
||||
configureBootInfSpec(this.bootInfSpec);
|
||||
@@ -325,4 +326,22 @@ public class BootJar extends Jar implements BootArchive {
|
||||
return this.resolvedDependencies;
|
||||
}
|
||||
|
||||
private final class LibrarySpec implements Spec<FileCopyDetails> {
|
||||
|
||||
@Override
|
||||
public boolean isSatisfiedBy(FileCopyDetails details) {
|
||||
return isLibrary(details);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final class ZipCompressionResolver implements Function<FileCopyDetails, ZipCompression> {
|
||||
|
||||
@Override
|
||||
public ZipCompression apply(FileCopyDetails details) {
|
||||
return resolveZipCompression(details);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.boot.gradle.tasks.bundling;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.gradle.api.Action;
|
||||
import org.gradle.api.Project;
|
||||
@@ -59,7 +60,7 @@ public class BootWar extends War implements BootArchive {
|
||||
* Creates a new {@code BootWar} task.
|
||||
*/
|
||||
public BootWar() {
|
||||
this.support = new BootArchiveSupport(LAUNCHER, this::isLibrary, this::resolveZipCompression);
|
||||
this.support = new BootArchiveSupport(LAUNCHER, new LibrarySpec(), new ZipCompressionResolver());
|
||||
this.mainClass = getProject().getObjects().property(String.class);
|
||||
getWebInf().into("lib-provided", fromCallTo(this::getProvidedLibFiles));
|
||||
this.support.moveModuleInfoToRoot(getRootSpec());
|
||||
@@ -232,4 +233,22 @@ public class BootWar extends War implements BootArchive {
|
||||
return callable;
|
||||
}
|
||||
|
||||
private final class LibrarySpec implements Spec<FileCopyDetails> {
|
||||
|
||||
@Override
|
||||
public boolean isSatisfiedBy(FileCopyDetails details) {
|
||||
return isLibrary(details);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final class ZipCompressionResolver implements Function<FileCopyDetails, ZipCompression> {
|
||||
|
||||
@Override
|
||||
public ZipCompression apply(FileCopyDetails details) {
|
||||
return resolveZipCompression(details);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
|
||||
package org.springframework.boot.gradle.tasks.run;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Set;
|
||||
|
||||
import org.gradle.api.file.SourceDirectorySet;
|
||||
import org.gradle.api.tasks.Input;
|
||||
@@ -63,8 +65,9 @@ public class BootRun extends JavaExec {
|
||||
* @param sourceSet the source set
|
||||
*/
|
||||
public void sourceResources(SourceSet sourceSet) {
|
||||
setClasspath(getProject().files(sourceSet.getResources().getSrcDirs(), getClasspath())
|
||||
.filter((file) -> !file.equals(sourceSet.getOutput().getResourcesDir())));
|
||||
File resourcesDir = sourceSet.getOutput().getResourcesDir();
|
||||
Set<File> srcDirs = sourceSet.getResources().getSrcDirs();
|
||||
setClasspath(getProject().files(srcDirs, getClasspath()).filter((file) -> !file.equals(resourcesDir)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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 com.example.main;
|
||||
|
||||
/**
|
||||
* Application used for testing {@code BootRun}'s main class configuration.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public class CustomMainClass {
|
||||
|
||||
protected CustomMainClass() {
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(CustomMainClass.class.getName());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,7 +17,9 @@
|
||||
package org.springframework.boot.gradle.docs;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
import org.junit.jupiter.api.TestTemplate;
|
||||
import org.junit.jupiter.api.condition.DisabledForJreRange;
|
||||
@@ -43,20 +45,23 @@ class RunningDocumentationTests {
|
||||
@TestTemplate
|
||||
@DisabledForJreRange(min = JRE.JAVA_13)
|
||||
void bootRunMain() throws IOException {
|
||||
assertThat(this.gradleBuild.script("src/docs/gradle/running/boot-run-main").build("configuredMainClass")
|
||||
.getOutput()).contains("com.example.ExampleApplication");
|
||||
writeMainClass();
|
||||
assertThat(this.gradleBuild.script("src/docs/gradle/running/boot-run-main").build("bootRun").getOutput())
|
||||
.contains("com.example.ExampleApplication");
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void applicationPluginMainClassName() {
|
||||
void applicationPluginMainClassName() throws IOException {
|
||||
writeMainClass();
|
||||
assertThat(this.gradleBuild.script("src/docs/gradle/running/application-plugin-main-class-name")
|
||||
.build("configuredMainClass").getOutput()).contains("com.example.ExampleApplication");
|
||||
.build("bootRun").getOutput()).contains("com.example.ExampleApplication");
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void springBootDslMainClassName() throws IOException {
|
||||
assertThat(this.gradleBuild.script("src/docs/gradle/running/spring-boot-dsl-main-class-name")
|
||||
.build("configuredMainClass").getOutput()).contains("com.example.ExampleApplication");
|
||||
writeMainClass();
|
||||
assertThat(this.gradleBuild.script("src/docs/gradle/running/spring-boot-dsl-main-class-name").build("bootRun")
|
||||
.getOutput()).contains("com.example.ExampleApplication");
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
@@ -84,4 +89,18 @@ class RunningDocumentationTests {
|
||||
.contains("com.example.property = custom");
|
||||
}
|
||||
|
||||
private void writeMainClass() throws IOException {
|
||||
File exampleApplication = new File(this.gradleBuild.getProjectDir(),
|
||||
"src/main/java/com/example/ExampleApplication.java");
|
||||
exampleApplication.getParentFile().mkdirs();
|
||||
try (PrintWriter writer = new PrintWriter(new FileWriter(exampleApplication))) {
|
||||
writer.println("package com.example;");
|
||||
writer.println("public class ExampleApplication {");
|
||||
writer.println(" public static void main(String[] args) {");
|
||||
writer.println(" System.out.println(ExampleApplication.class.getName());");
|
||||
writer.println(" }");
|
||||
writer.println("}");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -41,4 +41,11 @@ import org.springframework.boot.gradle.testkit.GradleBuild;
|
||||
@ExtendWith(GradleCompatibilityExtension.class)
|
||||
public @interface GradleCompatibility {
|
||||
|
||||
/**
|
||||
* Whether to include running Gradle with {@code --cache-configuration} cache in the
|
||||
* compatibility matrix.
|
||||
* @return {@code true} to enable the configuration cache, {@code false} otherwise
|
||||
*/
|
||||
boolean configurationCache() default false;
|
||||
|
||||
}
|
||||
|
||||
@@ -16,16 +16,19 @@
|
||||
|
||||
package org.springframework.boot.gradle.junit;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.gradle.api.JavaVersion;
|
||||
import org.gradle.util.GradleVersion;
|
||||
import org.junit.jupiter.api.TestTemplate;
|
||||
import org.junit.jupiter.api.extension.Extension;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.TestTemplateInvocationContext;
|
||||
import org.junit.jupiter.api.extension.TestTemplateInvocationContextProvider;
|
||||
import org.junit.platform.commons.util.AnnotationUtils;
|
||||
|
||||
import org.springframework.boot.gradle.testkit.GradleBuild;
|
||||
import org.springframework.boot.gradle.testkit.GradleBuildExtension;
|
||||
@@ -45,16 +48,29 @@ final class GradleCompatibilityExtension implements TestTemplateInvocationContex
|
||||
JavaVersion javaVersion = JavaVersion.current();
|
||||
if (javaVersion.isCompatibleWith(JavaVersion.VERSION_14)
|
||||
|| javaVersion.isCompatibleWith(JavaVersion.VERSION_13)) {
|
||||
GRADLE_VERSIONS = Arrays.asList("6.3", "6.4.1", "6.5.1", "6.6.1", "default");
|
||||
GRADLE_VERSIONS = Arrays.asList("6.3", "6.4.1", "6.5.1", "6.6.1", "current");
|
||||
}
|
||||
else {
|
||||
GRADLE_VERSIONS = Arrays.asList("5.6.4", "6.3", "6.4.1", "6.5.1", "6.6.1", "default");
|
||||
GRADLE_VERSIONS = Arrays.asList("5.6.4", "6.3", "6.4.1", "6.5.1", "6.6.1", "current");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<TestTemplateInvocationContext> provideTestTemplateInvocationContexts(ExtensionContext context) {
|
||||
return GRADLE_VERSIONS.stream().map(GradleVersionTestTemplateInvocationContext::new);
|
||||
return GRADLE_VERSIONS.stream().flatMap((version) -> {
|
||||
if (version.equals("current")) {
|
||||
version = GradleVersion.current().getVersion();
|
||||
}
|
||||
List<TestTemplateInvocationContext> invocationContexts = new ArrayList<>();
|
||||
invocationContexts.add(new GradleVersionTestTemplateInvocationContext(version, false));
|
||||
boolean configurationCache = AnnotationUtils
|
||||
.findAnnotation(context.getRequiredTestClass(), GradleCompatibility.class).get()
|
||||
.configurationCache();
|
||||
if (configurationCache && GradleVersion.version(version).compareTo(GradleVersion.version("6.7")) >= 0) {
|
||||
invocationContexts.add(new GradleVersionTestTemplateInvocationContext(version, true));
|
||||
}
|
||||
return invocationContexts.stream();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -66,20 +82,23 @@ final class GradleCompatibilityExtension implements TestTemplateInvocationContex
|
||||
|
||||
private final String gradleVersion;
|
||||
|
||||
GradleVersionTestTemplateInvocationContext(String gradleVersion) {
|
||||
private final boolean configurationCache;
|
||||
|
||||
GradleVersionTestTemplateInvocationContext(String gradleVersion, boolean configurationCache) {
|
||||
this.gradleVersion = gradleVersion;
|
||||
this.configurationCache = configurationCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayName(int invocationIndex) {
|
||||
return "Gradle " + this.gradleVersion;
|
||||
return "Gradle " + this.gradleVersion + ((this.configurationCache) ? " --configuration-cache" : "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Extension> getAdditionalExtensions() {
|
||||
GradleBuild gradleBuild = new GradleBuild();
|
||||
if (!this.gradleVersion.equals("default")) {
|
||||
gradleBuild.gradleVersion(this.gradleVersion);
|
||||
GradleBuild gradleBuild = new GradleBuild().gradleVersion(this.gradleVersion);
|
||||
if (this.configurationCache) {
|
||||
gradleBuild.configurationCache();
|
||||
}
|
||||
return Arrays.asList(new GradleBuildFieldSetter(gradleBuild), new GradleBuildExtension());
|
||||
}
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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.gradle.plugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.plugins.ApplicationPlugin;
|
||||
import org.gradle.api.plugins.JavaApplication;
|
||||
import org.gradle.testfixtures.ProjectBuilder;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import org.springframework.boot.gradle.dsl.SpringBootExtension;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link MainClassConvention}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
class MainClassConventionTests {
|
||||
|
||||
@TempDir
|
||||
File temp;
|
||||
|
||||
private Project project;
|
||||
|
||||
private MainClassConvention convention;
|
||||
|
||||
@BeforeEach
|
||||
void createConvention() throws IOException {
|
||||
this.project = ProjectBuilder.builder().withProjectDir(this.temp).build();
|
||||
this.convention = new MainClassConvention(this.project, () -> null);
|
||||
}
|
||||
|
||||
@Test
|
||||
void javaApplicationExtensionMainClassNameIsUsed() throws Exception {
|
||||
this.project.getPlugins().apply(ApplicationPlugin.class);
|
||||
JavaApplication extension = this.project.getExtensions().findByType(JavaApplication.class);
|
||||
extension.getMainClass().set("com.example.MainClass");
|
||||
assertThat(this.convention.call()).isEqualTo("com.example.MainClass");
|
||||
}
|
||||
|
||||
@Test
|
||||
void springBootExtensionMainClassNameIsUsed() throws Exception {
|
||||
SpringBootExtension extension = this.project.getExtensions().create("springBoot", SpringBootExtension.class,
|
||||
this.project);
|
||||
extension.getMainClass().set("com.example.MainClass");
|
||||
assertThat(this.convention.call()).isEqualTo("com.example.MainClass");
|
||||
}
|
||||
|
||||
@Test
|
||||
void springBootExtensionMainClassNameIsUsedInPreferenceToJavaApplicationExtensionMainClassName() throws Exception {
|
||||
this.project.getPlugins().apply(ApplicationPlugin.class);
|
||||
JavaApplication javaApplication = this.project.getExtensions().findByType(JavaApplication.class);
|
||||
javaApplication.getMainClass().set("com.example.JavaApplicationMainClass");
|
||||
SpringBootExtension extension = this.project.getExtensions().create("springBoot", SpringBootExtension.class,
|
||||
this.project);
|
||||
extension.getMainClass().set("com.example.SpringBootExtensionMainClass");
|
||||
assertThat(this.convention.call()).isEqualTo("com.example.SpringBootExtensionMainClass");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,9 +19,13 @@ package org.springframework.boot.gradle.tasks.buildinfo;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.time.Instant;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.gradle.testkit.runner.BuildResult;
|
||||
import org.gradle.testkit.runner.InvalidRunnerConfigurationException;
|
||||
import org.gradle.testkit.runner.TaskOutcome;
|
||||
import org.gradle.testkit.runner.UnexpectedBuildFailure;
|
||||
@@ -38,7 +42,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@GradleCompatibility
|
||||
@GradleCompatibility(configurationCache = true)
|
||||
class BuildInfoIntegrationTests {
|
||||
|
||||
GradleBuild gradleBuild;
|
||||
@@ -69,7 +73,14 @@ class BuildInfoIntegrationTests {
|
||||
@TestTemplate
|
||||
void notUpToDateWhenExecutedTwiceAsTimeChanges() {
|
||||
assertThat(this.gradleBuild.build("buildInfo").task(":buildInfo").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
Properties first = buildInfoProperties();
|
||||
String firstBuildTime = first.getProperty("build.time");
|
||||
assertThat(firstBuildTime).isNotNull();
|
||||
assertThat(this.gradleBuild.build("buildInfo").task(":buildInfo").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
Properties second = buildInfoProperties();
|
||||
String secondBuildTime = second.getProperty("build.time");
|
||||
assertThat(secondBuildTime).isNotNull();
|
||||
assertThat(Instant.parse(firstBuildTime).isBefore(Instant.parse(secondBuildTime)));
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
@@ -81,11 +92,22 @@ class BuildInfoIntegrationTests {
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void notUpToDateWhenExecutedTwiceWithFixedTimeAndChangedProjectVersion() {
|
||||
assertThat(this.gradleBuild.build("buildInfo", "-PnullTime").task(":buildInfo").getOutcome())
|
||||
.isEqualTo(TaskOutcome.SUCCESS);
|
||||
BuildResult result = this.gradleBuild.build("buildInfo", "-PnullTime", "-PprojectVersion=0.2.0");
|
||||
assertThat(result.task(":buildInfo").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
void notUpToDateWhenExecutedTwiceWithFixedTimeAndChangedProjectVersion() throws IOException {
|
||||
assertThat(this.gradleBuild.scriptProperty("projectVersion", "0.1.0").build("buildInfo").task(":buildInfo")
|
||||
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
assertThat(this.gradleBuild.scriptProperty("projectVersion", "0.2.0").build("buildInfo").task(":buildInfo")
|
||||
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void notUpToDateWhenExecutedTwiceWithFixedTimeAndChangedGradlePropertiesProjectVersion() throws IOException {
|
||||
Path gradleProperties = new File(this.gradleBuild.getProjectDir(), "gradle.properties").toPath();
|
||||
Files.write(gradleProperties, "version=0.1.0".getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE,
|
||||
StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING);
|
||||
assertThat(this.gradleBuild.build("buildInfo").task(":buildInfo").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
Files.write(gradleProperties, "version=0.2.0".getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE,
|
||||
StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING);
|
||||
assertThat(this.gradleBuild.build("buildInfo").task(":buildInfo").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
|
||||
@@ -24,6 +24,8 @@ import java.time.format.DateTimeFormatter;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.internal.project.ProjectInternal;
|
||||
import org.gradle.initialization.GradlePropertiesController;
|
||||
import org.gradle.testfixtures.ProjectBuilder;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
@@ -125,7 +127,10 @@ class BuildInfoTests {
|
||||
|
||||
private Project createProject(String projectName) {
|
||||
File projectDir = new File(this.temp, projectName);
|
||||
return ProjectBuilder.builder().withProjectDir(projectDir).withName(projectName).build();
|
||||
Project project = ProjectBuilder.builder().withProjectDir(projectDir).withName(projectName).build();
|
||||
((ProjectInternal) project).getServices().get(GradlePropertiesController.class)
|
||||
.loadGradlePropertiesFrom(projectDir);
|
||||
return project;
|
||||
}
|
||||
|
||||
private BuildInfo createTask(Project project) {
|
||||
|
||||
@@ -32,9 +32,9 @@ import org.gradle.testkit.runner.TaskOutcome;
|
||||
import org.gradle.testkit.runner.UnexpectedBuildFailure;
|
||||
import org.junit.jupiter.api.TestTemplate;
|
||||
|
||||
import org.springframework.boot.gradle.junit.GradleCompatibility;
|
||||
import org.springframework.boot.gradle.testkit.GradleBuild;
|
||||
import org.springframework.boot.loader.tools.FileUtils;
|
||||
import org.springframework.util.FileSystemUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -43,7 +43,6 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@GradleCompatibility
|
||||
abstract class AbstractBootArchiveIntegrationTests {
|
||||
|
||||
private final String taskName;
|
||||
@@ -99,25 +98,25 @@ abstract class AbstractBootArchiveIntegrationTests {
|
||||
|
||||
@TestTemplate
|
||||
void notUpToDateWhenLaunchScriptWasNotIncludedAndThenIsIncluded() {
|
||||
assertThat(this.gradleBuild.build(this.taskName).task(":" + this.taskName).getOutcome())
|
||||
.isEqualTo(TaskOutcome.SUCCESS);
|
||||
assertThat(this.gradleBuild.build("-PincludeLaunchScript=true", this.taskName).task(":" + this.taskName)
|
||||
assertThat(this.gradleBuild.scriptProperty("launchScript", "").build(this.taskName).task(":" + this.taskName)
|
||||
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
assertThat(this.gradleBuild.scriptProperty("launchScript", "launchScript()").build(this.taskName)
|
||||
.task(":" + this.taskName).getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void notUpToDateWhenLaunchScriptWasIncludedAndThenIsNotIncluded() {
|
||||
assertThat(this.gradleBuild.build(this.taskName).task(":" + this.taskName).getOutcome())
|
||||
.isEqualTo(TaskOutcome.SUCCESS);
|
||||
assertThat(this.gradleBuild.build("-PincludeLaunchScript=true", this.taskName).task(":" + this.taskName)
|
||||
assertThat(this.gradleBuild.scriptProperty("launchScript", "launchScript()").build(this.taskName)
|
||||
.task(":" + this.taskName).getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
assertThat(this.gradleBuild.scriptProperty("launchScript", "").build(this.taskName).task(":" + this.taskName)
|
||||
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void notUpToDateWhenLaunchScriptPropertyChanges() {
|
||||
assertThat(this.gradleBuild.build("-PincludeLaunchScript=true", "-PlaunchScriptProperty=foo", this.taskName)
|
||||
assertThat(this.gradleBuild.scriptProperty("launchScriptProperty", "alpha").build(this.taskName)
|
||||
.task(":" + this.taskName).getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
assertThat(this.gradleBuild.build("-PincludeLaunchScript=true", "-PlaunchScriptProperty=bar", this.taskName)
|
||||
assertThat(this.gradleBuild.scriptProperty("launchScriptProperty", "bravo").build(this.taskName)
|
||||
.task(":" + this.taskName).getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
}
|
||||
|
||||
@@ -190,6 +189,27 @@ abstract class AbstractBootArchiveIntegrationTests {
|
||||
}
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void startClassIsSetByResolvingTheMainClass() throws IOException {
|
||||
copyMainClassApplication();
|
||||
assertThat(this.gradleBuild.build(this.taskName).task(":" + this.taskName).getOutcome())
|
||||
.isEqualTo(TaskOutcome.SUCCESS);
|
||||
try (JarFile jarFile = new JarFile(new File(this.gradleBuild.getProjectDir(), "build/libs").listFiles()[0])) {
|
||||
Attributes mainAttributes = jarFile.getManifest().getMainAttributes();
|
||||
assertThat(mainAttributes.getValue("Start-Class")).isEqualTo("com.example.main.CustomMainClass");
|
||||
}
|
||||
}
|
||||
|
||||
private void copyMainClassApplication() throws IOException {
|
||||
copyApplication("main");
|
||||
}
|
||||
|
||||
private void copyApplication(String name) throws IOException {
|
||||
File output = new File(this.gradleBuild.getProjectDir(), "src/main/java/com/example/" + name);
|
||||
output.mkdirs();
|
||||
FileSystemUtils.copyRecursively(new File("src/test/java/com/example/" + name), output);
|
||||
}
|
||||
|
||||
private void createStandardJar(File location) throws IOException {
|
||||
createJar(location, (attributes) -> {
|
||||
});
|
||||
|
||||
@@ -46,7 +46,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Andy Wilkinson
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
@GradleCompatibility
|
||||
@GradleCompatibility(configurationCache = true)
|
||||
@DisabledIfDockerUnavailable
|
||||
class BootBuildImageIntegrationTests {
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ import org.gradle.testkit.runner.TaskOutcome;
|
||||
import org.gradle.testkit.runner.UnexpectedBuildFailure;
|
||||
import org.junit.jupiter.api.TestTemplate;
|
||||
|
||||
import org.springframework.boot.gradle.junit.GradleCompatibility;
|
||||
import org.springframework.boot.loader.tools.JarModeLibrary;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -55,43 +56,39 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Madhura Bhave
|
||||
* @author Paddy Drury
|
||||
*/
|
||||
@GradleCompatibility(configurationCache = true)
|
||||
class BootJarIntegrationTests extends AbstractBootArchiveIntegrationTests {
|
||||
|
||||
BootJarIntegrationTests() {
|
||||
super("bootJar", "BOOT-INF/lib/", "BOOT-INF/classes/");
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void upToDateWhenBuiltTwiceWithLayers() throws InvalidRunnerConfigurationException, UnexpectedBuildFailure {
|
||||
assertThat(this.gradleBuild.build("-PcustomizeLayered=true", "bootJar").task(":bootJar").getOutcome())
|
||||
.isEqualTo(TaskOutcome.SUCCESS);
|
||||
assertThat(this.gradleBuild.build("-PcustomizeLayered=true", "bootJar").task(":bootJar").getOutcome())
|
||||
.isEqualTo(TaskOutcome.UP_TO_DATE);
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void upToDateWhenBuiltWithDefaultLayeredAndThenWithExplicitLayered()
|
||||
throws InvalidRunnerConfigurationException, UnexpectedBuildFailure {
|
||||
assertThat(this.gradleBuild.build("bootJar").task(":bootJar").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
assertThat(this.gradleBuild.build("-PcustomizeLayered=true", "bootJar").task(":bootJar").getOutcome())
|
||||
.isEqualTo(TaskOutcome.UP_TO_DATE);
|
||||
assertThat(this.gradleBuild.scriptProperty("layered", "").build("bootJar").task(":bootJar").getOutcome())
|
||||
.isEqualTo(TaskOutcome.SUCCESS);
|
||||
assertThat(
|
||||
this.gradleBuild.scriptProperty("layered", "layered {}").build("bootJar").task(":bootJar").getOutcome())
|
||||
.isEqualTo(TaskOutcome.UP_TO_DATE);
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void notUpToDateWhenBuiltWithoutLayersAndThenWithLayers()
|
||||
throws InvalidRunnerConfigurationException, UnexpectedBuildFailure {
|
||||
assertThat(this.gradleBuild.build("-PcustomizeLayered=true", "-PdisableLayers=true", "bootJar").task(":bootJar")
|
||||
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
assertThat(this.gradleBuild.build("-PcustomizeLayered=true", "bootJar").task(":bootJar").getOutcome())
|
||||
.isEqualTo(TaskOutcome.SUCCESS);
|
||||
assertThat(this.gradleBuild.scriptProperty("layerEnablement", "enabled = false").build("bootJar")
|
||||
.task(":bootJar").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
assertThat(this.gradleBuild.scriptProperty("layerEnablement", "enabled = true").build("bootJar")
|
||||
.task(":bootJar").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void notUpToDateWhenBuiltWithLayerToolsAndThenWithoutLayerTools()
|
||||
throws InvalidRunnerConfigurationException, UnexpectedBuildFailure {
|
||||
assertThat(this.gradleBuild.build("bootJar").task(":bootJar").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
assertThat(this.gradleBuild.build("-PcustomizeLayered=true", "-PexcludeTools=true", "bootJar").task(":bootJar")
|
||||
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
assertThat(this.gradleBuild.scriptProperty("layerTools", "").build("bootJar").task(":bootJar").getOutcome())
|
||||
.isEqualTo(TaskOutcome.SUCCESS);
|
||||
assertThat(this.gradleBuild.scriptProperty("layerTools", "includeLayerTools = false").build("bootJar")
|
||||
.task(":bootJar").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
|
||||
@@ -16,11 +16,14 @@
|
||||
|
||||
package org.springframework.boot.gradle.tasks.bundling;
|
||||
|
||||
import org.springframework.boot.gradle.junit.GradleCompatibility;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link BootJar}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@GradleCompatibility(configurationCache = true)
|
||||
class BootWarIntegrationTests extends AbstractBootArchiveIntegrationTests {
|
||||
|
||||
BootWarIntegrationTests() {
|
||||
|
||||
@@ -40,7 +40,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@GradleCompatibility
|
||||
@GradleCompatibility(configurationCache = true)
|
||||
class BootRunIntegrationTests {
|
||||
|
||||
GradleBuild gradleBuild;
|
||||
@@ -68,23 +68,25 @@ class BootRunIntegrationTests {
|
||||
|
||||
@TestTemplate
|
||||
void springBootExtensionMainClassNameIsUsed() throws IOException {
|
||||
BuildResult result = this.gradleBuild.build("echoMainClassName");
|
||||
assertThat(result.task(":echoMainClassName").getOutcome()).isEqualTo(TaskOutcome.UP_TO_DATE);
|
||||
assertThat(result.getOutput()).contains("Main class name = com.example.CustomMainClass");
|
||||
copyMainClassApplication();
|
||||
BuildResult result = this.gradleBuild.build("bootRun");
|
||||
assertThat(result.task(":bootRun").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
assertThat(result.getOutput()).contains("com.example.main.CustomMainClass");
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void applicationPluginMainClassNameIsUsed() throws IOException {
|
||||
BuildResult result = this.gradleBuild.build("echoMainClassName");
|
||||
assertThat(result.task(":echoMainClassName").getOutcome()).isEqualTo(TaskOutcome.UP_TO_DATE);
|
||||
assertThat(result.getOutput()).contains("Main class name = com.example.CustomMainClass");
|
||||
copyMainClassApplication();
|
||||
BuildResult result = this.gradleBuild.build("bootRun");
|
||||
assertThat(result.task(":bootRun").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
assertThat(result.getOutput()).contains("com.example.main.CustomMainClass");
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void applicationPluginMainClassNameIsNotUsedWhenItIsNull() throws IOException {
|
||||
copyClasspathApplication();
|
||||
BuildResult result = this.gradleBuild.build("echoMainClassName");
|
||||
assertThat(result.task(":echoMainClassName").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
BuildResult result = this.gradleBuild.build("bootRun");
|
||||
assertThat(result.task(":bootRun").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
assertThat(result.getOutput()).contains("Main class name = com.example.classpath.BootRunClasspathApplication");
|
||||
}
|
||||
|
||||
@@ -135,6 +137,10 @@ class BootRunIntegrationTests {
|
||||
assertThat(result.getOutput()).contains("standard.jar").doesNotContain("starter.jar");
|
||||
}
|
||||
|
||||
private void copyMainClassApplication() throws IOException {
|
||||
copyApplication("main");
|
||||
}
|
||||
|
||||
private void copyClasspathApplication() throws IOException {
|
||||
copyApplication("classpath");
|
||||
}
|
||||
|
||||
@@ -24,7 +24,10 @@ import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonView;
|
||||
@@ -72,8 +75,14 @@ public class GradleBuild {
|
||||
|
||||
private GradleVersion expectDeprecationWarnings;
|
||||
|
||||
private boolean configurationCache = false;
|
||||
|
||||
private Map<String, String> scriptProperties = new HashMap<>();
|
||||
|
||||
public GradleBuild() {
|
||||
this(Dsl.GROOVY);
|
||||
this.scriptProperties.put("bootVersion", getBootVersion());
|
||||
this.scriptProperties.put("dependencyManagementPluginVersion", getDependencyManagementPluginVersion());
|
||||
}
|
||||
|
||||
public GradleBuild(Dsl dsl) {
|
||||
@@ -124,6 +133,16 @@ public class GradleBuild {
|
||||
return this;
|
||||
}
|
||||
|
||||
public GradleBuild configurationCache() {
|
||||
this.configurationCache = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GradleBuild scriptProperty(String key, String value) {
|
||||
this.scriptProperties.put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public BuildResult build(String... arguments) {
|
||||
try {
|
||||
BuildResult result = prepareRunner(arguments).build();
|
||||
@@ -148,15 +167,16 @@ public class GradleBuild {
|
||||
}
|
||||
|
||||
public GradleRunner prepareRunner(String... arguments) throws IOException {
|
||||
String scriptContent = FileCopyUtils.copyToString(new FileReader(this.script))
|
||||
.replace("{version}", getBootVersion())
|
||||
.replace("{dependency-management-plugin-version}", getDependencyManagementPluginVersion());
|
||||
String scriptContent = FileCopyUtils.copyToString(new FileReader(this.script));
|
||||
for (Entry<String, String> property : this.scriptProperties.entrySet()) {
|
||||
scriptContent = scriptContent.replace("{" + property.getKey() + "}", property.getValue());
|
||||
}
|
||||
FileCopyUtils.copy(scriptContent, new FileWriter(new File(this.projectDir, "build" + this.dsl.getExtension())));
|
||||
FileSystemUtils.copyRecursively(new File("src/test/resources/repository"),
|
||||
new File(this.projectDir, "repository"));
|
||||
GradleRunner gradleRunner = GradleRunner.create().withProjectDir(this.projectDir)
|
||||
.withPluginClasspath(pluginClasspath());
|
||||
if (this.dsl != Dsl.KOTLIN) {
|
||||
if (this.dsl != Dsl.KOTLIN && !this.configurationCache) {
|
||||
// see https://github.com/gradle/gradle/issues/6862
|
||||
gradleRunner.withDebug(true);
|
||||
}
|
||||
@@ -169,6 +189,9 @@ public class GradleBuild {
|
||||
allArguments.addAll(Arrays.asList(arguments));
|
||||
allArguments.add("--warning-mode");
|
||||
allArguments.add("all");
|
||||
if (this.configurationCache) {
|
||||
allArguments.add("--configuration-cache");
|
||||
}
|
||||
return gradleRunner.withArguments(allArguments);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
plugins {
|
||||
id 'org.springframework.boot' version '{version}' apply false
|
||||
}
|
||||
|
||||
version = '0.1.0'
|
||||
|
||||
task buildInfo(type: org.springframework.boot.gradle.tasks.buildinfo.BuildInfo) {
|
||||
destinationDir project.buildDir
|
||||
properties {
|
||||
artifact = 'foo'
|
||||
group = 'foo'
|
||||
name = 'foo'
|
||||
additional = ['additional': 'foo']
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,4 @@ plugins {
|
||||
id 'org.springframework.boot' version '{version}' apply false
|
||||
}
|
||||
|
||||
def property(String name, Object defaultValue) {
|
||||
project.hasProperty(name) ? project.getProperty(name) : defaultValue
|
||||
}
|
||||
|
||||
task buildInfo(type: org.springframework.boot.gradle.tasks.buildinfo.BuildInfo)
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
plugins {
|
||||
id 'org.springframework.boot' version '{version}' apply false
|
||||
}
|
||||
|
||||
task buildInfo(type: org.springframework.boot.gradle.tasks.buildinfo.BuildInfo)
|
||||
@@ -0,0 +1,13 @@
|
||||
plugins {
|
||||
id 'org.springframework.boot' version '{version}' apply false
|
||||
}
|
||||
|
||||
task buildInfo(type: org.springframework.boot.gradle.tasks.buildinfo.BuildInfo) {
|
||||
properties {
|
||||
artifact = 'example'
|
||||
group = 'com.example'
|
||||
name = 'example'
|
||||
additional = ['additional': 'alpha']
|
||||
time = null
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
plugins {
|
||||
id 'org.springframework.boot' version '{version}' apply false
|
||||
}
|
||||
|
||||
version = '{projectVersion}'
|
||||
|
||||
task buildInfo(type: org.springframework.boot.gradle.tasks.buildinfo.BuildInfo) {
|
||||
properties {
|
||||
artifact = 'example'
|
||||
group = 'com.example'
|
||||
name = 'example'
|
||||
additional = ['additional': 'alpha']
|
||||
time = null
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
plugins {
|
||||
id 'org.springframework.boot' version '{version}' apply false
|
||||
}
|
||||
|
||||
task buildInfo(type: org.springframework.boot.gradle.tasks.buildinfo.BuildInfo) {
|
||||
properties {
|
||||
time = null
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
plugins {
|
||||
id 'org.springframework.boot' version '{version}' apply false
|
||||
}
|
||||
|
||||
task buildInfo(type: org.springframework.boot.gradle.tasks.buildinfo.BuildInfo) {
|
||||
properties {
|
||||
time = null
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
plugins {
|
||||
id 'org.springframework.boot' version '{version}' apply false
|
||||
}
|
||||
|
||||
def property(String name, Object defaultValue) {
|
||||
project.hasProperty(name) ? project.getProperty(name) : defaultValue
|
||||
}
|
||||
|
||||
version = property('projectVersion', '0.1.0')
|
||||
|
||||
task buildInfo(type: org.springframework.boot.gradle.tasks.buildinfo.BuildInfo) {
|
||||
destinationDir file(property('buildInfoDestinationDir', project.buildDir))
|
||||
properties {
|
||||
artifact = property('buildInfoArtifact', 'foo')
|
||||
group = property('buildInfoGroup', 'foo')
|
||||
name = property('buildInfoName', 'foo')
|
||||
additional = ['additional': property('buildInfoAdditional', 'foo')]
|
||||
if (project.hasProperty('nullTime')) {
|
||||
time = null
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'org.springframework.boot' version '{version}'
|
||||
}
|
||||
|
||||
bootJar {
|
||||
mainClass = 'com.example.Application'
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'org.springframework.boot' version '{version}'
|
||||
}
|
||||
|
||||
bootJar {
|
||||
mainClass = 'com.example.Application'
|
||||
layered {
|
||||
{layerTools}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'org.springframework.boot' version '{version}'
|
||||
}
|
||||
|
||||
bootJar {
|
||||
mainClass = 'com.example.Application'
|
||||
layered {
|
||||
{layerEnablement}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'org.springframework.boot' version '{version}'
|
||||
}
|
||||
|
||||
bootJar {
|
||||
mainClass = 'com.example.Application'
|
||||
launchScript {
|
||||
properties 'prop' : '{launchScriptProperty}'
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'org.springframework.boot' version '{version}'
|
||||
}
|
||||
|
||||
bootJar {
|
||||
mainClass = 'com.example.Application'
|
||||
{launchScript}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'org.springframework.boot' version '{version}'
|
||||
}
|
||||
|
||||
bootJar {
|
||||
mainClass = 'com.example.Application'
|
||||
{launchScript}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'application'
|
||||
id 'org.springframework.boot' version '{version}'
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'org.springframework.boot' version '{version}'
|
||||
}
|
||||
|
||||
bootJar {
|
||||
mainClass = 'com.example.Application'
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'org.springframework.boot' version '{version}'
|
||||
}
|
||||
|
||||
bootJar {
|
||||
mainClassName = 'com.example.Application'
|
||||
launchScript()
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'org.springframework.boot' version '{version}'
|
||||
}
|
||||
|
||||
bootJar {
|
||||
mainClass = 'com.example.Application'
|
||||
{layered}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'org.springframework.boot' version '{version}'
|
||||
}
|
||||
|
||||
bootJar {
|
||||
mainClass = 'com.example.Application'
|
||||
if (project.hasProperty('includeLaunchScript') ? includeLaunchScript : false) {
|
||||
launchScript {
|
||||
properties 'prop' : project.hasProperty('launchScriptProperty') ? launchScriptProperty : 'default'
|
||||
}
|
||||
}
|
||||
if (project.hasProperty('customizeLayered') && project.getProperty('customizeLayered')) {
|
||||
layered {
|
||||
includeLayerTools = project.hasProperty('excludeTools') && project.getProperty('excludeTools') ? false : true
|
||||
enabled = project.hasProperty('disableLayers') && project.getProperty('disableLayers') ? false : true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
plugins {
|
||||
id 'war'
|
||||
id 'org.springframework.boot' version '{version}'
|
||||
}
|
||||
|
||||
bootWar {
|
||||
mainClass = 'com.example.Application'
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
plugins {
|
||||
id 'war'
|
||||
id 'org.springframework.boot' version '{version}'
|
||||
}
|
||||
|
||||
bootWar {
|
||||
mainClass = 'com.example.CustomMain'
|
||||
duplicatesStrategy = "exclude"
|
||||
}
|
||||
|
||||
configurations {
|
||||
provided
|
||||
}
|
||||
|
||||
sourceSets.all {
|
||||
compileClasspath += configurations.provided
|
||||
runtimeClasspath += configurations.provided
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("org.apache.commons:commons-lang3:3.6")
|
||||
provided "org.apache.commons:commons-lang3:3.6"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
plugins {
|
||||
id 'war'
|
||||
id 'org.springframework.boot' version '{version}'
|
||||
}
|
||||
|
||||
bootWar {
|
||||
mainClass = 'com.example.Application'
|
||||
launchScript {
|
||||
properties 'prop' : '{launchScriptProperty}'
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
plugins {
|
||||
id 'war'
|
||||
id 'org.springframework.boot' version '{version}'
|
||||
}
|
||||
|
||||
bootWar {
|
||||
mainClass = 'com.example.Application'
|
||||
{launchScript}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
plugins {
|
||||
id 'war'
|
||||
id 'org.springframework.boot' version '{version}'
|
||||
}
|
||||
|
||||
bootWar {
|
||||
mainClass = 'com.example.Application'
|
||||
{launchScript}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
plugins {
|
||||
id 'war'
|
||||
id 'application'
|
||||
id 'org.springframework.boot' version '{version}'
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
plugins {
|
||||
id 'war'
|
||||
id 'org.springframework.boot' version '{version}'
|
||||
}
|
||||
|
||||
bootWar {
|
||||
mainClass = 'com.example.Application'
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
plugins {
|
||||
id 'war'
|
||||
id 'org.springframework.boot' version '{version}'
|
||||
}
|
||||
|
||||
bootWar {
|
||||
mainClass = 'com.example.Application'
|
||||
launchScript()
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
plugins {
|
||||
id 'war'
|
||||
id 'org.springframework.boot' version '{version}'
|
||||
}
|
||||
|
||||
bootWar {
|
||||
mainClass = 'com.example.Application'
|
||||
if (project.hasProperty('includeLaunchScript') ? includeLaunchScript : false) {
|
||||
launchScript {
|
||||
properties 'prop' : project.hasProperty('launchScriptProperty') ? launchScriptProperty : 'default'
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,9 +3,8 @@ plugins {
|
||||
id 'org.springframework.boot' version '{version}'
|
||||
}
|
||||
|
||||
task echoMainClassName {
|
||||
dependsOn compileJava
|
||||
doLast {
|
||||
println 'Main class name = ' + bootRun.main
|
||||
bootRun {
|
||||
doFirst {
|
||||
println "Main class name = ${bootRun.main}"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,4 @@ plugins {
|
||||
id 'org.springframework.boot' version '{version}'
|
||||
}
|
||||
|
||||
mainClassName = 'com.example.CustomMainClass'
|
||||
|
||||
task echoMainClassName {
|
||||
println 'Main class name = ' + bootRun.main
|
||||
}
|
||||
mainClassName = 'com.example.main.CustomMainClass'
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
plugins {
|
||||
id 'application'
|
||||
id 'java'
|
||||
id 'org.springframework.boot' version '{version}'
|
||||
}
|
||||
|
||||
springBoot {
|
||||
mainClass = 'com.example.CustomMainClass'
|
||||
}
|
||||
|
||||
task echoMainClassName {
|
||||
println 'Main class name = ' + bootRun.main
|
||||
mainClass = 'com.example.main.CustomMainClass'
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user