Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ private class CreateJmxConnector implements Callable<@Nullable JMXConnector> {
}

private boolean hasCauseWithType(Throwable t, Class<? extends Exception> type) {
return type.isAssignableFrom(t.getClass()) || t.getCause() != null && hasCauseWithType(t.getCause(), type);
return type.isInstance(t) || t.getCause() != null && hasCauseWithType(t.getCause(), type);
}

}
Expand Down
12 changes: 12 additions & 0 deletions config/checkstyle/checkstyle.xml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,18 @@
value="Please use static AssertJ imports." />
<property name="ignoreComments" value="true" />
</module>
<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">
<property name="maximum" value="0"/>
<property name="format" value="\.isAssignableFrom\(.+\.getClass\(\)\)" />
<property name="message" value="Please use type.isInstance(object) instead." />
<property name="ignoreComments" value="true" />
</module>
<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">
<property name="maximum" value="0"/>
<property name="format" value="\w+\.class\.isInstance\(.+\)" />
<property name="message" value="Please use object instanceof type instead." />
<property name="ignoreComments" value="true" />
</module>
<module name="io.spring.javaformat.checkstyle.check.SpringJavadocCheck">
<property name="publicOnlySinceTags" value="true" />
<property name="requireSinceTag" value="true" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,14 @@ String getKind() throws Exception {
}

