Browse Source

Merge pull request #47980 from scottfrederick

* pr/47980:
  Polish "Add since to deprecations in config metadata JSON files"
  Add since to deprecations in config metadata JSON files
  Add since attribute to uses of DeprecatedConfigurationProperty

Closes gh-47980
pull/48129/head
Stéphane Nicoll 1 month ago
parent
commit
b50a2d0168
  1. 26
      buildSrc/src/main/java/org/springframework/boot/build/architecture/ArchitectureCheck.java
  2. 27
      buildSrc/src/main/java/org/springframework/boot/build/architecture/ArchitectureRules.java
  3. 1
      buildSrc/src/main/java/org/springframework/boot/build/context/properties/CheckAdditionalSpringConfigurationMetadata.java
  4. 1
      buildSrc/src/main/java/org/springframework/boot/build/context/properties/CheckManualSpringConfigurationMetadata.java
  5. 20
      buildSrc/src/main/java/org/springframework/boot/build/context/properties/ConfigurationPropertiesAnalyzer.java
  6. 68
      buildSrc/src/test/java/org/springframework/boot/build/architecture/ArchitectureCheckTests.java
  7. 49
      buildSrc/src/test/java/org/springframework/boot/build/architecture/annotations/TestDeprecatedConfigurationProperty.java
  8. 35
      buildSrc/src/test/java/org/springframework/boot/build/architecture/configurationproperties/DeprecatedConfigurationPropertySince.java
  9. 26
      buildSrc/src/test/java/org/springframework/boot/build/context/properties/ConfigurationPropertiesAnalyzerTests.java
  10. 684
      spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json
  11. 2
      spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayProperties.java
  12. 743
      spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json
  13. 2
      spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/appendix/configurationmetadata/format/property/MyProperties.java
  14. 2
      spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/appendix/configurationmetadata/format/property/MyProperties.kt
  15. 51
      spring-boot-project/spring-boot/src/main/resources/META-INF/additional-spring-configuration-metadata.json

26
buildSrc/src/main/java/org/springframework/boot/build/architecture/ArchitectureCheck.java

