From 768aa5dfcc1f5ce2d3b0c2fe520dd0f00b83cd5f Mon Sep 17 00:00:00 2001 From: Madhura Bhave Date: Mon, 1 Apr 2019 15:48:32 -0700 Subject: [PATCH] Ignore exception if ValidationAdapter can't get a MessageInterpolator Fixes gh-16177 --- .../validation/ValidatorAdapter.java | 10 ++- .../validation/ValidatorAdapterTests.java | 86 ++++++++++--------- 2 files changed, 55 insertions(+), 41 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/ValidatorAdapter.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/ValidatorAdapter.java index ed84cc2ecea..da1c3cf73b3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/ValidatorAdapter.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/ValidatorAdapter.java @@ -16,6 +16,8 @@ package org.springframework.boot.autoconfigure.validation; +import javax.validation.ValidationException; + import org.springframework.beans.BeansException; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; @@ -135,7 +137,13 @@ public class ValidatorAdapter implements SmartValidator, ApplicationContextAware private static Validator create() { OptionalValidatorFactoryBean validator = new OptionalValidatorFactoryBean(); - validator.setMessageInterpolator(new MessageInterpolatorFactory().getObject()); + try { + validator + .setMessageInterpolator(new MessageInterpolatorFactory().getObject()); + } + catch (ValidationException ex) { + // Ignore + } return wrap(validator, false); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/validation/ValidatorAdapterTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/validation/ValidatorAdapterTests.java index 675bf8317b5..94d0d1e082a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/validation/ValidatorAdapterTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/validation/ValidatorAdapterTests.java @@ -20,13 +20,14 @@ import java.util.HashMap; import javax.validation.constraints.Min; -import org.junit.After; import org.junit.Test; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; import org.springframework.validation.MapBindingResult; import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; @@ -41,60 +42,65 @@ import static org.mockito.Mockito.verify; * Tests for {@link ValidatorAdapter}. * * @author Stephane Nicoll + * @author Madhura Bhave */ public class ValidatorAdapterTests { - private AnnotationConfigApplicationContext context; - - @After - public void close() { - if (this.context != null) { - this.context.close(); - } - } + private ApplicationContextRunner contextRunner = new ApplicationContextRunner(); @Test public void wrapLocalValidatorFactoryBean() { - ValidatorAdapter wrapper = load(LocalValidatorFactoryBeanConfig.class); - assertThat(wrapper.supports(SampleData.class)).isTrue(); - MapBindingResult errors = new MapBindingResult(new HashMap(), - "test"); - wrapper.validate(new SampleData(40), errors); - assertThat(errors.getErrorCount()).isEqualTo(1); + this.contextRunner.withUserConfiguration(LocalValidatorFactoryBeanConfig.class) + .run((context) -> { + ValidatorAdapter wrapper = context.getBean(ValidatorAdapter.class); + assertThat(wrapper.supports(SampleData.class)).isTrue(); + MapBindingResult errors = new MapBindingResult( + new HashMap(), "test"); + wrapper.validate(new SampleData(40), errors); + assertThat(errors.getErrorCount()).isEqualTo(1); + }); } @Test public void wrapperInvokesCallbackOnNonManagedBean() { - load(NonManagedBeanConfig.class); - LocalValidatorFactoryBean validator = this.context - .getBean(NonManagedBeanConfig.class).validator; - verify(validator, times(1)).setApplicationContext(any(ApplicationContext.class)); - verify(validator, times(1)).afterPropertiesSet(); - verify(validator, never()).destroy(); - this.context.close(); - this.context = null; - verify(validator, times(1)).destroy(); + this.contextRunner.withUserConfiguration(NonManagedBeanConfig.class) + .run((context) -> { + LocalValidatorFactoryBean validator = context + .getBean(NonManagedBeanConfig.class).validator; + verify(validator, times(1)) + .setApplicationContext(any(ApplicationContext.class)); + verify(validator, times(1)).afterPropertiesSet(); + verify(validator, never()).destroy(); + context.close(); + verify(validator, times(1)).destroy(); + }); } @Test public void wrapperDoesNotInvokeCallbackOnManagedBean() { - load(ManagedBeanConfig.class); - LocalValidatorFactoryBean validator = this.context - .getBean(ManagedBeanConfig.class).validator; - verify(validator, never()).setApplicationContext(any(ApplicationContext.class)); - verify(validator, never()).afterPropertiesSet(); - verify(validator, never()).destroy(); - this.context.close(); - this.context = null; - verify(validator, never()).destroy(); + this.contextRunner.withUserConfiguration(ManagedBeanConfig.class) + .run((context) -> { + LocalValidatorFactoryBean validator = context + .getBean(ManagedBeanConfig.class).validator; + verify(validator, never()) + .setApplicationContext(any(ApplicationContext.class)); + verify(validator, never()).afterPropertiesSet(); + verify(validator, never()).destroy(); + context.close(); + verify(validator, never()).destroy(); + }); } - private ValidatorAdapter load(Class config) { - AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); - ctx.register(config); - ctx.refresh(); - this.context = ctx; - return this.context.getBean(ValidatorAdapter.class); + @Test + public void wrapperWhenValidationProviderNotPresentShouldNotThrowException() { + ClassPathResource hibernateValidator = new ClassPathResource( + "META-INF/services/javax.validation.spi.ValidationProvider"); + this.contextRunner + .withClassLoader(new FilteredClassLoader( + FilteredClassLoader.ClassPathResourceFilter + .of(hibernateValidator), + FilteredClassLoader.PackageFilter.of("org.hibernate.validator"))) + .run((context) -> ValidatorAdapter.get(context, null)); } @Configuration