diff --git a/debian/changelog b/debian/changelog index addf891dd1bcdff5192a1bd5e4323ce834b1f8da..84829c328313558301357199380f016d9adcd25a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +libspring-java (4.3.22-5) UNRELEASED; urgency=medium + + * Team upload. + * Fix FTBFS with libhibernate-validator-java 5.x: Upgrade to Bean Validation + 1.1 and remove Hibernate Validator 4.x support. (Closes: #941685) + + -- Ryan Tandy <ryan@nardis.ca> Mon, 18 Nov 2019 19:48:22 +0000 + libspring-java (4.3.22-4) unstable; urgency=medium * Team upload. diff --git a/debian/control b/debian/control index b7d5a178d1af9a2129bc7079aa70d0a0e9ec738f..ba1cdd91e00f5fc7881b975cbca5ba35c287271f 100644 --- a/debian/control +++ b/debian/control @@ -43,7 +43,7 @@ Build-Depends-Indep: bsh, libgeronimo-jcache-1.0-spec-java, libgeronimo-jms-1.1-spec-java, libgeronimo-jta-1.2-spec-java, - libgeronimo-validation-1.0-spec-java, + libgeronimo-validation-1.1-spec-java, libhessian-java, libhibernate-validator-java (>= 4.3.2), libhibernate3-java (>= 3.5), @@ -156,7 +156,7 @@ Recommends: libasm-java (>= 5.0), libcglib-java (>= 3.1), libgeronimo-ejb-3.2-spec-java, libgeronimo-jms-1.1-spec-java, - libgeronimo-validation-1.0-spec-java, + libgeronimo-validation-1.1-spec-java, libjodatime-java, libspring-instrument-java (= ${source:Version}), libtomcat9-java diff --git a/debian/maven.rules b/debian/maven.rules index c5658212aec0332da63883efe0c4bdf225a2dfb4..00a460978ffbcbbf7ff2ee25d8f44ebbeaf3debb 100644 --- a/debian/maven.rules +++ b/debian/maven.rules @@ -10,7 +10,7 @@ javax.portlet portlet-api * * * * s/javax.resource/org.apache.geronimo.specs/ s/connector-api/geronimo-j2ee-connector_1.5_spec/ * s/.*/debian/ * * s/javax.servlet.jsp.jstl/org.apache.taglibs/ s/javax.servlet.jsp.jstl-api/taglibs-standard-spec/ * s/.*/debian/ * * s/javax.transaction/org.apache.geronimo.specs/ s/javax.transaction-api/geronimo-jta_1.2_spec/ * s/.*/debian/ * * -s/javax.validation/org.apache.geronimo.specs/ s/validation-api/geronimo-validation_1.0_spec/ * s/.*/debian/ * * +s/javax.validation/org.apache.geronimo.specs/ s/validation-api/geronimo-validation_1.1_spec/ * s/.*/debian/ * * junit junit * s/.*/4.x/ * * log4j log4j * s/.*/1.2.x/ * * org.apache.tomcat s/catalina/tomcat-catalina/ * s/.*/9.x/ * * diff --git a/debian/patches/0054-disable-hibernate-validator-4.patch b/debian/patches/0054-disable-hibernate-validator-4.patch new file mode 100644 index 0000000000000000000000000000000000000000..5992789440bdf334a42c2baab7006af5f16d15bf --- /dev/null +++ b/debian/patches/0054-disable-hibernate-validator-4.patch @@ -0,0 +1,315 @@ +Description: Fix compilation failure with Hibernate Validator 5.x + Backport parts of upstream commit 54004e0d78dd92c62429999b77befbc9d9fcdb68 + to remove Hibernate Validator 4.x dependency and use Bean Validation 1.1 + directly. +Author: Ryan Tandy <ryan@nardis.ca> +Forwarded: not-needed +Bug-Debian: https://bugs.debian.org/941685 +--- a/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java ++++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java +@@ -24,11 +24,13 @@ + import java.lang.reflect.Proxy; + import java.util.Arrays; + import java.util.HashMap; ++import java.util.List; + import java.util.Map; + import java.util.Properties; + import javax.validation.Configuration; + import javax.validation.ConstraintValidatorFactory; + import javax.validation.MessageInterpolator; ++import javax.validation.ParameterNameProvider; + import javax.validation.TraversableResolver; + import javax.validation.Validation; + import javax.validation.ValidationException; +@@ -67,15 +69,8 @@ + * you will almost always use the default Validator anyway. This can also be injected directly + * into any target dependency of type {@link org.springframework.validation.Validator}! + * +- * <p><b>As of Spring 4.0, this class supports Bean Validation 1.0 and 1.1, with special support +- * for Hibernate Validator 4.3 and 5.x</b> (see {@link #setValidationMessageSource}). +- * +- * <p>Note that Bean Validation 1.1's {@code #forExecutables} method isn't supported: We do not +- * expect that method to be called by application code; consider {@link MethodValidationInterceptor} +- * instead. If you really need programmatic {@code #forExecutables} access, inject this class as +- * a {@link ValidatorFactory} and call {@link #getValidator()} on it, then {@code #forExecutables} +- * on the returned native {@link Validator} reference instead of directly on this class. +- * Alternatively, call {@code #unwrap(Validator.class)} which will also provide the native object. ++ * <p><b>As of Spring 5.0, this class requires Bean Validation 1.1, with special support ++ * for Hibernate Validator 5.x</b> (see {@link #setValidationMessageSource}). + * + * <p>This class is also being used by Spring's MVC configuration namespace, in case of the + * {@code javax.validation} API being present but no explicit Validator having been configured. +@@ -90,10 +85,6 @@ + public class LocalValidatorFactoryBean extends SpringValidatorAdapter + implements ValidatorFactory, ApplicationContextAware, InitializingBean, DisposableBean { + +- // Bean Validation 1.1 close() method available? +- private static final Method closeMethod = ClassUtils.getMethodIfAvailable(ValidatorFactory.class, "close"); +- +- + @SuppressWarnings("rawtypes") + private Class providerClass; + +@@ -312,55 +303,23 @@ + } + + private void configureParameterNameProviderIfPossible(Configuration<?> configuration) { +- try { +- Class<?> parameterNameProviderClass = +- ClassUtils.forName("javax.validation.ParameterNameProvider", getClass().getClassLoader()); +- Method parameterNameProviderMethod = +- Configuration.class.getMethod("parameterNameProvider", parameterNameProviderClass); +- final Object defaultProvider = ReflectionUtils.invokeMethod( +- Configuration.class.getMethod("getDefaultParameterNameProvider"), configuration); +- final ParameterNameDiscoverer discoverer = this.parameterNameDiscoverer; +- Object parameterNameProvider = Proxy.newProxyInstance(getClass().getClassLoader(), +- new Class<?>[] {parameterNameProviderClass}, new InvocationHandler() { +- @Override +- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { +- if (method.getName().equals("getParameterNames")) { +- String[] result = null; +- if (args[0] instanceof Constructor) { +- result = discoverer.getParameterNames((Constructor<?>) args[0]); +- } +- else if (args[0] instanceof Method) { +- result = discoverer.getParameterNames((Method) args[0]); +- } +- if (result != null) { +- return Arrays.asList(result); +- } +- else { +- try { +- return method.invoke(defaultProvider, args); +- } +- catch (InvocationTargetException ex) { +- throw ex.getTargetException(); +- } +- } +- } +- else { +- // toString, equals, hashCode +- try { +- return method.invoke(this, args); +- } +- catch (InvocationTargetException ex) { +- throw ex.getTargetException(); +- } +- } +- } +- }); +- ReflectionUtils.invokeMethod(parameterNameProviderMethod, configuration, parameterNameProvider); +- +- } +- catch (Throwable ex) { +- // Bean Validation 1.1 API not available - simply not applying the ParameterNameDiscoverer +- } ++ // TODO: inner class ++ final ParameterNameDiscoverer discoverer = this.parameterNameDiscoverer; ++ final ParameterNameProvider defaultProvider = configuration.getDefaultParameterNameProvider(); ++ configuration.parameterNameProvider(new ParameterNameProvider() { ++ @Override ++ public List<String> getParameterNames(Constructor<?> constructor) { ++ String[] paramNames = discoverer.getParameterNames(constructor); ++ return (paramNames != null ? Arrays.asList(paramNames) : ++ defaultProvider.getParameterNames(constructor)); ++ } ++ @Override ++ public List<String> getParameterNames(Method method) { ++ String[] paramNames = discoverer.getParameterNames(method); ++ return (paramNames != null ? Arrays.asList(paramNames) : ++ defaultProvider.getParameterNames(method)); ++ } ++ }); + } + + /** +@@ -428,9 +387,14 @@ + } + + ++ @Override ++ public ParameterNameProvider getParameterNameProvider() { ++ return this.validatorFactory.getParameterNameProvider(); ++ } ++ + public void close() { +- if (closeMethod != null && this.validatorFactory != null) { +- ReflectionUtils.invokeMethod(closeMethod, this.validatorFactory); ++ if (this.validatorFactory != null) { ++ this.validatorFactory.close(); + } + } + +--- a/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationInterceptor.java ++++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationInterceptor.java +@@ -26,7 +26,6 @@ + + import org.aopalliance.intercept.MethodInterceptor; + import org.aopalliance.intercept.MethodInvocation; +-import org.hibernate.validator.HibernateValidator; + + import org.springframework.beans.factory.FactoryBean; + import org.springframework.beans.factory.SmartFactoryBean; +@@ -50,9 +49,8 @@ + * at the type level of the containing target class, applying to all public service methods + * of that class. By default, JSR-303 will validate against its default group only. + * +- * <p>As of Spring 4.0, this functionality requires either a Bean Validation 1.1 provider +- * (such as Hibernate Validator 5.x) or the Bean Validation 1.0 API with Hibernate Validator +- * 4.3. The actual provider will be autodetected and automatically adapted. ++ * <p>As of Spring 5.0, this functionality requires a Bean Validation 1.1 provider ++ * (such as Hibernate Validator 5.x). + * + * @author Juergen Hoeller + * @since 3.1 +@@ -90,8 +88,7 @@ + * Create a new MethodValidationInterceptor using a default JSR-303 validator underneath. + */ + public MethodValidationInterceptor() { +- this(forExecutablesMethod != null ? Validation.buildDefaultValidatorFactory() : +- HibernateValidatorDelegate.buildValidatorFactory()); ++ this(Validation.buildDefaultValidatorFactory()); + } + + /** +@@ -121,52 +118,36 @@ + + Class<?>[] groups = determineValidationGroups(invocation); + +- if (forExecutablesMethod != null) { +- // Standard Bean Validation 1.1 API +- Object execVal; +- try { +- execVal = ReflectionUtils.invokeMethod(forExecutablesMethod, this.validator); +- } +- catch (AbstractMethodError err) { +- // Probably an adapter (maybe a lazy-init proxy) without BV 1.1 support +- Validator nativeValidator = this.validator.unwrap(Validator.class); +- execVal = ReflectionUtils.invokeMethod(forExecutablesMethod, nativeValidator); +- // If successful, store native Validator for further use +- this.validator = nativeValidator; +- } +- +- Method methodToValidate = invocation.getMethod(); +- Set<ConstraintViolation<?>> result; +- +- try { +- result = (Set<ConstraintViolation<?>>) ReflectionUtils.invokeMethod(validateParametersMethod, +- execVal, invocation.getThis(), methodToValidate, invocation.getArguments(), groups); +- } +- catch (IllegalArgumentException ex) { +- // Probably a generic type mismatch between interface and impl as reported in SPR-12237 / HV-1011 +- // Let's try to find the bridged method on the implementation class... +- methodToValidate = BridgeMethodResolver.findBridgedMethod( +- ClassUtils.getMostSpecificMethod(invocation.getMethod(), invocation.getThis().getClass())); +- result = (Set<ConstraintViolation<?>>) ReflectionUtils.invokeMethod(validateParametersMethod, +- execVal, invocation.getThis(), methodToValidate, invocation.getArguments(), groups); +- } +- if (!result.isEmpty()) { +- throw new ConstraintViolationException(result); +- } +- +- Object returnValue = invocation.proceed(); +- result = (Set<ConstraintViolation<?>>) ReflectionUtils.invokeMethod(validateReturnValueMethod, +- execVal, invocation.getThis(), methodToValidate, returnValue, groups); +- if (!result.isEmpty()) { +- throw new ConstraintViolationException(result); +- } +- return returnValue; +- } +- +- else { +- // Hibernate Validator 4.3's native API +- return HibernateValidatorDelegate.invokeWithinValidation(invocation, this.validator, groups); ++ // Standard Bean Validation 1.1 API ++ Object execVal = ReflectionUtils.invokeMethod(forExecutablesMethod, this.validator); ++ Method methodToValidate = invocation.getMethod(); ++ Set<ConstraintViolation<?>> result; ++ ++ try { ++ result = (Set<ConstraintViolation<?>>) ReflectionUtils.invokeMethod(validateParametersMethod, ++ execVal, invocation.getThis(), methodToValidate, invocation.getArguments(), groups); ++ } ++ catch (IllegalArgumentException ex) { ++ // Probably a generic type mismatch between interface and impl as reported in SPR-12237 / HV-1011 ++ // Let's try to find the bridged method on the implementation class... ++ methodToValidate = BridgeMethodResolver.findBridgedMethod( ++ ClassUtils.getMostSpecificMethod(invocation.getMethod(), invocation.getThis().getClass())); ++ result = (Set<ConstraintViolation<?>>) ReflectionUtils.invokeMethod(validateParametersMethod, ++ execVal, invocation.getThis(), methodToValidate, invocation.getArguments(), groups); + } ++ if (!result.isEmpty()) { ++ throw new ConstraintViolationException(result); ++ } ++ ++ Object returnValue = invocation.proceed(); ++ ++ result = (Set<ConstraintViolation<?>>) ReflectionUtils.invokeMethod(validateReturnValueMethod, ++ execVal, invocation.getThis(), methodToValidate, returnValue, groups); ++ if (!result.isEmpty()) { ++ throw new ConstraintViolationException(result); ++ } ++ ++ return returnValue; + } + + private boolean isFactoryBeanMetadataMethod(Method method) { +@@ -205,36 +186,4 @@ + return (validatedAnn != null ? validatedAnn.value() : new Class<?>[0]); + } + +- +- /** +- * Inner class to avoid a hard-coded Hibernate Validator 4.3 dependency. +- */ +- private static class HibernateValidatorDelegate { +- +- public static ValidatorFactory buildValidatorFactory() { +- return Validation.byProvider(HibernateValidator.class).configure().buildValidatorFactory(); +- } +- +- @SuppressWarnings("deprecation") +- public static Object invokeWithinValidation(MethodInvocation invocation, Validator validator, Class<?>[] groups) +- throws Throwable { +- +- org.hibernate.validator.method.MethodValidator methodValidator = +- validator.unwrap(org.hibernate.validator.method.MethodValidator.class); +- Set<org.hibernate.validator.method.MethodConstraintViolation<Object>> result = +- methodValidator.validateAllParameters( +- invocation.getThis(), invocation.getMethod(), invocation.getArguments(), groups); +- if (!result.isEmpty()) { +- throw new org.hibernate.validator.method.MethodConstraintViolationException(result); +- } +- Object returnValue = invocation.proceed(); +- result = methodValidator.validateReturnValue( +- invocation.getThis(), invocation.getMethod(), returnValue, groups); +- if (!result.isEmpty()) { +- throw new org.hibernate.validator.method.MethodConstraintViolationException(result); +- } +- return returnValue; +- } +- } +- + } +--- a/spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java ++++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java +@@ -27,6 +27,7 @@ + import javax.validation.ConstraintViolation; + import javax.validation.ValidationException; + import javax.validation.Validator; ++import javax.validation.executable.ExecutableValidator; + import javax.validation.metadata.BeanDescriptor; + import javax.validation.metadata.ConstraintDescriptor; + +@@ -320,6 +321,11 @@ + } + } + ++ @Override ++ public ExecutableValidator forExecutables() { ++ return this.targetValidator.forExecutables(); ++ } ++ + + /** + * Wrapper for a String attribute which can be resolved via a {@code MessageSource}, diff --git a/debian/patches/series b/debian/patches/series index c1b2e38f914dcb4077180a692af077c6abc59869..cd82afb301b516260792db7e7024c50576bed5d0 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -21,3 +21,4 @@ 0051-reproducible-build-source-date.patch 0052-no-jasperreports.patch 0053-ignore-reactor.patch +0054-disable-hibernate-validator-4.patch