@ -26,6 +26,7 @@ import java.nio.file.StandardOpenOption; @@ -26,6 +26,7 @@ import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.function.Supplier;
import java.util.stream.Stream;
@ -42,6 +43,7 @@ import org.gradle.api.file.DirectoryProperty; @@ -42,6 +43,7 @@ import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.file.FileCollection;
import org.gradle.api.file.FileTree;
import org.gradle.api.provider.ListProperty;
import org.gradle.api.provider.MapProperty;
import org.gradle.api.provider.Property;
import org.gradle.api.provider.Provider;
import org.gradle.api.tasks.Classpath;
@ -70,19 +72,27 @@ import org.gradle.api.tasks.VerificationException; @@ -70,19 +72,27 @@ import org.gradle.api.tasks.VerificationException;
*/
public abstract class ArchitectureCheck extends DefaultTask {
static final String CONDITIONAL_ON_CLASS = "ConditionalOnClass";
static final String DEPRECATED_CONFIGURATION_PROPERTY = "DeprecatedConfigurationProperty";
private static final String CONDITIONAL_ON_CLASS_ANNOTATION = "org.springframework.boot.autoconfigure.condition.ConditionalOnClass";
private static final String DEPRECATED_CONFIGURATION_PROPERTY_ANNOTATION = "org.springframework.boot.context.properties.DeprecatedConfigurationProperty";
private FileCollection classes;
public ArchitectureCheck() {
getOutputDirectory().convention(getProject().getLayout().getBuildDirectory().dir(getName()));
getConditionalOnClassAnnotation().convention(CONDITIONAL_ON_CLASS_ANNOTATION);
getAnnotationClasses().convention(Map.of(CONDITIONAL_ON_CLASS, CONDITIONAL_ON_CLASS_ANNOTATION,
DEPRECATED_CONFIGURATION_PROPERTY, DEPRECATED_CONFIGURATION_PROPERTY_ANNOTATION));
getRules().addAll(getProhibitObjectsRequireNonNull().convention(true)
.map(whenTrue(ArchitectureRules::noClassesShouldCallObjectsRequireNonNull)));
getRules().addAll(ArchitectureRules.standard());
getRules().addAll(whenMainSources(() -> List
.of(ArchitectureRules.allBeanMethodsShouldReturnNonPrivateType(), ArchitectureRules
.allBeanMethodsShouldNotHaveConditionalOnClassAnnotation(getConditionalOnClassAnnotation().get()))));
getRules().addAll(whenMainSources(() -> ArchitectureRules
.beanMethods(annotationClassFor(CONDITIONAL_ON_CLASS, CONDITIONAL_ON_CLASS_ANNOTATION))));
getRules().addAll(whenMainSources(() -> ArchitectureRules.configurationProperties(
annotationClassFor(DEPRECATED_CONFIGURATION_PROPERTY, DEPRECATED_CONFIGURATION_PROPERTY_ANNOTATION))));
getRuleDescriptions().set(getRules().map(this::asDescriptions));
}
@ -100,6 +110,10 @@ public abstract class ArchitectureCheck extends DefaultTask { @@ -100,6 +110,10 @@ public abstract class ArchitectureCheck extends DefaultTask {
return rules.stream().map(ArchRule::getDescription).toList();
}
private String annotationClassFor(String name, String defaultValue) {
return getAnnotationClasses().get().getOrDefault(name, defaultValue);
}
@TaskAction
void checkArchitecture() throws Exception {
withCompileClasspath(() -> {
@ -190,7 +204,7 @@ public abstract class ArchitectureCheck extends DefaultTask { @@ -190,7 +204,7 @@ public abstract class ArchitectureCheck extends DefaultTask {
@Input // Use descriptions as input since rules aren't serializable
abstract ListProperty<String> getRuleDescriptions();
@Internal
abstract Property<String> getConditionalOnClassAnnotation();
@Input
abstract MapProperty<String, String> getAnnotationClasses();
}

27
buildSrc/src/main/java/org/springframework/boot/build/architecture/ArchitectureRules.java

@ -101,7 +101,16 @@ final class ArchitectureRules { @@ -101,7 +101,16 @@ final class ArchitectureRules {
return List.copyOf(rules);
}
static ArchRule allBeanMethodsShouldReturnNonPrivateType() {
static List<ArchRule> beanMethods(String annotationName) {
return List.of(allBeanMethodsShouldReturnNonPrivateType(),
allBeanMethodsShouldNotHaveConditionalOnClassAnnotation(annotationName));
}
static List<ArchRule> configurationProperties(String annotationName) {
return List.of(allDeprecatedConfigurationPropertiesShouldIncludeSince(annotationName));
}
private static ArchRule allBeanMethodsShouldReturnNonPrivateType() {
return methodsThatAreAnnotatedWith("org.springframework.context.annotation.Bean").should(check(
"not return types declared with the %s modifier, as such types are incompatible with Spring AOT processing"
.formatted(JavaModifier.PRIVATE),
@ -115,7 +124,7 @@ final class ArchitectureRules { @@ -115,7 +124,7 @@ final class ArchitectureRules {
.allowEmptyShould(true);
}
static ArchRule allBeanMethodsShouldNotHaveConditionalOnClassAnnotation(String annotationName) {
private static ArchRule allBeanMethodsShouldNotHaveConditionalOnClassAnnotation(String annotationName) {
return methodsThatAreAnnotatedWith("org.springframework.context.annotation.Bean").should()
.notBeAnnotatedWith(annotationName)
.because("@ConditionalOnClass on @Bean methods is ineffective - it doesn't prevent "
@ -348,6 +357,20 @@ final class ArchitectureRules { @@ -348,6 +357,20 @@ final class ArchitectureRules {
.allowEmptyShould(true);
}
private static ArchRule allDeprecatedConfigurationPropertiesShouldIncludeSince(String annotationName) {
return methodsThatAreAnnotatedWith(annotationName)
.should(check("include a non-empty 'since' attribute", (method, events) -> {
JavaAnnotation<JavaMethod> annotation = method.getAnnotationOfType(annotationName);
Map<String, Object> properties = annotation.getProperties();
Object since = properties.get("since");
if (!(since instanceof String) || ((String) since).isEmpty()) {
addViolation(events, method, annotation.getDescription()
+ " should include a non-empty 'since' attribute of @DeprecatedConfigurationProperty");
}
}))
.allowEmptyShould(true);
}
private static boolean containsOnlySingleType(JavaType[] types, JavaType type) {
return types.length == 1 && type.equals(types[0]);
}

1
buildSrc/src/main/java/org/springframework/boot/build/context/properties/CheckAdditionalSpringConfigurationMetadata.java

@ -59,6 +59,7 @@ public abstract class CheckAdditionalSpringConfigurationMetadata extends SourceT @@ -59,6 +59,7 @@ public abstract class CheckAdditionalSpringConfigurationMetadata extends SourceT
ConfigurationPropertiesAnalyzer analyzer = new ConfigurationPropertiesAnalyzer(getSource().getFiles());
Report report = new Report(this.projectDir);
analyzer.analyzeSort(report);
analyzer.analyzeDeprecationSince(report);
File reportFile = getReportLocation().get().getAsFile();
report.write(reportFile);
if (report.hasProblems()) {

1
buildSrc/src/main/java/org/springframework/boot/build/context/properties/CheckManualSpringConfigurationMetadata.java

@ -66,6 +66,7 @@ public abstract class CheckManualSpringConfigurationMetadata extends DefaultTask @@ -66,6 +66,7 @@ public abstract class CheckManualSpringConfigurationMetadata extends DefaultTask
Report report = new Report(this.projectDir);
analyzer.analyzeSort(report);
analyzer.analyzePropertyDescription(report, getExclusions().get());
analyzer.analyzeDeprecationSince(report);
File reportFile = getReportLocation().get().getAsFile();
report.write(reportFile);
if (report.hasProblems()) {

20
buildSrc/src/main/java/org/springframework/boot/build/context/properties/ConfigurationPropertiesAnalyzer.java

@ -133,6 +133,26 @@ class ConfigurationPropertiesAnalyzer { @@ -133,6 +133,26 @@ class ConfigurationPropertiesAnalyzer {
return property.get("description") != null;
}
void analyzeDeprecationSince(Report report) throws IOException {
for (File source : this.sources) {
report.registerAnalysis(source, analyzeDeprecationSince(source));
}
}
@SuppressWarnings("unchecked")
private Analysis analyzeDeprecationSince(File source) throws IOException {
Analysis analysis = new Analysis("The following properties are deprecated without a 'since' version:");
Map<String, Object> json = readJsonContent(source);
List<Map<String, Object>> properties = (List<Map<String, Object>>) json.get("properties");
properties.stream().filter((property) -> property.containsKey("deprecation")).forEach((property) -> {
Map<String, Object> deprecation = (Map<String, Object>) property.get("deprecation");
if (!deprecation.containsKey("since")) {
analysis.addItem(property.get("name").toString());
}
});
return analysis;
}
private Map<String, Object> readJsonContent(File source) throws IOException {
return this.objectMapperSupplier.obtain().readValue(source, new TypeReference<Map<String, Object>>() {
});

68
buildSrc/src/test/java/org/springframework/boot/build/architecture/ArchitectureCheckTests.java

@ -19,14 +19,17 @@ package org.springframework.boot.build.architecture; @@ -19,14 +19,17 @@ package org.springframework.boot.build.architecture;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
import org.gradle.api.tasks.SourceSet;
import org.gradle.testkit.runner.BuildResult;
@ -41,6 +44,7 @@ import org.junit.jupiter.params.ParameterizedTest; @@ -41,6 +44,7 @@ import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
import org.springframework.boot.build.architecture.annotations.TestConditionalOnClass;
import org.springframework.boot.build.architecture.annotations.TestDeprecatedConfigurationProperty;
import org.springframework.util.ClassUtils;
import org.springframework.util.FileSystemUtils;
import org.springframework.util.StringUtils;
@ -316,6 +320,16 @@ class ArchitectureCheckTests { @@ -316,6 +320,16 @@ class ArchitectureCheckTests {
build(gradleBuild, Task.CHECK_ARCHITECTURE_TEST);
}
@Test
void whenDeprecatedConfigurationPropertyIsMissingSinceShouldFailAndWriteReport() throws IOException {
prepareTask(Task.CHECK_ARCHITECTURE_MAIN, "configurationproperties", "annotations");
GradleBuild gradleBuild = this.gradleBuild.withDependencies(SPRING_CONTEXT)
.withDeprecatedConfigurationPropertyAnnotation(TestDeprecatedConfigurationProperty.class.getName());
buildAndFail(gradleBuild, Task.CHECK_ARCHITECTURE_MAIN,
"should include a non-empty 'since' attribute of @DeprecatedConfigurationProperty",
"DeprecatedConfigurationPropertySince.getProperty");
}
private void prepareTask(Task task, String... sourceDirectories) throws IOException {
for (String sourceDirectory : sourceDirectories) {
FileSystemUtils.copyRecursively(
@ -348,7 +362,12 @@ class ArchitectureCheckTests { @@ -348,7 +362,12 @@ class ArchitectureCheckTests {
try {
BuildResult buildResult = gradleBuild.buildAndFail(task.toString());
assertThat(buildResult.taskPaths(TaskOutcome.FAILED)).as(buildResult.getOutput()).contains(":" + task);
assertThat(task.getFailureReport(gradleBuild.getProjectDir())).contains(messages);
try {
assertThat(task.getFailureReport(gradleBuild.getProjectDir())).contains(messages);
}
catch (NoSuchFileException ex) {
throw new AssertionError("Expected failure report not found\n" + buildResult.getOutput());
}
}
catch (UnexpectedBuildSuccess ex) {
throw new AssertionError("Expected build to fail but it succeeded\n" + ex.getBuildResult().getOutput(), ex);
@ -410,9 +429,18 @@ class ArchitectureCheckTests { @@ -410,9 +429,18 @@ class ArchitectureCheckTests {
return this;
}
GradleBuild withConditionalOnClassAnnotation(String annotationName) {
GradleBuild withConditionalOnClassAnnotation(String annotationClass) {
for (Task task : Task.values()) {
configureTask(task, (configuration) -> configuration
.withAnnotation(ArchitectureCheck.CONDITIONAL_ON_CLASS, annotationClass));
}
return this;
}
GradleBuild withDeprecatedConfigurationPropertyAnnotation(String annotationClass) {
for (Task task : Task.values()) {
configureTask(task, (configuration) -> configuration.withConditionalOnClassAnnotation(annotationName));
configureTask(task, (configuration) -> configuration
.withAnnotation(ArchitectureCheck.DEPRECATED_CONFIGURATION_PROPERTY, annotationClass));
}
return this;
}
@ -454,18 +482,18 @@ class ArchitectureCheckTests { @@ -454,18 +482,18 @@ class ArchitectureCheckTests {
for (String dependency : this.dependencies) {
buildFile.append("\n implementation ").append(StringUtils.quote(dependency));
}
buildFile.append("}\n");
buildFile.append("\n}\n\n");
}
this.taskConfigurations.forEach((task, configuration) -> {
buildFile.append(task).append(" {");
if (configuration.conditionalOnClassAnnotation() != null) {
buildFile.append("\n conditionalOnClassAnnotation = ")
.append(StringUtils.quote(configuration.conditionalOnClassAnnotation()));
}
if (configuration.prohibitObjectsRequireNonNull() != null) {
buildFile.append("\n prohibitObjectsRequireNonNull = ")
.append(configuration.prohibitObjectsRequireNonNull());
}
if (configuration.annotations() != null && !configuration.annotations().isEmpty()) {
buildFile.append("\n annotationClasses = ")
.append(toGroovyMapString(configuration.annotations()));
}
buildFile.append("\n}\n");
});
Files.writeString(this.projectDir.resolve("build.gradle"), buildFile, StandardCharsets.UTF_8);
@ -475,15 +503,31 @@ class ArchitectureCheckTests { @@ -475,15 +503,31 @@ class ArchitectureCheckTests {
.withPluginClasspath();
}
private record TaskConfiguration(Boolean prohibitObjectsRequireNonNull, String conditionalOnClassAnnotation) {
static String toGroovyMapString(Map<String, String> map) {
return map.entrySet()
.stream()
.map((entry) -> "'" + entry.getKey() + "' : '" + entry.getValue() + "'")
.collect(Collectors.joining(", ", "[", "]"));
}
private TaskConfiguration withConditionalOnClassAnnotation(String annotationName) {
return new TaskConfiguration(this.prohibitObjectsRequireNonNull, annotationName);
private record TaskConfiguration(Boolean prohibitObjectsRequireNonNull, Map<String, String> annotations) {
public TaskConfiguration {
if (annotations == null) {
annotations = new HashMap<>();
}
}
private TaskConfiguration withProhibitObjectsRequireNonNull(Boolean prohibitObjectsRequireNonNull) {
return new TaskConfiguration(prohibitObjectsRequireNonNull, this.conditionalOnClassAnnotation);
return new TaskConfiguration(prohibitObjectsRequireNonNull, this.annotations);
}
private TaskConfiguration withAnnotation(String name, String annotationClass) {
Map<String, String> map = new HashMap<>(this.annotations);
map.put(name, annotationClass);
return new TaskConfiguration(this.prohibitObjectsRequireNonNull, map);
}
}
}

49
buildSrc/src/test/java/org/springframework/boot/build/architecture/annotations/TestDeprecatedConfigurationProperty.java

@ -0,0 +1,49 @@ @@ -0,0 +1,49 @@
/*
* Copyright 2012-present 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.build.architecture.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* {@code @DeprecatedConfigurationProperty} analogue for architecture checks.
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestDeprecatedConfigurationProperty {
/**
* The reason for the deprecation.
* @return the deprecation reason
*/
String reason() default "";
/**
* The field that should be used instead (if any).
* @return the replacement field
*/
String replacement() default "";
/**
* The version in which the property became deprecated.
* @return the version
*/
String since() default "";
}

35
buildSrc/src/test/java/org/springframework/boot/build/architecture/configurationproperties/DeprecatedConfigurationPropertySince.java

@ -0,0 +1,35 @@ @@ -0,0 +1,35 @@
/*
* Copyright 2012-present 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.build.architecture.configurationproperties;
import org.springframework.boot.build.architecture.annotations.TestDeprecatedConfigurationProperty;
public class DeprecatedConfigurationPropertySince {
private String property;
@TestDeprecatedConfigurationProperty(reason = "no longer used")
@Deprecated
public String getProperty() {
return this.property;
}
public void setProperty(String property) {
this.property = property;
}
}

26
buildSrc/src/test/java/org/springframework/boot/build/context/properties/ConfigurationPropertiesAnalyzerTests.java

@ -115,6 +115,32 @@ class ConfigurationPropertiesAnalyzerTests { @@ -115,6 +115,32 @@ class ConfigurationPropertiesAnalyzerTests {
.satisfies(((analysis) -> assertThat(analysis.getItems()).containsExactly("def")));
}
@Test
void analyzeDeprecatedPropertyWithMissingSince(@TempDir File tempDir) throws IOException {
File metadata = new File(tempDir, "metadata.json");
Files.writeString(metadata.toPath(), """
{ "properties": [
{
"name": "abc",
"description": "This is abc.",
"deprecation": { "reason": "abc reason", "since": "3.0.0" }
},
{ "name": "def", "description": "This is def." },
{
"name": "xyz",
"description": "This is xyz.",
"deprecation": { "reason": "xyz reason" }
}
]
}""");
Report report = new Report(tempDir);
ConfigurationPropertiesAnalyzer analyzer = new ConfigurationPropertiesAnalyzer(List.of(metadata));
analyzer.analyzeDeprecationSince(report);
assertThat(report.hasProblems()).isTrue();
assertThat(report.getAnalyses(metadata)).singleElement()
.satisfies(((analysis) -> assertThat(analysis.getItems()).containsExactly("xyz")));
}
@Test
void writeEmptyReport(@TempDir File tempDir) throws IOException {
assertThat(writeToFile(tempDir, new Report(tempDir))).hasContent("No problems found.");

684
spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json

File diff suppressed because it is too large Load Diff

2
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayProperties.java

@ -794,7 +794,7 @@ public class FlywayProperties { @@ -794,7 +794,7 @@ public class FlywayProperties {
this.outputQueryResults = outputQueryResults;
}
@DeprecatedConfigurationProperty(replacement = "spring.flyway.sqlserver.kerberos-login-file")
@DeprecatedConfigurationProperty(replacement = "spring.flyway.sqlserver.kerberos-login-file", since = "3.2.0")
@Deprecated(since = "3.2.0", forRemoval = true)
public String getSqlServerKerberosLoginFile() {
return getSqlserver().getKerberosLoginFile();

743
spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json

File diff suppressed because it is too large Load Diff

2
spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/appendix/configurationmetadata/format/property/MyProperties.java

@ -33,7 +33,7 @@ public class MyProperties { @@ -33,7 +33,7 @@ public class MyProperties {
}
@Deprecated
@DeprecatedConfigurationProperty(replacement = "my.app.name")
@DeprecatedConfigurationProperty(replacement = "my.app.name", since = "1.2.0")
public String getTarget() {
return this.name;
}

2
spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/appendix/configurationmetadata/format/property/MyProperties.kt

@ -23,7 +23,7 @@ import org.springframework.boot.context.properties.DeprecatedConfigurationProper @@ -23,7 +23,7 @@ import org.springframework.boot.context.properties.DeprecatedConfigurationProper
class MyProperties(val name: String?) {
var target: String? = null
@Deprecated("") @DeprecatedConfigurationProperty(replacement = "my.app.name") get
@Deprecated("") @DeprecatedConfigurationProperty(replacement = "my.app.name", since = "1.2.0") get
@Deprecated("") set
}

51
spring-boot-project/spring-boot/src/main/resources/META-INF/additional-spring-configuration-metadata.json

@ -42,7 +42,8 @@ @@ -42,7 +42,8 @@
"description": "Log file name (for instance, `myapp.log`). Names can be an exact location or relative to the current directory.",
"deprecation": {
"replacement": "logging.file.name",
"level": "error"
"level": "error",
"since": "2.2.0"
}
},
{
@ -52,7 +53,8 @@ @@ -52,7 +53,8 @@
"sourceType": "org.springframework.boot.context.logging.LoggingApplicationListener",
"defaultValue": false,
"deprecation": {
"replacement": "logging.logback.rollingpolicy.clean-history-on-start"
"replacement": "logging.logback.rollingpolicy.clean-history-on-start",
"since": "2.4.0"
}
},
{
@ -62,7 +64,8 @@ @@ -62,7 +64,8 @@
"sourceType": "org.springframework.boot.context.logging.LoggingApplicationListener",
"defaultValue": 7,
"deprecation": {
"replacement": "logging.logback.rollingpolicy.max-history"
"replacement": "logging.logback.rollingpolicy.max-history",
"since": "2.4.0"
}
},
{
@ -72,7 +75,8 @@ @@ -72,7 +75,8 @@
"sourceType": "org.springframework.boot.context.logging.LoggingApplicationListener",
"defaultValue": "10MB",
"deprecation": {
"replacement": "logging.logback.rollingpolicy.max-file-size"
"replacement": "logging.logback.rollingpolicy.max-file-size",
"since": "2.4.0"
}
},
{
@ -94,7 +98,8 @@ @@ -94,7 +98,8 @@
"sourceType": "org.springframework.boot.context.logging.LoggingApplicationListener",
"defaultValue": "0B",
"deprecation": {
"replacement": "logging.logback.rollingpolicy.total-size-cap"
"replacement": "logging.logback.rollingpolicy.total-size-cap",
"since": "2.4.0"
}
},
{
@ -169,7 +174,8 @@ @@ -169,7 +174,8 @@
"description": "Location of the log file. For instance, `/var/log`.",
"deprecation": {
"replacement": "logging.file.path",
"level": "error"
"level": "error",
"since": "2.2.0"
}
},
{
@ -211,7 +217,8 @@ @@ -211,7 +217,8 @@
"sourceType": "org.springframework.boot.context.logging.LoggingApplicationListener",
"defaultValue": "${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz",
"deprecation": {
"replacement": "logging.logback.rollingpolicy.file-name-pattern"
"replacement": "logging.logback.rollingpolicy.file-name-pattern",
"since": "2.4.0"
}
},
{
@ -349,7 +356,8 @@ @@ -349,7 +356,8 @@
"description": "Application index.",
"deprecation": {
"level": "error",
"reason": "Application context ids are now unique by default."
"reason": "Application context ids are now unique by default.",
"since": "2.0.0"
}
},
{
@ -374,7 +382,8 @@ @@ -374,7 +382,8 @@
"type": "java.lang.Integer",
"deprecation": {
"level": "error",
"reason": "Support for image banners has been removed."
"reason": "Support for image banners has been removed.",
"since": "3.0.0"
}
},
{
@ -382,7 +391,8 @@ @@ -382,7 +391,8 @@
"type": "java.lang.Integer",
"deprecation": {
"level": "error",
"reason": "Support for image banners has been removed."
"reason": "Support for image banners has been removed.",
"since": "3.0.0"
}
},
{
@ -390,7 +400,8 @@ @@ -390,7 +400,8 @@
"type": "java.lang.Boolean",
"deprecation": {
"level": "error",
"reason": "Support for image banners has been removed."
"reason": "Support for image banners has been removed.",
"since": "3.0.0"
}
},
{
@ -398,7 +409,8 @@ @@ -398,7 +409,8 @@
"type": "org.springframework.core.io.Resource",
"deprecation": {
"level": "error",
"reason": "Support for image banners has been removed."
"reason": "Support for image banners has been removed.",
"since": "3.0.0"
}
},
{
@ -406,7 +418,8 @@ @@ -406,7 +418,8 @@
"type": "java.lang.Integer",
"deprecation": {
"level": "error",
"reason": "Support for image banners has been removed."
"reason": "Support for image banners has been removed.",
"since": "3.0.0"
}
},
{
@ -414,7 +427,8 @@ @@ -414,7 +427,8 @@
"type": "org.springframework.boot.ImageBanner$PixelMode",
"deprecation": {
"level": "error",
"reason": "Support for image banners has been removed."
"reason": "Support for image banners has been removed.",
"since": "3.0.0"
}
},
{
@ -422,7 +436,8 @@ @@ -422,7 +436,8 @@
"type": "java.lang.Integer",
"deprecation": {
"level": "error",
"reason": "Support for image banners has been removed."
"reason": "Support for image banners has been removed.",
"since": "3.0.0"
}
},
{
@ -541,7 +556,8 @@ @@ -541,7 +556,8 @@
"description": "Display the banner when the application runs.",
"defaultValue": true,
"deprecation": {
"replacement": "spring.main.banner-mode"
"replacement": "spring.main.banner-mode",
"since": "1.3.0"
}
},
{
@ -562,7 +578,8 @@ @@ -562,7 +578,8 @@
"sourceType": "org.springframework.boot.SpringApplication",
"description": "Run the application in a web environment (auto-detected by default).",
"deprecation": {
"replacement": "spring.main.web-application-type"
"replacement": "spring.main.web-application-type",
"since": "2.0.0"
}
},
{

Loading…
Cancel
Save