Object getLiteralValue() throws Exception {
if (this.literalTreeType.isAssignableFrom(getInstance().getClass())) {
if (this.literalTreeType.isInstance(getInstance())) {
return this.literalValueMethod.invoke(getInstance());
}
return null;
}

Object getFactoryValue() throws Exception {
if (this.methodInvocationTreeType.isAssignableFrom(getInstance().getClass())) {
if (this.methodInvocationTreeType.isInstance(getInstance())) {
List<?> arguments = (List<?>) this.methodInvocationArgumentsMethod.invoke(getInstance());
if (arguments.size() == 1) {
return new ExpressionTree(arguments.get(0)).getLiteralValue();
Expand All @@ -72,7 +72,7 @@ Object getFactoryValue() throws Exception {
}

Member getSelectedMember() throws Exception {
if (this.memberSelectTreeType.isAssignableFrom(getInstance().getClass())) {
if (this.memberSelectTreeType.isInstance(getInstance())) {
String expression = this.memberSelectTreeExpressionMethod.invoke(getInstance()).toString();
String identifier = this.memberSelectTreeIdentifierMethod.invoke(getInstance()).toString();
if (expression != null && identifier != null) {
Expand All @@ -83,7 +83,7 @@ Member getSelectedMember() throws Exception {
}

List<? extends ExpressionTree> getArrayExpression() throws Exception {
if (this.newArrayTreeType.isAssignableFrom(getInstance().getClass())) {
if (this.newArrayTreeType.isInstance(getInstance())) {
List<?> elements = (List<?>) this.arrayValueMethod.invoke(getInstance());
List<ExpressionTree> result = new ArrayList<>();
if (elements == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.env.Environment;
import org.springframework.test.context.NestedTestConfiguration;
import org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration;
import org.springframework.test.context.TestPropertySource;

import static org.assertj.core.api.Assertions.assertThat;
Expand Down Expand Up @@ -68,6 +70,38 @@ void containingClassTestPropertySourceIsHonored() {

}

@Nested
@SpringBootTest(classes = Config.class)
@Import(ImportedByNestedTests.class)
@NestedTestConfiguration(EnclosingConfiguration.OVERRIDE)
class OverrideNestedTests {

@Autowired(required = false)
private ImportedByContainingTests importedByContainingTests;

@Autowired(required = false)
private ImportedByNestedTests importedByNestedTests;

@Autowired
private Environment environment;

@Test
void sameClassImportIsHonored() {
assertThat(this.importedByNestedTests).isNotNull();
}

@Test
void containingClassImportIsNotInherited() {
assertThat(this.importedByContainingTests).isNull();
}

@Test
void containingClassTestPropertySourceIsNotInherited() {
assertThat(this.environment.getProperty("a")).isNull();
}

}

@Configuration(proxyBeanMethods = false)
static class Config {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
import org.springframework.boot.context.properties.source.ConfigurationPropertyName.Form;
import org.springframework.core.ResolvableType;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.AbstractBindingResult;
import org.springframework.validation.BeanPropertyBindingResult;
Expand Down Expand Up @@ -115,8 +114,7 @@ private void validate(ConfigurationPropertyName name, Bindable<?> target, BindCo
if (this.exception == null) {
Object validationTarget = getValidationTarget(target, context, result);
Class<?> validationType = target.getBoxedType().resolve();
if (validationTarget != null) {
Assert.state(validationType != null, "'validationType' must not be null");
if (validationTarget != null && validationType != null) {
validateAndPush(name, validationTarget, validationType);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public abstract class AbstractInjectionFailureAnalyzer<T extends Throwable> exte
Throwable candidate = root;
C result = null;
while (candidate != null) {
if (type.isAssignableFrom(candidate.getClass())) {
if (type.isInstance(candidate)) {
result = (C) candidate;
}
candidate = candidate.getCause();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ protected final <T> T tryParse(Callable<T> parser, Class<? extends Exception> ch
return parser.call();
}
catch (Exception ex) {
if (check.isAssignableFrom(ex.getClass())) {
if (check.isInstance(ex)) {
throw new JsonParseException(ex);
}
ReflectionUtils.rethrowRuntimeException(ex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,15 @@ void validateMapValuesWithNonUniformSource() {
this.binder.bind(ConfigurationPropertyName.of("test"), Bindable.of(ExampleWithMap.class), this.handler);
}

@Test
void bindShouldValidateMapWithWildcardValue() {
this.sources.add(new MockConfigurationPropertySource("test.params.toto", "titi"));
ExampleWithWildcardMap result = this.binder
.bind(ConfigurationPropertyName.of("test"), Bindable.of(ExampleWithWildcardMap.class), this.handler)
.get();
assertThat(result.getParams().get("toto")).isEqualTo("titi");
}

private Validator getMapValidator() {
return new Validator() {

Expand Down Expand Up @@ -425,6 +434,21 @@ Map<String, ExampleMapValue> getItems() {

}

@Validated
static class ExampleWithWildcardMap {

private Map<String, ?> params = new LinkedHashMap<>();

Map<String, ?> getParams() {
return this.params;
}

void setParams(Map<String, ?> params) {
this.params = params;
}

}

static class ExampleMapValue {

private @Nullable String number;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ include::partial$configuration-properties/devtools.adoc[]

include::partial$configuration-properties/docker-compose.adoc[]

include::partial$configuration-properties/grpc.adoc[]

include::partial$configuration-properties/integration.adoc[]

include::partial$configuration-properties/json.adoc[]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,17 @@ tasks.register("buildSignedJarRsaApp", GradleBuild) {
tasks = ["build"]
}

tasks.register("syncWarAppSource", org.springframework.boot.build.SyncAppSource) {
sourceDirectory = file("spring-boot-loader-tests-war")
destinationDirectory = file(layout.buildDirectory.dir("spring-boot-loader-tests-war"))
}

tasks.register("buildWarApp", GradleBuild) {
dependsOn syncWarAppSource, syncMavenRepository
dir = layout.buildDirectory.dir("spring-boot-loader-tests-war")
startParameter.buildCacheEnabled = false
tasks = ["build"]
}

tasks.register("downloadJdk", Download) {
def destFolder = new File(project.gradle.gradleUserHomeDir, "caches/springboot/downloads/jdk/oracle")
Expand All @@ -105,5 +116,5 @@ tasks.named("processDockerTestResources").configure {
}

tasks.named("dockerTest").configure {
dependsOn buildApp, buildSignedJarApp, buildSignedJarRsaApp
dependsOn buildApp, buildWarApp, buildSignedJarApp, buildSignedJarRsaApp
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* 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.
*/

plugins {
id "war"
id "org.springframework.boot"
}

java {
sourceCompatibility = '17'
targetCompatibility = '17'
}

repositories {
maven { url = layout.projectDirectory.dir("../docker-test-maven-repository") }
mavenCentral()
spring.mavenRepositories()
}

dependencies {
implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES))
implementation("org.springframework.boot:spring-boot-starter-webmvc")

providedRuntime(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES))
providedRuntime("org.springframework.boot:spring-boot-starter-tomcat-runtime")
providedRuntime("org.glassfish.web:jakarta.servlet.jsp.jstl")
providedRuntime("org.apache.tomcat.embed:tomcat-embed-jasper")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* 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.
*/

pluginManagement {
evaluate(new File("${gradle.parent.rootProject.rootDir}/buildSrc/SpringRepositorySupport.groovy")).apply(this)
repositories {
maven { url = layout.settingsDirectory.dir("../docker-test-maven-repository") }
mavenCentral()
spring.mavenRepositories()
}
resolutionStrategy {
eachPlugin {
if (requested.id.id == "org.springframework.boot") {
useModule "org.springframework.boot:spring-boot-gradle-plugin:${requested.version}"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* 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.loaderwarapp;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

@SpringBootApplication
public class LoaderWarTestApplication extends SpringBootServletInitializer {

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(LoaderWarTestApplication.class);
}

public static void main(String[] args) {
SpringApplication.run(LoaderWarTestApplication.class, args).close();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<html lang="en">
<body>
<c:url value="/" var="url"/>
<spring:url value="/" htmlEscape="true" var="springUrl" />
Spring URL: ${springUrl}
JSTL URL: ${url}
</body>
</html>
Loading
Loading