From f50b1b9c1087c6ed41ea8d28f443f10df0ec88ce Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Thu, 25 Aug 2016 08:28:35 +0200 Subject: [PATCH 001/124] HV-1060 Adding Brazilian Portuguese messages for @EAN and @ParameterScriptAssert --- .../hibernate/validator/ValidationMessages_pt_BR.properties | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/engine/src/main/resources/org/hibernate/validator/ValidationMessages_pt_BR.properties b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_pt_BR.properties index 4b739afe99..7708001c7c 100644 --- a/engine/src/main/resources/org/hibernate/validator/ValidationMessages_pt_BR.properties +++ b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_pt_BR.properties @@ -15,6 +15,7 @@ javax.validation.constraints.Size.message = tamanho deve estar entre {min org.hibernate.validator.constraints.CreditCardNumber.message = N\u00FAmero de Cart\u00E3o de Cr\u00E9dito inv\u00E1lido org.hibernate.validator.constraints.Email.message = N\u00E3o \u00E9 um endere\u00E7o de e-mail +org.hibernate.validator.constraints.EAN.message = C\u00F3digo de barras {type} inv\u00E1lido org.hibernate.validator.constraints.Length.message = Tamanho deve estar entre {min} e {max} org.hibernate.validator.constraints.LuhnCheck.message = Digito verificador para ${validatedValue} \u00E9 inv\u00E1lido, verifica\u00E7\u00E3o M\u00F3dulo 10 de Luhn falhou org.hibernate.validator.constraints.Mod10Check.message = Digito verificador para ${validatedValue} \u00E9 inv\u00E1lido, verifica\u00E7\u00E3o M\u00F3dulo 10 falhou @@ -22,10 +23,11 @@ org.hibernate.validator.constraints.Mod11Check.message = Digito verific org.hibernate.validator.constraints.ModCheck.message = Digito verificador para ${validatedValue} \u00E9 inv\u00E1lido, verifica\u00E7\u00E3o ${modType} falhou org.hibernate.validator.constraints.NotBlank.message = N\u00E3o pode estar em branco org.hibernate.validator.constraints.NotEmpty.message = N\u00E3o pode estar vazio +org.hibernate.validator.constraints.ParametersScriptAssert.message = O script "{script}" n\u00E3o retornou verdadeiro org.hibernate.validator.constraints.Range.message = O valor precisa estar entre {min} e {max} org.hibernate.validator.constraints.SafeHtml.message = Pode ter conte\u00FAdo inseguro no html org.hibernate.validator.constraints.ScriptAssert.message = Express\u00E3o de script "{script}" n\u00E3o retornou verdadeiro org.hibernate.validator.constraints.URL.message = Deve ser uma URL v\u00E1lida org.hibernate.validator.constraints.br.CNPJ.message = CNPJ inv\u00E1lido org.hibernate.validator.constraints.br.CPF.message = CPF inv\u00E1lido -org.hibernate.validator.constraints.br.TituloEleitoral.message = T\u00EDtulo Eleitoral inv\u00E1lido \ No newline at end of file +org.hibernate.validator.constraints.br.TituloEleitoral.message = T\u00EDtulo Eleitoral inv\u00E1lido From c9d541f8bf03d31775d08fa83749e54963a3b8f5 Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Wed, 24 Aug 2016 11:21:10 +0200 Subject: [PATCH 002/124] HV-1013 Avoiding call of hashCode() of validated objects in caching traversable resolver --- ...raversableResolverForSingleValidation.java | 38 +++++-------------- 1 file changed, 10 insertions(+), 28 deletions(-) diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/resolver/CachingTraversableResolverForSingleValidation.java b/engine/src/main/java/org/hibernate/validator/internal/engine/resolver/CachingTraversableResolverForSingleValidation.java index e71eae3b25..d47d4bec16 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/resolver/CachingTraversableResolverForSingleValidation.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/resolver/CachingTraversableResolverForSingleValidation.java @@ -9,6 +9,7 @@ import java.lang.annotation.ElementType; import java.util.HashMap; import java.util.Map; + import javax.validation.Path; import javax.validation.TraversableResolver; @@ -20,8 +21,8 @@ * @author Emmanuel Bernard */ public class CachingTraversableResolverForSingleValidation implements TraversableResolver { - private TraversableResolver delegate; - private Map traversables = new HashMap(); + private final TraversableResolver delegate; + private final Map traversables = new HashMap(); public CachingTraversableResolverForSingleValidation(TraversableResolver delegate) { this.delegate = delegate; @@ -29,9 +30,7 @@ public CachingTraversableResolverForSingleValidation(TraversableResolver delegat @Override public boolean isReachable(Object traversableObject, Path.Node traversableProperty, Class rootBeanType, Path pathToTraversableObject, ElementType elementType) { - TraversableHolder currentLH = new TraversableHolder( - traversableObject, traversableProperty, rootBeanType, pathToTraversableObject, elementType - ); + TraversableHolder currentLH = new TraversableHolder( traversableObject, traversableProperty ); TraversableHolder cachedLH = traversables.get( currentLH ); if ( cachedLH == null ) { currentLH.isReachable = delegate.isReachable( @@ -58,9 +57,8 @@ else if ( cachedLH.isReachable == null ) { @Override public boolean isCascadable(Object traversableObject, Path.Node traversableProperty, Class rootBeanType, Path pathToTraversableObject, ElementType elementType) { - TraversableHolder currentLH = new TraversableHolder( - traversableObject, traversableProperty, rootBeanType, pathToTraversableObject, elementType - ); + TraversableHolder currentLH = new TraversableHolder( traversableObject, traversableProperty ); + TraversableHolder cachedLH = traversables.get( currentLH ); if ( cachedLH == null ) { currentLH.isCascadable = delegate.isCascadable( @@ -88,21 +86,15 @@ else if ( cachedLH.isCascadable == null ) { private static final class TraversableHolder { private final Object traversableObject; private final Path.Node traversableProperty; - private final Class rootBeanType; - private final Path pathToTraversableObject; - private final ElementType elementType; private final int hashCode; private Boolean isReachable; private Boolean isCascadable; - private TraversableHolder(Object traversableObject, Path.Node traversableProperty, Class rootBeanType, Path pathToTraversableObject, ElementType elementType) { + private TraversableHolder(Object traversableObject, Path.Node traversableProperty) { this.traversableObject = traversableObject; this.traversableProperty = traversableProperty; - this.rootBeanType = rootBeanType; - this.pathToTraversableObject = pathToTraversableObject; - this.elementType = elementType; this.hashCode = buildHashCode(); } @@ -117,15 +109,6 @@ public boolean equals(Object o) { TraversableHolder that = (TraversableHolder) o; - if ( elementType != that.elementType ) { - return false; - } - if ( !pathToTraversableObject.equals( that.pathToTraversableObject ) ) { - return false; - } - if ( !rootBeanType.equals( that.rootBeanType ) ) { - return false; - } if ( traversableObject != null ? !traversableObject.equals( that.traversableObject ) : that.traversableObject != null ) { return false; } @@ -142,11 +125,10 @@ public int hashCode() { } public int buildHashCode() { - int result = traversableObject != null ? traversableObject.hashCode() : 0; + // HV-1013 Using identity hash code in order to avoid calling hashCode() of objects which may + // be handling null properties not correctly + int result = traversableObject != null ? System.identityHashCode( traversableObject ) : 0; result = 31 * result + traversableProperty.hashCode(); - result = 31 * result + rootBeanType.hashCode(); - result = 31 * result + pathToTraversableObject.hashCode(); - result = 31 * result + elementType.hashCode(); return result; } } From deb8f5eb1721ff7cf98b619685ff4302fb0b327c Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Mon, 29 Aug 2016 17:42:19 +0200 Subject: [PATCH 003/124] HV-1066 Don't use IDN.toASCII on the local part of the email Using IDN.toASCII on the local part of the email was a bad idea to begin with, forcing us to introduce a splitting logic on top of IDN.toASCII. Executing IDN.toASCII on each chunk of a split string is not equivalent to executing it on the whole string, potentially opening the way for other bugs. Thus, we ended up doing the following: - allow the \u0080-\uFFFF character range in the local part of the email thus allowing local parts containing UTF-8 characters; - only use IDN.toASCII on the domain name as it should be. This simplifies the logic a lot and should limit the number of bugs in this area. In passing: - improve the feedback in email validation tests; - be more cautious about how we generate the domain names in tests: each label of a domain name must be at most 63 characters long. --- .../hv/EmailValidator.java | 66 +++++++++-------- .../hv/EmailValidatorTest.java | 72 +++++++++++++------ 2 files changed, 82 insertions(+), 56 deletions(-) diff --git a/engine/src/main/java/org/hibernate/validator/internal/constraintvalidators/hv/EmailValidator.java b/engine/src/main/java/org/hibernate/validator/internal/constraintvalidators/hv/EmailValidator.java index c3176284f6..ac5faf0a55 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/constraintvalidators/hv/EmailValidator.java +++ b/engine/src/main/java/org/hibernate/validator/internal/constraintvalidators/hv/EmailValidator.java @@ -6,16 +6,17 @@ */ package org.hibernate.validator.internal.constraintvalidators.hv; +import static java.util.regex.Pattern.CASE_INSENSITIVE; + import java.net.IDN; import java.util.regex.Matcher; import java.util.regex.Pattern; + import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import org.hibernate.validator.constraints.Email; -import static java.util.regex.Pattern.CASE_INSENSITIVE; - /** * Checks that a given character sequence (e.g. string) is a well-formed email address. *

@@ -29,25 +30,31 @@ * * @author Emmanuel Bernard * @author Hardy Ferentschik + * @author Guillaume Smet */ public class EmailValidator implements ConstraintValidator { - private static final String ATOM = "[a-z0-9!#$%&'*+/=?^_`{|}~-]"; - private static final String DOMAIN = ATOM + "+(\\." + ATOM + "+)*"; + private static final String LOCAL_PART_ATOM = "[a-z0-9!#$%&'*+/=?^_`{|}~\u0080-\uFFFF-]"; + private static final String DOMAIN_LABEL = "[a-z0-9!#$%&'*+/=?^_`{|}~-]"; + private static final String DOMAIN = DOMAIN_LABEL + "+(\\." + DOMAIN_LABEL + "+)*"; private static final String IP_DOMAIN = "\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\]"; private static final int MAX_LOCAL_PART_LENGTH = 64; + /** + * This is the maximum length of a domain name. But be aware that each label (parts separated by a dot) of the + * domain name must be at most 63 characters long. This is verified by {@link IDN#toASCII(String)}. + */ private static final int MAX_DOMAIN_PART_LENGTH = 255; /** * Regular expression for the local part of an email address (everything before '@') */ - private final Pattern localPattern = java.util.regex.Pattern.compile( - ATOM + "+(\\." + ATOM + "+)*", CASE_INSENSITIVE + private static final Pattern LOCAL_PART_PATTERN = Pattern.compile( + LOCAL_PART_ATOM + "+(\\." + LOCAL_PART_ATOM + "+)*", CASE_INSENSITIVE ); /** * Regular expression for the domain part of an email address (everything after '@') */ - private final Pattern domainPattern = java.util.regex.Pattern.compile( + private static final Pattern DOMAIN_PATTERN = Pattern.compile( DOMAIN + "|" + IP_DOMAIN, CASE_INSENSITIVE ); @@ -70,51 +77,42 @@ public boolean isValid(CharSequence value, ConstraintValidatorContext context) { return false; } - // if we have a trailing dot in local or domain part we have an invalid email address. - // the regular expression match would take care of this, but IDN.toASCII drops the trailing '.' - // (imo a bug in the implementation) - if ( emailParts[0].endsWith( "." ) || emailParts[1].endsWith( "." ) ) { + if ( !matchLocalPart( emailParts[0] ) ) { return false; } - if ( !matchPart( emailParts[0], localPattern, MAX_LOCAL_PART_LENGTH ) ) { + return matchDomain( emailParts[1] ); + } + + private boolean matchLocalPart(String localPart) { + if ( localPart.length() > MAX_LOCAL_PART_LENGTH ) { return false; } - - return matchPart( emailParts[1], domainPattern, MAX_DOMAIN_PART_LENGTH ); + Matcher matcher = LOCAL_PART_PATTERN.matcher( localPart ); + return matcher.matches(); } - private boolean matchPart(String part, Pattern pattern, int maxLength) { + private boolean matchDomain(String domain) { + // if we have a trailing dot the domain part we have an invalid email address. + // the regular expression match would take care of this, but IDN.toASCII drops the trailing '.' + if ( domain.endsWith( "." ) ) { + return false; + } + String asciiString; try { - asciiString = toAscii( part ); + asciiString = IDN.toASCII( domain ); } catch (IllegalArgumentException e) { return false; } - if ( asciiString.length() > maxLength ) { + if ( asciiString.length() > MAX_DOMAIN_PART_LENGTH ) { return false; } - Matcher matcher = pattern.matcher( asciiString ); + Matcher matcher = DOMAIN_PATTERN.matcher( asciiString ); return matcher.matches(); } - private String toAscii(String unicodeString) throws IllegalArgumentException { - String asciiString = ""; - int start = 0; - int end = unicodeString.length() <= 63 ? unicodeString.length() : 63; - while ( true ) { - // IDN.toASCII only supports a max "label" length of 63 characters. Need to chunk the input in these sizes - asciiString += IDN.toASCII( unicodeString.substring( start, end ) ); - if ( end == unicodeString.length() ) { - break; - } - start = end; - end = start + 63 > unicodeString.length() ? unicodeString.length() : start + 63; - } - - return asciiString; - } } diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/constraintvalidators/hv/EmailValidatorTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/constraintvalidators/hv/EmailValidatorTest.java index 593d37270f..fc12c71a74 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/constraintvalidators/hv/EmailValidatorTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/constraintvalidators/hv/EmailValidatorTest.java @@ -6,13 +6,19 @@ */ package org.hibernate.validator.test.internal.constraintvalidators.hv; +import static java.lang.annotation.ElementType.METHOD; +import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertCorrectConstraintViolationMessages; +import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertNumberOfViolations; +import static org.hibernate.validator.testutils.ValidatorUtil.getConfiguration; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; +import static org.testng.AssertJUnit.assertEquals; + import java.util.Set; + import javax.validation.ConstraintViolation; import javax.validation.Validator; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - import org.hibernate.validator.HibernateValidator; import org.hibernate.validator.HibernateValidatorConfiguration; import org.hibernate.validator.cfg.ConstraintMapping; @@ -22,17 +28,12 @@ import org.hibernate.validator.testutil.MyCustomStringImpl; import org.hibernate.validator.testutil.TestForIssue; import org.hibernate.validator.testutils.ValidatorUtil; - -import static java.lang.annotation.ElementType.METHOD; -import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertCorrectConstraintViolationMessages; -import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertNumberOfViolations; -import static org.hibernate.validator.testutils.ValidatorUtil.getConfiguration; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertTrue; -import static org.testng.AssertJUnit.assertEquals; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; /** * @author Hardy Ferentschik + * @author Guillaume Smet */ public class EmailValidatorTest { // http://stackoverflow.com/questions/406230/regular-expression-to-match-string-not-containing-a-word @@ -74,6 +75,7 @@ public void testInValidEmail() throws Exception { isInvalidEmail( "emmanuel@" ); isInvalidEmail( "emma\nnuel@hibernate.org" ); isInvalidEmail( "emma@nuel@hibernate.org" ); + isInvalidEmail( "emma@nuel@.hibernate.org" ); isInvalidEmail( "Just a string" ); isInvalidEmail( "string" ); isInvalidEmail( "me@" ); @@ -154,10 +156,12 @@ public void testEMailWithTrailingAt() throws Exception { } @Test - @TestForIssue(jiraKey = "HV-1005") - public void testEmailWith64CharacterLocalPartIsValid() { + @TestForIssue(jiraKey = { "HV-1005", "HV-1066" }) + public void testEmailWithUpTo64CharacterLocalPartIsValid() { // Local part should allow up to 64 octets: https://tools.ietf.org/html/rfc5321#section-4.5.3.1.1 - isValidEmail( stringOfLength( 64 ) + "@foo.com" ); + for ( int length = 1; length <= 64; length++ ) { + isValidEmail( stringOfLength( length ) + "@foo.com" ); + } } @Test @@ -167,17 +171,25 @@ public void testEmailWith65CharacterLocalPartIsInvalid() { } @Test - @TestForIssue(jiraKey = "HV-1005") - public void testEmailWith255CharacterDomainPartIsValid() { + @TestForIssue(jiraKey = { "HV-1005", "HV-1066" }) + public void testEmailWithUpTo255CharacterDomainPartIsValid() { // Domain part should allow up to 255 - isValidEmail( "foo@" + stringOfLength( 251 ) + ".com" ); + for ( int length = 1; length <= 251; length++ ) { + isValidEmail( "foo@" + domainOfLength( length ) + ".com" ); + } + } + + @Test + @TestForIssue(jiraKey = { "HV-1005", "HV-1066" }) + public void testEmailWith63CharactersDomainPartIsValid() { + isValidEmail( "foo@" + stringOfLength( 63 ) + "." + stringOfLength( 63 ) + ".com" ); } @Test @TestForIssue(jiraKey = "HV-1005") public void testEmailWith256CharacterDomainPartIsInvalid() { // Domain part should allow up to 255 - isInvalidEmail( "foo@" + stringOfLength( 252 ) + ".com" ); + isInvalidEmail( "foo@" + domainOfLength( 252 ) + ".com" ); } private String stringOfLength(int length) { @@ -190,25 +202,41 @@ private String stringOfLength(int length) { return s; } + private String domainOfLength(int length) { + StringBuilder builder = new StringBuilder(); + for ( int i = 0; i < length; i++ ) { + // we insert a dot from time to time to be sure each label of the domain name is at most 63 characters long + if ( i % 32 == 0 && i > 0 && i < length - 1 ) { + builder.append( "." ); + } + else { + builder.append( 'a' ); + } + } + String s = builder.toString(); + assertEquals( length, s.getBytes().length ); + return s; + } + private void assertOrgAddressesAreNotValid(Set> violations) { assertNumberOfViolations( violations, 1 ); assertCorrectConstraintViolationMessages( violations, "ORG addresses are not valid" ); } private void isValidEmail(CharSequence email, String message) { - assertTrue( validator.isValid( email, null ), message ); + assertTrue( validator.isValid( email, null ), String.format( message, email ) ); } private void isValidEmail(CharSequence email) { - isValidEmail( email, "Expected a valid email." ); + isValidEmail( email, "Expected %1$s to be a valid email." ); } private void isInvalidEmail(CharSequence email, String message) { - assertFalse( validator.isValid( email, null ), message ); + assertFalse( validator.isValid( email, null ), String.format( message, email ) ); } private void isInvalidEmail(CharSequence email) { - isInvalidEmail( email, "Expected a invalid email." ); + isInvalidEmail( email, "Expected %1$s to be an invalid email." ); } @SuppressWarnings("unused") From 34844cdfaee51be504eb565a0ae6a9e2847b97e9 Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Wed, 31 Aug 2016 09:27:21 +0200 Subject: [PATCH 004/124] HV-1080 Simplifying retrieval of cascaded values; * No instanceof check needed anymore * No repeated setAccessible() calls * No need to expose getCascadedMember() on PropertyMetadata --- .../internal/engine/ValidatorImpl.java | 23 +++----- .../aggregated/ParameterMetaData.java | 9 ++- .../metadata/aggregated/PropertyMetaData.java | 58 +++++++++++++++++-- .../aggregated/ReturnValueMetaData.java | 6 ++ .../internal/metadata/facets/Cascadable.java | 6 ++ 5 files changed, 78 insertions(+), 24 deletions(-) diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java index 51be01f1ec..685de0ff26 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java @@ -6,6 +6,10 @@ */ package org.hibernate.validator.internal.engine; +import static org.hibernate.validator.internal.util.CollectionHelper.newArrayList; +import static org.hibernate.validator.internal.util.CollectionHelper.newHashMap; +import static org.hibernate.validator.internal.util.logging.Messages.MESSAGES; + import java.lang.annotation.ElementType; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Constructor; @@ -23,6 +27,7 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentMap; + import javax.validation.ConstraintValidatorFactory; import javax.validation.ConstraintViolation; import javax.validation.ElementKind; @@ -70,10 +75,6 @@ import org.hibernate.validator.spi.time.TimeProvider; import org.hibernate.validator.spi.valuehandling.ValidatedValueUnwrapper; -import static org.hibernate.validator.internal.util.CollectionHelper.newArrayList; -import static org.hibernate.validator.internal.util.CollectionHelper.newHashMap; -import static org.hibernate.validator.internal.util.logging.Messages.MESSAGES; - /** * The main Bean Validation class. This is the core processing class of Hibernate Validator. * @@ -178,7 +179,7 @@ public ValidatorImpl(ConstraintValidatorFactory constraintValidatorFactory, validationOrderGenerator = new ValidationOrderGenerator(); - this.accessibleMembers = new ConcurrentReferenceHashMap( + this.accessibleMembers = new ConcurrentReferenceHashMap<>( 100, ReferenceType.SOFT, ReferenceType.SOFT @@ -1654,17 +1655,7 @@ private boolean shouldFailFast(ValidationContext context) { } private Object getValue(Object object, ValidationContext validationContext, Cascadable cascadable) { - Object value; - if ( cascadable instanceof PropertyMetaData ) { - Member member = getAccessible( ( (PropertyMetaData) cascadable ).getCascadingMember() ); - value = getValue( member, object ); - } - else if ( cascadable instanceof ParameterMetaData ) { - value = ( (Object[]) object )[( (ParameterMetaData) cascadable ).getIndex()]; - } - else { - value = object; - } + Object value = cascadable.getValue( object ); // Value can be wrapped (e.g. Optional

). Try to unwrap it UnwrapMode unwrapMode = cascadable.unwrapMode(); diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ParameterMetaData.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ParameterMetaData.java index 41b1d0fb4d..d25ac1c27d 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ParameterMetaData.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ParameterMetaData.java @@ -6,6 +6,8 @@ */ package org.hibernate.validator.internal.metadata.aggregated; +import static org.hibernate.validator.internal.util.CollectionHelper.newHashSet; + import java.lang.annotation.ElementType; import java.lang.reflect.Type; import java.util.Collections; @@ -26,8 +28,6 @@ import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind; import org.hibernate.validator.internal.metadata.raw.ConstrainedParameter; -import static org.hibernate.validator.internal.util.CollectionHelper.newHashSet; - /** * An aggregated view of the constraint related meta data for a single method * parameter. @@ -108,6 +108,11 @@ public ParameterDescriptor asDescriptor(boolean defaultGroupSequenceRedefined, L ); } + @Override + public Object getValue(Object parent) { + return ( (Object[]) parent )[getIndex()]; + } + public static class Builder extends MetaDataBuilder { private final Type parameterType; private final int parameterIndex; diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java index 1105d3bc6e..981d3b3353 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java @@ -6,10 +6,16 @@ */ package org.hibernate.validator.internal.metadata.aggregated; +import static org.hibernate.validator.internal.util.CollectionHelper.newHashSet; + import java.lang.annotation.ElementType; +import java.lang.reflect.AccessibleObject; import java.lang.reflect.Field; import java.lang.reflect.Member; +import java.lang.reflect.Method; import java.lang.reflect.Type; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.Collections; import java.util.EnumSet; import java.util.List; @@ -32,8 +38,9 @@ import org.hibernate.validator.internal.util.ReflectionHelper; import org.hibernate.validator.internal.util.logging.Log; import org.hibernate.validator.internal.util.logging.LoggerFactory; - -import static org.hibernate.validator.internal.util.CollectionHelper.newHashSet; +import org.hibernate.validator.internal.util.privilegedactions.GetDeclaredField; +import org.hibernate.validator.internal.util.privilegedactions.GetDeclaredMethod; +import org.hibernate.validator.internal.util.privilegedactions.SetAccessibility; /** * Represents the constraint related meta data for a JavaBeans property. @@ -86,7 +93,7 @@ private PropertyMetaData(String propertyName, ); if ( cascadingMember != null ) { - this.cascadingMember = cascadingMember; + this.cascadingMember = getAccessible( cascadingMember ); this.elementType = cascadingMember instanceof Field ? ElementType.FIELD : ElementType.METHOD; } else { @@ -99,8 +106,28 @@ private PropertyMetaData(String propertyName, this.groupConversionHelper.validateGroupConversions( isCascading(), this.toString() ); } - public Member getCascadingMember() { - return cascadingMember; + /** + * Returns an accessible version of the given member. Will be the given member itself in case it is accessible, + * otherwise a copy which is set accessible. + */ + private static Member getAccessible(Member original) { + if ( ( (AccessibleObject) original ).isAccessible() ) { + return original; + } + + Class clazz = original.getDeclaringClass(); + Member member; + + if ( original instanceof Field ) { + member = run( GetDeclaredField.action( clazz, original.getName() ) ); + } + else { + member = run( GetDeclaredMethod.action( clazz, original.getName() ) ); + } + + run( SetAccessibility.action( member ) ); + + return member; } @Override @@ -137,8 +164,27 @@ public PropertyDescriptorImpl asDescriptor(boolean defaultGroupSequenceRedefined } @Override - public String toString() { + public Object getValue(Object parent) { + if ( elementType == ElementType.METHOD ) { + return ReflectionHelper.getValue( (Method) cascadingMember, parent ); + } + else { + return ReflectionHelper.getValue( (Field) cascadingMember, parent ); + } + } + /** + * Runs the given privileged action, using a privileged block if required. + *

+ * NOTE: This must never be changed into a publicly available method to avoid execution of arbitrary + * privileged actions within HV's protection domain. + */ + private static T run(PrivilegedAction action) { + return System.getSecurityManager() != null ? AccessController.doPrivileged( action ) : action.run(); + } + + @Override + public String toString() { return "PropertyMetaData [type=" + getType() + ", propertyName=" + getName() + ", cascadingMember=[" + cascadingMember + "]]"; } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ReturnValueMetaData.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ReturnValueMetaData.java index ad0f155d8e..4b1b69cc6a 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ReturnValueMetaData.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ReturnValueMetaData.java @@ -13,6 +13,7 @@ import java.util.List; import java.util.Map; import java.util.Set; + import javax.validation.ElementKind; import javax.validation.metadata.GroupConversionDescriptor; import javax.validation.metadata.ReturnValueDescriptor; @@ -100,4 +101,9 @@ public ReturnValueDescriptor asDescriptor(boolean defaultGroupSequenceRedefined, groupConversionHelper.asDescriptors() ); } + + @Override + public Object getValue(Object parent) { + return parent; + } } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/facets/Cascadable.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/facets/Cascadable.java index e58eb5244d..59b1053696 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/facets/Cascadable.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/facets/Cascadable.java @@ -9,6 +9,7 @@ import java.lang.annotation.ElementType; import java.lang.reflect.Type; import java.util.Set; + import javax.validation.ElementKind; import javax.validation.metadata.GroupConversionDescriptor; @@ -89,4 +90,9 @@ public interface Cascadable { * @return This cascadable type. */ Type getType(); + + /** + * Returns the value of this cacadable from the given parent. + */ + Object getValue(Object parent); } From 9de1ab4e75b3a98f68d9e17d67fb4c33e9ebd6c6 Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Wed, 31 Aug 2016 10:36:54 +0200 Subject: [PATCH 005/124] HV-1080 Making sure that the correct type is used for unwrapper resolution; When determining the unwrapper for a cascadable property, it wasn't determined which type (the one from the field or the getter) would be used. Mostly that doesn't matter, but it makes a difference if the field is a "normal" type and the getter is an Optional of this type. Now always the type of the cascadable member (marked with @Valid) is used. --- .../internal/engine/ValidatorImpl.java | 2 +- .../aggregated/ParameterMetaData.java | 5 + .../metadata/aggregated/PropertyMetaData.java | 9 ++ .../aggregated/ReturnValueMetaData.java | 5 + .../internal/metadata/facets/Cascadable.java | 2 +- .../valuehandling/CascadedOptionalTest.java | 96 +++++++++++++++++++ 6 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 engine/src/test/java/org/hibernate/validator/test/internal/engine/valuehandling/CascadedOptionalTest.java diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java index 685de0ff26..e78804d936 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java @@ -1660,7 +1660,7 @@ private Object getValue(Object object, ValidationContext validationContext, Casc // Value can be wrapped (e.g. Optional

). Try to unwrap it UnwrapMode unwrapMode = cascadable.unwrapMode(); if ( UnwrapMode.UNWRAP.equals( unwrapMode ) || UnwrapMode.AUTOMATIC.equals( unwrapMode ) ) { - ValidatedValueUnwrapper valueHandler = validationContext.getValidatedValueUnwrapper( cascadable.getType() ); + ValidatedValueUnwrapper valueHandler = validationContext.getValidatedValueUnwrapper( cascadable.getCascadableType() ); if ( valueHandler != null ) { value = valueHandler.handleValidatedValue( value ); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ParameterMetaData.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ParameterMetaData.java index d25ac1c27d..184e01cb5f 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ParameterMetaData.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ParameterMetaData.java @@ -113,6 +113,11 @@ public Object getValue(Object parent) { return ( (Object[]) parent )[getIndex()]; } + @Override + public Type getCascadableType() { + return getType(); + } + public static class Builder extends MetaDataBuilder { private final Type parameterType; private final int parameterIndex; diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java index 981d3b3353..911eb3f323 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java @@ -66,6 +66,8 @@ public class PropertyMetaData extends AbstractConstraintMetaData implements Casc */ private final Member cascadingMember; + private final Type cascadableType; + private final ElementType elementType; private final GroupConversionHelper groupConversionHelper; @@ -94,10 +96,12 @@ private PropertyMetaData(String propertyName, if ( cascadingMember != null ) { this.cascadingMember = getAccessible( cascadingMember ); + this.cascadableType = ReflectionHelper.typeOf( cascadingMember ); this.elementType = cascadingMember instanceof Field ? ElementType.FIELD : ElementType.METHOD; } else { this.cascadingMember = null; + this.cascadableType = null; this.elementType = ElementType.TYPE; } @@ -173,6 +177,11 @@ public Object getValue(Object parent) { } } + @Override + public Type getCascadableType() { + return cascadableType; + } + /** * Runs the given privileged action, using a privileged block if required. *

diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ReturnValueMetaData.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ReturnValueMetaData.java index 4b1b69cc6a..4d41626c9b 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ReturnValueMetaData.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/ReturnValueMetaData.java @@ -106,4 +106,9 @@ public ReturnValueDescriptor asDescriptor(boolean defaultGroupSequenceRedefined, public Object getValue(Object parent) { return parent; } + + @Override + public Type getCascadableType() { + return getType(); + } } diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/facets/Cascadable.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/facets/Cascadable.java index 59b1053696..cb673bd695 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/facets/Cascadable.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/facets/Cascadable.java @@ -89,7 +89,7 @@ public interface Cascadable { * * @return This cascadable type. */ - Type getType(); + Type getCascadableType(); /** * Returns the value of this cacadable from the given parent. diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/engine/valuehandling/CascadedOptionalTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/engine/valuehandling/CascadedOptionalTest.java new file mode 100644 index 0000000000..abedd5d7fe --- /dev/null +++ b/engine/src/test/java/org/hibernate/validator/test/internal/engine/valuehandling/CascadedOptionalTest.java @@ -0,0 +1,96 @@ +/* + * Hibernate Validator, declare and validate application constraints + * + * License: Apache License, Version 2.0 + * See the license.txt file in the root directory or . + */ +package org.hibernate.validator.test.internal.engine.valuehandling; + +import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertCorrectPropertyPaths; +import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertNumberOfViolations; +import static org.hibernate.validator.testutils.ValidatorUtil.getValidator; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +import java.util.Optional; +import java.util.Set; + +import javax.validation.ConstraintViolation; +import javax.validation.Valid; +import javax.validation.Validator; +import javax.validation.constraints.NotNull; + +import org.hibernate.validator.testutil.TestForIssue; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +/** + * Ensure we can handle a field of type T and a getter of type Optional. + * + * @author Gunnar Morling + */ +@TestForIssue(jiraKey = "HV-1080") +public class CascadedOptionalTest { + + private Validator validator; + + @BeforeClass + public void setupValidator() { + validator = getValidator(); + } + + @Test + public void cascadedValueIsRetrievedFromField() { + PondWithCascadedField pond = new PondWithCascadedField(); + pond.masterFish = new MasterFish(); + + Set> constraintViolations = validator.validate( pond ); + + assertNumberOfViolations( constraintViolations, 1 ); + assertCorrectPropertyPaths( constraintViolations, "masterFish.name" ); + assertFalse( pond.getMasterFishInvoked ); + } + + @Test + public void cascadedValueIsRetrievedFromGetterApplyingUnwrapper() { + PondWithCascadedGetter pond = new PondWithCascadedGetter(); + pond.masterFish = new MasterFish(); + + Set> constraintViolations = validator.validate( pond ); + + assertNumberOfViolations( constraintViolations, 1 ); + assertCorrectPropertyPaths( constraintViolations, "masterFish.name" ); + assertTrue( pond.getMasterFishInvoked ); + } + + private class PondWithCascadedField { + + @Valid + private MasterFish masterFish; + private boolean getMasterFishInvoked = false; + + @SuppressWarnings("unused") + public Optional getMasterFish() { + getMasterFishInvoked = true; + return Optional.ofNullable( masterFish ); + } + } + + private class PondWithCascadedGetter { + + private MasterFish masterFish; + private boolean getMasterFishInvoked = false; + + @Valid + public Optional getMasterFish() { + getMasterFishInvoked = true; + return Optional.ofNullable( masterFish ); + } + } + + private class MasterFish { + + @NotNull + private String name; + } +} From 79c5ed5d327cd515025af472d6dd16e8c87e4a77 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Wed, 31 Aug 2016 15:44:36 +0200 Subject: [PATCH 006/124] HV-1080 Fix a diamond introduced in a previous commit 34844cdfaee51be504eb565a0ae6a9e2847b97e9 introduced a diamond operator while we are still in Java 6 in the 5.3 branch --- .../org/hibernate/validator/internal/engine/ValidatorImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java index e78804d936..b7b0e73af2 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java @@ -179,7 +179,7 @@ public ValidatorImpl(ConstraintValidatorFactory constraintValidatorFactory, validationOrderGenerator = new ValidationOrderGenerator(); - this.accessibleMembers = new ConcurrentReferenceHashMap<>( + this.accessibleMembers = new ConcurrentReferenceHashMap( 100, ReferenceType.SOFT, ReferenceType.SOFT From 1d0160ff3c17b06a45dc89bfc1c1b3a643c3beee Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Fri, 26 Aug 2016 15:28:44 +0200 Subject: [PATCH 007/124] HV-1092 Provide a settings-example.xml --- .travis.yml | 4 +-- README.md | 4 +-- settings-example.xml | 68 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 settings-example.xml diff --git a/.travis.yml b/.travis.yml index 1729ded0d8..c2620ec715 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ install: - mvn -N io.takari:maven:wrapper - ./mvnw -v # first run to download all the Maven dependencies without logging - - travis_wait ./mvnw -B -q -DskipTests=true install + - travis_wait ./mvnw -s settings-example.xml -B -q -DskipTests=true install before_script: script: - - ./mvnw clean verify + - ./mvnw -s settings-example.xml clean verify diff --git a/README.md b/README.md index bbffa97dcf..5e890e667a 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ the Apache Software License 2.0. Refer to license.txt for more information. You can build Hibernate Validator from source by cloning the git repository git://github.com/hibernate/hibernate-validator.git. You will also need a JDK 8 and Maven 3 (>= 3.0.3). With these prerequisites in place you can compile the source via - mvn clean install + mvn -s settings-example.xml clean install There are more build options available as well. For more information refer to [Contributing to Hibernate Validator](http://hibernate.org/validator/contribute/). @@ -88,7 +88,7 @@ To build Hibernate Validator with JDK 9, export the following environment variab Then the build can be started like this: - mvn clean install -DdisableDocumentationBuild=true -DdisableDistributionBuild + mvn -s settings-example.xml clean install -DdisableDocumentationBuild=true -DdisableDistributionBuild The documentation and distribution modules are known to not work on Java 9 for the time being, hence they need to be excluded. Also the integration tests on WildFly will fail on Java 9 currently, hence this "integration" module is excluded automatically when building on JDK 9. diff --git a/settings-example.xml b/settings-example.xml new file mode 100644 index 0000000000..e96f41de72 --- /dev/null +++ b/settings-example.xml @@ -0,0 +1,68 @@ + + + + + + jboss-public-repository + + + + central + Maven Central + http://repo.maven.apache.org/maven2/ + + false + never + + + + jboss-public-repository-group + JBoss Public Maven Repository Group + https://repository.jboss.org/nexus/content/groups/public-jboss/ + default + + true + never + + + true + never + + + + + + + central + Maven Central + http://repo.maven.apache.org/maven2/ + + false + never + + + + jboss-public-repository-group + JBoss Public Maven Repository Group + https://repository.jboss.org/nexus/content/groups/public-jboss/ + default + + true + never + + + true + never + + + + + + + + jboss-public-repository + + + From 46fd97c247e73e1aa016749865eb771777ae0c15 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Mon, 22 Aug 2016 18:22:55 +0200 Subject: [PATCH 008/124] HV-1086 Update Maven plugin dependencies --- .../src/main/resources/checkstyle.xml | 2 +- distribution/src/main/assembly/dist.xml | 2 - pom.xml | 77 +++++++------------ 3 files changed, 28 insertions(+), 53 deletions(-) diff --git a/build-config/src/main/resources/checkstyle.xml b/build-config/src/main/resources/checkstyle.xml index 8c16ca9c1a..71c808d511 100644 --- a/build-config/src/main/resources/checkstyle.xml +++ b/build-config/src/main/resources/checkstyle.xml @@ -131,7 +131,7 @@ diff --git a/distribution/src/main/assembly/dist.xml b/distribution/src/main/assembly/dist.xml index f3e2a915b6..b03f1c6591 100644 --- a/distribution/src/main/assembly/dist.xml +++ b/distribution/src/main/assembly/dist.xml @@ -87,8 +87,6 @@ license.txt - **/zanata.sh - **/zanata.xml src/main/scripts/** hibernate-noorm-release-scripts/** diff --git a/pom.xml b/pom.xml index 5a5c812536..40b4f61644 100644 --- a/pom.xml +++ b/pom.xml @@ -96,7 +96,7 @@ - 6.19 + 7.1 @@ -282,9 +282,8 @@ - org.apache.maven.plugins maven-enforcer-plugin - 1.0.1 + 1.4.1 enforce-java @@ -308,19 +307,16 @@ - org.apache.maven.plugins maven-antrun-plugin - 1.4 + 1.8 - org.apache.maven.plugins maven-clean-plugin - 2.5 + 3.0.0 - org.apache.maven.plugins maven-jar-plugin - 2.4 + 3.0.2 @@ -328,15 +324,14 @@ ${project.version} ${project.parent.groupId} ${project.parent.groupId} - http://validator.hibernate.org + http://hibernate.org/validator/ - org.apache.maven.plugins maven-compiler-plugin - 3.1 + 3.5.1 1.6 1.6 @@ -344,7 +339,6 @@ - org.apache.maven.plugins maven-checkstyle-plugin 2.17 @@ -409,14 +403,14 @@ org.codehaus.mojo animal-sniffer-maven-plugin - 1.11 + 1.15 org.ow2.asm asm-all - 5.0.3 + 5.0.4 @@ -440,9 +434,8 @@ - org.apache.maven.plugins maven-surefire-plugin - 2.15 + 2.19.1 once true @@ -452,9 +445,8 @@ - org.apache.maven.plugins maven-surefire-report-plugin - 2.12 + 2.19.1 generate-test-report @@ -470,9 +462,8 @@ - org.apache.maven.plugins maven-failsafe-plugin - 2.18.1 + 2.19.1 integration-test @@ -484,24 +475,20 @@ - org.apache.maven.plugins maven-dependency-plugin - 2.4 + 2.10 - org.apache.maven.plugins maven-install-plugin - 2.3.1 + 2.5.2 - org.apache.maven.plugins maven-assembly-plugin - 2.3 + 2.6 - org.apache.maven.plugins maven-release-plugin - 2.5.1 + 2.5.3 clean install true @@ -515,7 +502,7 @@ org.codehaus.mojo exec-maven-plugin - 1.2.1 + 1.5.0 org.codehaus.mojo @@ -544,7 +531,7 @@ org.asciidoctor asciidoctor-maven-plugin - 1.5.2 + 1.5.3 index.asciidoc book @@ -555,24 +542,21 @@ - org.apache.maven.plugins maven-project-info-reports-plugin - 2.0.1 + 2.9 org.apache.felix maven-bundle-plugin - 2.5.0 + 3.2.0 - org.apache.maven.plugins maven-source-plugin - 2.1.2 + 3.0.1 - org.apache.maven.plugins maven-javadoc-plugin - 2.9 + 2.10.4 true ${project.basedir}/../src/main/javadoc @@ -582,19 +566,12 @@ - org.apache.maven.plugins maven-deploy-plugin - 2.7 + 2.8.2 - org.zanata - zanata-maven-plugin - 1.3 - - - org.apache.maven.plugins maven-resources-plugin - 2.6 + 3.0.1 @@ -617,18 +594,18 @@ org.apache.servicemix.tooling depends-maven-plugin - 1.2 + 1.3.1 org.codehaus.mojo build-helper-maven-plugin - 1.8 + 1.12 org.codehaus.mojo clirr-maven-plugin - 2.5 + 2.7 5.2.4.Final From 4727147e7f1c8e5aea8054cf4982cfde88464b0f Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Mon, 22 Aug 2016 20:06:09 +0200 Subject: [PATCH 009/124] HV-1086 Update Maven dependencies --- engine/pom.xml | 2 +- osgi/integrationtest/pom.xml | 5 +-- osgi/karaf-features/pom.xml | 5 --- pom.xml | 84 +++++++++++++++++++++++++----------- 4 files changed, 62 insertions(+), 34 deletions(-) diff --git a/engine/pom.xml b/engine/pom.xml index 45bea60230..b5bf8c1740 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -196,7 +196,7 @@ org.xml.sax.*;version="0", org.jboss.logging.*;version="[3.1.0,4.0.0)", com.fasterxml.classmate.*;version="[${classmate.version},2.0.0)", - org.joda.time.*;version="[1.6.0,2.0.0)";resolution:=optional, + org.joda.time.*;version="[2.0.0,3.0.0)";resolution:=optional, org.jsoup.*;version="[1.5.2,2.0.0)";resolution:=optional, com.thoughtworks.paranamer.*;version="[2.5.5,3.0.0)";resolution:=optional diff --git a/osgi/integrationtest/pom.xml b/osgi/integrationtest/pom.xml index 3400aa2652..aeab64132e 100644 --- a/osgi/integrationtest/pom.xml +++ b/osgi/integrationtest/pom.xml @@ -23,9 +23,6 @@ true - 4.8.0 - 2.4.7 - 3.0.6 @@ -97,7 +94,7 @@ org.osgi org.osgi.core - 6.0.0 + ${osgi-core.version} test diff --git a/osgi/karaf-features/pom.xml b/osgi/karaf-features/pom.xml index 3fe2274b66..0e7ca30c96 100644 --- a/osgi/karaf-features/pom.xml +++ b/osgi/karaf-features/pom.xml @@ -21,11 +21,6 @@ Hibernate Validator Karaf Features Hibernate Validator features for Apache Karaf - - 4.4.0 - 3.0.3 - - diff --git a/pom.xml b/pom.xml index 40b4f61644..a48209280b 100644 --- a/pom.xml +++ b/pom.xml @@ -74,29 +74,57 @@ + 1.6 + 1.6 + UTF-8 true - - 1.0-beta-3 1.1.0.Final - 1.1.0 - 2.5.5 - 2.7 - 1.8.3 - 10.0.0.Final - 1.1.9.Final - 1.7.2 - 3.3.0.Final + + 2.8 2.2.4 + 3.3.0.Final 2.0.1.Final - - + + 1.0-beta-3 + + + 1.3.1 + 1.8.3 + 2.7 + 1.7.7 + 1.0.0.Final + + + 10.1.0.Final + 1.2 + 2.3.5.Final + 1.0.2.Final + 1.0.0.Final + + 1.1.11.Final + + + 4.8.0 + 2.4.7 + 3.0.6 + 6.0.0 7.1 + + + @@ -189,12 +217,12 @@ org.hibernate.javax.persistence hibernate-jpa-2.1-api - 1.0.0.Final + ${hibernate-jpa-2.1-api.version} junit junit - 4.11 + 4.12 org.testng @@ -204,12 +232,12 @@ org.codehaus.groovy groovy-jsr223 - 2.4.1 + 2.4.7 org.easymock easymock - 3.1 + 3.4 org.easytesting @@ -236,22 +264,32 @@ org.jboss.spec.javax.ejb jboss-ejb-api_3.2_spec - 1.0.0.Final + ${jboss-ejb-api_3.2_spec.version} javax.enterprise cdi-api - 1.2 + ${cdi-api.version} + + + javax.interceptor + javax.interceptor-api + + + javax.el + javax.el-api + + org.jboss.weld weld-core - 2.3.0.CR2 + ${weld.version} org.wildfly.arquillian wildfly-arquillian-container-managed - 1.0.1.Final + ${wildfly-arquillian.version} sun.jdk @@ -333,8 +371,6 @@ maven-compiler-plugin 3.5.1 - 1.6 - 1.6 -parameters @@ -361,12 +397,12 @@ org.slf4j jcl-over-slf4j - 1.7.5 + ${slf4j.version} org.slf4j slf4j-jdk14 - 1.7.5 + ${slf4j.version} From c63c0578a51fbfac17fcec81d526e4219d4e7a4f Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Wed, 31 Aug 2016 16:51:44 +0200 Subject: [PATCH 010/124] HV-1014 Clarify what @ValidPart is in example 2.3 of the reference guide --- documentation/src/main/asciidoc/ch02.asciidoc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/documentation/src/main/asciidoc/ch02.asciidoc b/documentation/src/main/asciidoc/ch02.asciidoc index de129d5f56..adc98c37ad 100644 --- a/documentation/src/main/asciidoc/ch02.asciidoc +++ b/documentation/src/main/asciidoc/ch02.asciidoc @@ -152,6 +152,8 @@ When applying constraints on an `Iterable` type argument, Hibernate Validator wi element. <> shows an example of a `List` with a type argument constraint. +In this example, `@ValidPart` is a custom constraint allowed to be used in the `TYPE_USE` context. + [[example-type-arguments-constraints-collections]] .Type argument constraint on `List` ==== From 72049532fa289d0f5664e9b1a7fd19fd514e595f Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Wed, 31 Aug 2016 15:28:25 +0200 Subject: [PATCH 011/124] HV-1091 Using iterative instead of recursive approach for message parsing --- .../parser/BeginState.java | 12 +-- .../messageinterpolation/parser/ELState.java | 10 --- .../parser/EscapedState.java | 9 -- .../parser/InterpolationTermState.java | 12 --- .../parser/MessageState.java | 11 --- .../parser/ParserState.java | 2 - .../parser/TokenCollector.java | 16 ++-- .../validator/bugs/TooBigMessageTest.java | 90 +++++++++++++++++++ .../TokenIteratorTest.java | 8 +- 9 files changed, 103 insertions(+), 67 deletions(-) create mode 100644 engine/src/test/java/org/hibernate/validator/bugs/TooBigMessageTest.java diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/parser/BeginState.java b/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/parser/BeginState.java index 678f16e460..5aee73b9f3 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/parser/BeginState.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/parser/BeginState.java @@ -18,11 +18,7 @@ public class BeginState implements ParserState { @Override public void terminate(TokenCollector tokenCollector) throws MessageDescriptorFormatException { - } - - @Override - public void start(TokenCollector tokenCollector) throws MessageDescriptorFormatException { - tokenCollector.next(); + tokenCollector.terminateToken(); } @Override @@ -30,7 +26,6 @@ public void handleNonMetaCharacter(char character, TokenCollector tokenCollector throws MessageDescriptorFormatException { tokenCollector.appendToToken( character ); tokenCollector.transitionState( new MessageState() ); - tokenCollector.next(); } @Override @@ -43,7 +38,6 @@ public void handleBeginTerm(char character, TokenCollector tokenCollector) throw tokenCollector.makeParameterToken(); } tokenCollector.transitionState( new InterpolationTermState() ); - tokenCollector.next(); } @Override @@ -56,7 +50,6 @@ public void handleEscapeCharacter(char character, TokenCollector tokenCollector) throws MessageDescriptorFormatException { tokenCollector.appendToToken( character ); tokenCollector.transitionState( new EscapedState( this ) ); - tokenCollector.next(); } @Override @@ -68,9 +61,6 @@ public void handleELDesignator(char character, TokenCollector tokenCollector) else { ParserState state = new ELState(); tokenCollector.transitionState( state ); - tokenCollector.next(); } } } - - diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/parser/ELState.java b/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/parser/ELState.java index ce7df402f4..569ea1e2e8 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/parser/ELState.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/parser/ELState.java @@ -15,11 +15,6 @@ public class ELState implements ParserState { private static final Log log = LoggerFactory.make(); - @Override - public void start(TokenCollector tokenCollector) { - throw new IllegalStateException( "Parsing of message descriptor cannot start in this state" ); - } - @Override public void terminate(TokenCollector tokenCollector) throws MessageDescriptorFormatException { tokenCollector.appendToToken( TokenCollector.EL_DESIGNATOR ); @@ -33,7 +28,6 @@ public void handleNonMetaCharacter(char character, TokenCollector tokenCollector tokenCollector.appendToToken( character ); tokenCollector.terminateToken(); tokenCollector.transitionState( new BeginState() ); - tokenCollector.next(); } @Override @@ -44,7 +38,6 @@ public void handleBeginTerm(char character, TokenCollector tokenCollector) throw tokenCollector.appendToToken( character ); tokenCollector.makeELToken(); tokenCollector.transitionState( new InterpolationTermState() ); - tokenCollector.next(); } @Override @@ -59,7 +52,6 @@ public void handleEndTerm(char character, TokenCollector tokenCollector) throws public void handleEscapeCharacter(char character, TokenCollector tokenCollector) throws MessageDescriptorFormatException { tokenCollector.transitionState( new EscapedState( this ) ); - tokenCollector.next(); } @Override @@ -68,5 +60,3 @@ public void handleELDesignator(char character, TokenCollector tokenCollector) handleNonMetaCharacter( character, tokenCollector ); } } - - diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/parser/EscapedState.java b/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/parser/EscapedState.java index 901acff4fd..f44242dd12 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/parser/EscapedState.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/parser/EscapedState.java @@ -16,11 +16,6 @@ public EscapedState(ParserState previousState) { this.previousState = previousState; } - @Override - public void start(TokenCollector tokenCollector) { - throw new IllegalStateException( "Parsing of message descriptor cannot start in this state" ); - } - @Override public void terminate(TokenCollector tokenCollector) throws MessageDescriptorFormatException { tokenCollector.terminateToken(); @@ -58,9 +53,5 @@ private void handleEscapedCharacter(char character, TokenCollector tokenCollecto throws MessageDescriptorFormatException { tokenCollector.appendToToken( character ); tokenCollector.transitionState( previousState ); - tokenCollector.next(); } } - - - diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/parser/InterpolationTermState.java b/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/parser/InterpolationTermState.java index f921113f9f..11c974373a 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/parser/InterpolationTermState.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/parser/InterpolationTermState.java @@ -15,11 +15,6 @@ public class InterpolationTermState implements ParserState { private static final Log log = LoggerFactory.make(); - @Override - public void start(TokenCollector tokenCollector) { - throw new IllegalStateException( "Parsing of message descriptor cannot start in this state" ); - } - @Override public void terminate(TokenCollector tokenCollector) throws MessageDescriptorFormatException { throw log.getNonTerminatedParameterException( @@ -32,7 +27,6 @@ public void terminate(TokenCollector tokenCollector) throws MessageDescriptorFor public void handleNonMetaCharacter(char character, TokenCollector tokenCollector) throws MessageDescriptorFormatException { tokenCollector.appendToToken( character ); - tokenCollector.next(); } @Override @@ -46,7 +40,6 @@ public void handleEndTerm(char character, TokenCollector tokenCollector) throws tokenCollector.terminateToken(); BeginState beginState = new BeginState(); tokenCollector.transitionState( beginState ); - tokenCollector.next(); } @Override @@ -55,16 +48,11 @@ public void handleEscapeCharacter(char character, TokenCollector tokenCollector) tokenCollector.appendToToken( character ); ParserState state = new EscapedState( this ); tokenCollector.transitionState( state ); - tokenCollector.next(); - } @Override public void handleELDesignator(char character, TokenCollector tokenCollector) throws MessageDescriptorFormatException { tokenCollector.appendToToken( character ); - tokenCollector.next(); } } - - diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/parser/MessageState.java b/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/parser/MessageState.java index bac9c7e46c..37cd23503c 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/parser/MessageState.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/parser/MessageState.java @@ -16,11 +16,6 @@ public class MessageState implements ParserState { private static final Log log = LoggerFactory.make(); - @Override - public void start(TokenCollector tokenCollector) { - throw new IllegalStateException( "The parsing of the message descriptor cannot start in this state." ); - } - @Override public void terminate(TokenCollector tokenCollector) throws MessageDescriptorFormatException { tokenCollector.terminateToken(); @@ -30,7 +25,6 @@ public void terminate(TokenCollector tokenCollector) throws MessageDescriptorFor public void handleNonMetaCharacter(char character, TokenCollector tokenCollector) throws MessageDescriptorFormatException { tokenCollector.appendToToken( character ); - tokenCollector.next(); } @Override @@ -42,7 +36,6 @@ public void handleBeginTerm(char character, TokenCollector tokenCollector) throw tokenCollector.makeParameterToken(); } tokenCollector.transitionState( new InterpolationTermState() ); - tokenCollector.next(); } @Override @@ -59,7 +52,6 @@ public void handleEscapeCharacter(char character, TokenCollector tokenCollector) tokenCollector.appendToToken( character ); tokenCollector.transitionState( new EscapedState( this ) ); - tokenCollector.next(); } @Override @@ -70,9 +62,6 @@ public void handleELDesignator(char character, TokenCollector tokenCollector) } else { tokenCollector.transitionState( new ELState() ); - tokenCollector.next(); } } } - - diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/parser/ParserState.java b/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/parser/ParserState.java index a48a48f2bc..64317de46d 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/parser/ParserState.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/parser/ParserState.java @@ -13,7 +13,6 @@ * @author Hardy Ferentschik */ public interface ParserState { - void start(TokenCollector tokenCollector) throws MessageDescriptorFormatException; void terminate(TokenCollector tokenCollector) throws MessageDescriptorFormatException; @@ -27,4 +26,3 @@ public interface ParserState { void handleELDesignator(char character, TokenCollector tokenCollector) throws MessageDescriptorFormatException; } - diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/parser/TokenCollector.java b/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/parser/TokenCollector.java index 1443eee7f5..ffce7bb68e 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/parser/TokenCollector.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/parser/TokenCollector.java @@ -6,13 +6,13 @@ */ package org.hibernate.validator.internal.engine.messageinterpolation.parser; +import static org.hibernate.validator.internal.util.CollectionHelper.newArrayList; + import java.util.Collections; import java.util.List; import org.hibernate.validator.internal.engine.messageinterpolation.InterpolationTermType; -import static org.hibernate.validator.internal.util.CollectionHelper.newArrayList; - /** * Used to creates a list of tokens from a message descriptor. * @@ -28,7 +28,7 @@ public class TokenCollector { private final String originalMessageDescriptor; private final InterpolationTermType interpolationTermType; - private List tokenList; + private final List tokenList; private ParserState currentParserState; private int currentPosition; private Token currentToken; @@ -69,10 +69,11 @@ public void makeELToken() { currentToken.makeELToken(); } - public void next() throws MessageDescriptorFormatException { + private void next() throws MessageDescriptorFormatException { if ( currentPosition == originalMessageDescriptor.length() ) { // give the current context the chance to complete currentParserState.terminate( this ); + currentPosition++; return; } char currentCharacter = originalMessageDescriptor.charAt( currentPosition ); @@ -98,12 +99,12 @@ public void next() throws MessageDescriptorFormatException { currentParserState.handleNonMetaCharacter( currentCharacter, this ); } } - // make sure the last token is terminated - terminateToken(); } public final void parse() throws MessageDescriptorFormatException { - currentParserState.start( this ); + while ( currentPosition <= originalMessageDescriptor.length() ) { + next(); + } } public void transitionState(ParserState newState) { @@ -122,4 +123,3 @@ public String getOriginalMessageDescriptor() { return originalMessageDescriptor; } } - diff --git a/engine/src/test/java/org/hibernate/validator/bugs/TooBigMessageTest.java b/engine/src/test/java/org/hibernate/validator/bugs/TooBigMessageTest.java new file mode 100644 index 0000000000..4eb8ffc18e --- /dev/null +++ b/engine/src/test/java/org/hibernate/validator/bugs/TooBigMessageTest.java @@ -0,0 +1,90 @@ +/* + * Hibernate Validator, declare and validate application constraints + * + * License: Apache License, Version 2.0 + * See the license.txt file in the root directory or . + */ +package org.hibernate.validator.bugs; + +import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertCorrectConstraintViolationMessages; +import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertNumberOfViolations; + +import java.util.Set; + +import javax.validation.ConstraintViolation; +import javax.validation.Validator; +import javax.validation.constraints.NotNull; + +import org.hibernate.validator.testutil.TestForIssue; +import org.hibernate.validator.testutils.ValidatorUtil; +import org.junit.Test; + +/** + * Ensure large error messages can be interpolated. + * + * @author Gunnar Morling + */ +public class TooBigMessageTest { + + /** + * Large enough to trigger a stack overflow with the recursive scheme, assuming default settings + */ + private static final String LARGE_MESSAGE = + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890123456789012345678901234567890"; + + @Test + @TestForIssue(jiraKey = "HV-1091") + public void largeMessageCanBeInterpolated() { + Validator validator = ValidatorUtil.getValidator(); + GoldFish fish = new GoldFish(); + + Set> constraintViolations = validator.validate( fish ); + assertNumberOfViolations( constraintViolations, 1 ); + assertCorrectConstraintViolationMessages( constraintViolations, LARGE_MESSAGE ); + } + + private static class GoldFish { + + @NotNull(message = LARGE_MESSAGE) + String name; + } +} diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/TokenIteratorTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/TokenIteratorTest.java index a63e1996aa..281f3bccff 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/TokenIteratorTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/TokenIteratorTest.java @@ -6,15 +6,15 @@ */ package org.hibernate.validator.test.internal.engine.messageinterpolation; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + import org.hibernate.validator.internal.engine.messageinterpolation.InterpolationTermType; import org.hibernate.validator.internal.engine.messageinterpolation.parser.TokenCollector; import org.hibernate.validator.internal.engine.messageinterpolation.parser.TokenIterator; import org.testng.annotations.Test; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertTrue; - /** * Tests for {@code TokenIterator}. * From 9d6404bae20c284d9e1014e954806981b35b86b9 Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Thu, 1 Sep 2016 11:27:37 +0200 Subject: [PATCH 012/124] HV-1031 Creating copy of PathImpl during marking processed paths --- ...ContainedSeveralTimesInCollectionTest.java | 120 ++++++++++++++++++ .../internal/engine/ValidationContext.java | 14 +- 2 files changed, 129 insertions(+), 5 deletions(-) create mode 100644 engine-jdk8-tests/src/test/java/org/hibernate/validator/test/internal/engine/typeannotationconstraint/SameElementContainedSeveralTimesInCollectionTest.java diff --git a/engine-jdk8-tests/src/test/java/org/hibernate/validator/test/internal/engine/typeannotationconstraint/SameElementContainedSeveralTimesInCollectionTest.java b/engine-jdk8-tests/src/test/java/org/hibernate/validator/test/internal/engine/typeannotationconstraint/SameElementContainedSeveralTimesInCollectionTest.java new file mode 100644 index 0000000000..27aa1227df --- /dev/null +++ b/engine-jdk8-tests/src/test/java/org/hibernate/validator/test/internal/engine/typeannotationconstraint/SameElementContainedSeveralTimesInCollectionTest.java @@ -0,0 +1,120 @@ +/* + * Hibernate Validator, declare and validate application constraints + * + * License: Apache License, Version 2.0 + * See the license.txt file in the root directory or . + */ +package org.hibernate.validator.test.internal.engine.typeannotationconstraint; + +import static java.lang.annotation.ElementType.ANNOTATION_TYPE; +import static java.lang.annotation.ElementType.CONSTRUCTOR; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.ElementType.TYPE_PARAMETER; +import static java.lang.annotation.ElementType.TYPE_USE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertCorrectPropertyPaths; +import static org.hibernate.validator.testutils.ValidatorUtil.getValidator; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.validation.Constraint; +import javax.validation.ConstraintViolation; +import javax.validation.OverridesAttribute; +import javax.validation.Payload; +import javax.validation.Valid; +import javax.validation.Validator; +import javax.validation.constraints.Size; + +import org.hibernate.validator.testutil.TestForIssue; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +/** + * @author Gunnar Morling + */ +@TestForIssue(jiraKey = "HV-1031") +public class SameElementContainedSeveralTimesInCollectionTest { + + private Validator validator; + + @BeforeClass + public void setup() { + validator = getValidator(); + } + + @Test + public void sameInvalidInstanceInListShouldBeReportedWithAllPaths() { + ListContainer listContainer = new ListContainer( Arrays.asList( "", "A", "" ) ); + + Set> constraintViolations = validator.validate( listContainer ); + + assertCorrectPropertyPaths( constraintViolations, "values[0]", "values[2]" ); + } + + @Test + public void sameInvalidInstanceInMapShouldBeReportedWithAllPaths() { + List emptyList = Collections.emptyList(); + List nonEmptyList = Arrays.asList( "A" ); + + HashMap> values = new HashMap<>(); + values.put( "NON_EMPTY", nonEmptyList ); + values.put( "EMPTY_1", emptyList ); + values.put( "EMPTY_2", emptyList ); + MapContainer withMap = new MapContainer( values ); + + Set> constraintViolations = validator.validate( withMap ); + + assertCorrectPropertyPaths( constraintViolations, "values[EMPTY_1]", "values[EMPTY_2]" ); + } + + private static class ListContainer { + + @Valid + public List<@SizeWithTypeUse(min = 1) String> values; + + public ListContainer(List values) { + this.values = values; + } + } + + private static class MapContainer { + + @Valid + public Map> values; + + public MapContainer(Map> values) { + this.values = values; + } + } + + // TODO Remove once the original one supports TYPE_USE + @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_PARAMETER, TYPE_USE }) + @Retention(RUNTIME) + @Documented + @Constraint(validatedBy = {}) + @Size + public @interface SizeWithTypeUse { + + String message() default "{javax.validation.constraints.Size.message}"; + + Class[] groups() default {}; + + Class[] payload() default {}; + + @OverridesAttribute(constraint = Size.class, name = "min") + int min() default 0; + + @OverridesAttribute(constraint = Size.class, name = "max") + int max() default Integer.MAX_VALUE; + } +} diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidationContext.java b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidationContext.java index ba1d45efc7..28455f6a65 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidationContext.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidationContext.java @@ -6,6 +6,9 @@ */ package org.hibernate.validator.internal.engine; +import static org.hibernate.validator.internal.util.CollectionHelper.newHashMap; +import static org.hibernate.validator.internal.util.CollectionHelper.newHashSet; + import java.lang.annotation.ElementType; import java.lang.reflect.Constructor; import java.lang.reflect.Method; @@ -17,6 +20,7 @@ import java.util.List; import java.util.Map; import java.util.Set; + import javax.validation.ConstraintValidatorFactory; import javax.validation.ConstraintViolation; import javax.validation.MessageInterpolator; @@ -26,9 +30,6 @@ import javax.validation.ValidationException; import javax.validation.metadata.ConstraintDescriptor; -import com.fasterxml.classmate.ResolvedType; -import com.fasterxml.classmate.TypeResolver; - import org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorContextImpl; import org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManager; import org.hibernate.validator.internal.engine.constraintvalidation.ConstraintViolationCreationContext; @@ -43,8 +44,8 @@ import org.hibernate.validator.spi.time.TimeProvider; import org.hibernate.validator.spi.valuehandling.ValidatedValueUnwrapper; -import static org.hibernate.validator.internal.util.CollectionHelper.newHashMap; -import static org.hibernate.validator.internal.util.CollectionHelper.newHashSet; +import com.fasterxml.classmate.ResolvedType; +import com.fasterxml.classmate.TypeResolver; /** * Context object keeping track of all required data for a validation call. @@ -472,6 +473,9 @@ private boolean isAlreadyValidatedForCurrentGroup(Object value, Class group) } private void markCurrentBeanAsProcessedForCurrentPath(Object value, PathImpl path) { + // HV-1031 The path object is mutated as we traverse the object tree, hence copy it before saving it + path = PathImpl.createCopy( path ); + if ( processedPathsPerBean.containsKey( value ) ) { processedPathsPerBean.get( value ).add( path ); } From 1c3dd2aa41e5a201c698f795da2cc19b0e9ba4b2 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Wed, 31 Aug 2016 16:25:59 +0200 Subject: [PATCH 013/124] HV-1065 Add hibernate.validator.constraint_mapping_contributors option The current hibernate.validator.constraint_mapping_contributor option does not accept a comma separated list of contributors which is not in line with the other options. Deprecate hibernate.validator.constraint_mapping_contributor. Will be removed in 6. --- documentation/src/main/asciidoc/ch11.asciidoc | 5 +- .../HibernateValidatorConfiguration.java | 13 +++- .../internal/engine/ValidatorFactoryImpl.java | 71 ++++++++++++++----- .../validator/internal/util/StringHelper.java | 11 +++ ...tributorConfiguredInValidationXmlTest.java | 22 +++++- .../hibernate/validator/test/cfg/Judge.java | 35 +++++++++ ...straint-mapping-contributor-validation.xml | 3 +- ...straint-mapping-contributor-validation.xml | 2 +- 8 files changed, 137 insertions(+), 25 deletions(-) create mode 100644 engine/src/test/java/org/hibernate/validator/test/cfg/Judge.java diff --git a/documentation/src/main/asciidoc/ch11.asciidoc b/documentation/src/main/asciidoc/ch11.asciidoc index 2b7724b243..15c38c3365 100644 --- a/documentation/src/main/asciidoc/ch11.asciidoc +++ b/documentation/src/main/asciidoc/ch11.asciidoc @@ -292,7 +292,7 @@ include::{sourcedir}/org/hibernate/validator/referenceguide/chapter11/constraint If you are not bootstrapping a validator factory manually but work with the default factory as configured via _META-INF/validation.xml_ (see <>), -you can add one or more constraint mappings by creating a constraint mapping contributor. +you can add one or more constraint mappings by creating one or several constraint mapping contributors. To do so, implement the `ConstraintMappingContributor` contract: [[example-constraint-mapping-contributor]] @@ -305,7 +305,8 @@ include::{sourcedir}/org/hibernate/validator/referenceguide/chapter11/constraint ==== You then need to specify the fully-qualified class name of the contributor implementation in _META-INF/validation.xml_, -using the property key `hibernate.validator.constraint_mapping_contributor`. +using the property key `hibernate.validator.constraint_mapping_contributors`. You can specify several +contributors by separating them with a comma. [[section-advanced-constraint-composition]] === Advanced constraint composition features diff --git a/engine/src/main/java/org/hibernate/validator/HibernateValidatorConfiguration.java b/engine/src/main/java/org/hibernate/validator/HibernateValidatorConfiguration.java index cee35114ed..212424c533 100644 --- a/engine/src/main/java/org/hibernate/validator/HibernateValidatorConfiguration.java +++ b/engine/src/main/java/org/hibernate/validator/HibernateValidatorConfiguration.java @@ -62,11 +62,22 @@ public interface HibernateValidatorConfiguration extends Configuration getConstraintMappings(Configuration serviceLoaderBasedContributor.createConstraintMappings( builder ); } - // XML-defined constraint mapping contributor - String constraintMappingContributorClassName = configurationState.getProperties() - .get( HibernateValidatorConfiguration.CONSTRAINT_MAPPING_CONTRIBUTOR ); + // XML-defined constraint mapping contributors + List contributors = getPropertyConfiguredConstraintMappingContributors( configurationState.getProperties(), + externalClassLoader ); - if ( constraintMappingContributorClassName != null ) { - @SuppressWarnings("unchecked") - Class contributorType = (Class) run( - LoadClass - .action( constraintMappingContributorClassName, externalClassLoader ) - ); - - ConstraintMappingContributor contributor = run( - NewInstance.action( - contributorType, - "constraint mapping contributor class" - ) - ); + for ( ConstraintMappingContributor contributor : contributors ) { DefaultConstraintMappingBuilder builder = new DefaultConstraintMappingBuilder( constraintMappings ); contributor.createConstraintMappings( builder ); } @@ -484,6 +473,50 @@ private static List> getPropertyConfiguredValidatedVa return handlers; } + /** + * Returns a list with {@link ConstraintMappingContributor}s configured via the + * {@link HibernateValidatorConfiguration#CONSTRAINT_MAPPING_CONTRIBUTORS} property. + * + * Also takes into account the deprecated {@link HibernateValidatorConfiguration#CONSTRAINT_MAPPING_CONTRIBUTOR} + * property. + * + * @param properties the properties used to bootstrap the factory + * + * @return a list with property-configured {@link ContraintMappingContributor}s; May be empty but never {@code null} + */ + private static List getPropertyConfiguredConstraintMappingContributors( + Map properties, ClassLoader externalClassLoader) { + String deprecatedPropertyValue = properties.get( HibernateValidatorConfiguration.CONSTRAINT_MAPPING_CONTRIBUTOR ); + String propertyValue = properties.get( HibernateValidatorConfiguration.CONSTRAINT_MAPPING_CONTRIBUTORS ); + + if ( StringHelper.isNullOrEmptyString( deprecatedPropertyValue ) && StringHelper.isNullOrEmptyString( propertyValue ) ) { + return Collections.emptyList(); + } + + StringBuilder assembledPropertyValue = new StringBuilder(); + if ( !StringHelper.isNullOrEmptyString( deprecatedPropertyValue ) ) { + assembledPropertyValue.append( deprecatedPropertyValue ); + } + if ( !StringHelper.isNullOrEmptyString( propertyValue ) ) { + if ( assembledPropertyValue.length() > 0 ) { + assembledPropertyValue.append( "," ); + } + assembledPropertyValue.append( propertyValue ); + } + + String[] contributorNames = assembledPropertyValue.toString().split( "," ); + List contributors = newArrayList( contributorNames.length ); + + for ( String contributorName : contributorNames ) { + @SuppressWarnings("unchecked") + Class contributorType = (Class) run( + LoadClass.action( contributorName, externalClassLoader ) ); + contributors.add( run( NewInstance.action( contributorType, "constraint mapping contributor class" ) ) ); + } + + return contributors; + } + private static void registerCustomConstraintValidators(Set constraintMappings, ConstraintHelper constraintHelper) { Set> definedConstraints = newHashSet(); diff --git a/engine/src/main/java/org/hibernate/validator/internal/util/StringHelper.java b/engine/src/main/java/org/hibernate/validator/internal/util/StringHelper.java index b0dc70fd49..618252b5c1 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/util/StringHelper.java +++ b/engine/src/main/java/org/hibernate/validator/internal/util/StringHelper.java @@ -85,9 +85,20 @@ public static String decapitalize(String string) { } } + /** + * Indicates if the string is null or is empty ie only contains whitespaces. + * + * @param value the string considered + * @return true if the string is null or only contains whitespaces + */ + public static boolean isNullOrEmptyString(String value) { + return value == null || value.trim().isEmpty(); + } + private static boolean startsWithSeveralUpperCaseLetters(String string) { return string.length() > 1 && Character.isUpperCase( string.charAt( 0 ) ) && Character.isUpperCase( string.charAt( 1 ) ); } + } diff --git a/engine/src/test/java/org/hibernate/validator/test/cfg/ConstraintMappingContributorConfiguredInValidationXmlTest.java b/engine/src/test/java/org/hibernate/validator/test/cfg/ConstraintMappingContributorConfiguredInValidationXmlTest.java index 497485d1af..4e047b644a 100644 --- a/engine/src/test/java/org/hibernate/validator/test/cfg/ConstraintMappingContributorConfiguredInValidationXmlTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/cfg/ConstraintMappingContributorConfiguredInValidationXmlTest.java @@ -48,6 +48,9 @@ public void run() { violations = validator.validate( new Runner() ); assertCorrectConstraintTypes( violations, AssertTrue.class ); + + violations = validator.validate( new Judge() ); + assertCorrectConstraintTypes( violations, Min.class ); } } ); @@ -58,7 +61,7 @@ private void runWithCustomValidationXml(String validationXmlName, Runnable runna runWithCustomValidationXml( validationXmlName, runnable ); } - public static class MyConstraintMappingContributor implements ConstraintMappingContributor { + public static class MyConstraintMappingContributor1 implements ConstraintMappingContributor { @Override public void createConstraintMappings(ConstraintMappingBuilder builder) { @@ -68,11 +71,28 @@ public void createConstraintMappings(ConstraintMappingBuilder builder) { .constraint( new NotNullDef() ) .property( "numberOfHelpers", FIELD ) .constraint( new MinDef().value( 1 ) ); + } + } + + public static class MyConstraintMappingContributor2 implements ConstraintMappingContributor { + @Override + public void createConstraintMappings(ConstraintMappingBuilder builder) { builder.addConstraintMapping() .type( Runner.class ) .property( "paidEntryFee", FIELD ) .constraint( new AssertTrueDef() ); } } + + public static class MyConstraintMappingContributor3 implements ConstraintMappingContributor { + + @Override + public void createConstraintMappings(ConstraintMappingBuilder builder) { + builder.addConstraintMapping() + .type( Judge.class ) + .property( "age", FIELD ) + .constraint( new MinDef().value( 18 ) ); + } + } } diff --git a/engine/src/test/java/org/hibernate/validator/test/cfg/Judge.java b/engine/src/test/java/org/hibernate/validator/test/cfg/Judge.java new file mode 100644 index 0000000000..07cf968e60 --- /dev/null +++ b/engine/src/test/java/org/hibernate/validator/test/cfg/Judge.java @@ -0,0 +1,35 @@ +/* + * Hibernate Validator, declare and validate application constraints + * + * License: Apache License, Version 2.0 + * See the license.txt file in the root directory or . + */ +package org.hibernate.validator.test.cfg; + +/** + * @author Guillaume Smet + */ +public class Judge { + + private String name; + + + private int age; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + +} diff --git a/engine/src/test/resources/org/hibernate/validator/test/cfg/constraint-mapping-contributor-validation.xml b/engine/src/test/resources/org/hibernate/validator/test/cfg/constraint-mapping-contributor-validation.xml index 9d2c194d5b..aac91cdbca 100644 --- a/engine/src/test/resources/org/hibernate/validator/test/cfg/constraint-mapping-contributor-validation.xml +++ b/engine/src/test/resources/org/hibernate/validator/test/cfg/constraint-mapping-contributor-validation.xml @@ -11,5 +11,6 @@ xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/configuration validation-configuration-1.1.xsd" version="1.1"> - org.hibernate.validator.test.cfg.ConstraintMappingContributorConfiguredInValidationXmlTest$MyConstraintMappingContributor + org.hibernate.validator.test.cfg.ConstraintMappingContributorConfiguredInValidationXmlTest$MyConstraintMappingContributor1,org.hibernate.validator.test.cfg.ConstraintMappingContributorConfiguredInValidationXmlTest$MyConstraintMappingContributor2 + org.hibernate.validator.test.cfg.ConstraintMappingContributorConfiguredInValidationXmlTest$MyConstraintMappingContributor3 diff --git a/integration/src/test/resources/constraint-mapping-contributor-validation.xml b/integration/src/test/resources/constraint-mapping-contributor-validation.xml index a610550f5f..45db0ec98a 100644 --- a/integration/src/test/resources/constraint-mapping-contributor-validation.xml +++ b/integration/src/test/resources/constraint-mapping-contributor-validation.xml @@ -11,5 +11,5 @@ xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/configuration validation-configuration-1.1.xsd" version="1.1"> - org.hibernate.validator.integration.wildfly.MyConstraintMappingContributor + org.hibernate.validator.integration.wildfly.MyConstraintMappingContributor From 1adf38f836fba78d107b6f6aeec3d0624fd04cd0 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Thu, 25 Aug 2016 18:16:13 +0200 Subject: [PATCH 014/124] HV-1046 Fix a formatting issue and an invalid include in the doc Interestingly, the Docbook conversion fixed the formatting issue in the example while the AsciiDoc output was all wrong. --- documentation/src/main/asciidoc/ch11.asciidoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/src/main/asciidoc/ch11.asciidoc b/documentation/src/main/asciidoc/ch11.asciidoc index 15c38c3365..4d817d029e 100644 --- a/documentation/src/main/asciidoc/ch11.asciidoc +++ b/documentation/src/main/asciidoc/ch11.asciidoc @@ -425,7 +425,7 @@ unwrapped to `HibernateConstraintViolation` in order to retrieve the dynamic pay ==== [source, JAVA, indent=0] ---- -include::{sourcedir}/org/hibernate/validator/referenceguide/chapter11/dynamicpayload/DynamicPayloadTest.java[tags=include] +include::{sourcedir}/org/hibernate/validator/referenceguide/chapter11/dynamicpayload/DynamicPayLoadTest.java[tags=include] ---- ==== @@ -811,7 +811,7 @@ definitions. You can use the programmatic constraint declaration API - see [[example-using-constraint-definition-api]] .Adding constraint definitions through the programmatic API -======== +==== [source, JAVA, indent=0] ---- include::{sourcedir}/org/hibernate/validator/referenceguide/chapter11/constraintapi/ConstraintApiTest.java[tags=constraintDefinition] From 1c5c3db0784b68ca3cb69629746dd4a8e7c3ac1e Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Fri, 2 Sep 2016 10:55:57 +0200 Subject: [PATCH 015/124] HV-1096 Adding Russian translations file --- copyright.txt | 1 + .../ValidationMessages_ru.properties | 29 +++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 engine/src/main/resources/org/hibernate/validator/ValidationMessages_ru.properties diff --git a/copyright.txt b/copyright.txt index cacd84f5e0..1666fa3cdd 100644 --- a/copyright.txt +++ b/copyright.txt @@ -1,5 +1,6 @@ Adam Stawicki Alaa Nassef +Andrey Derevyanko Andrey Rodionov Benson Margulies Brent Douglas diff --git a/engine/src/main/resources/org/hibernate/validator/ValidationMessages_ru.properties b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_ru.properties new file mode 100644 index 0000000000..92c1fbead3 --- /dev/null +++ b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_ru.properties @@ -0,0 +1,29 @@ + +javax.validation.constraints.AssertFalse.message = \u0434\u043E\u043B\u0436\u043D\u043E \u0431\u044B\u0442\u044C \u043B\u043E\u0436\u043D\u044B\u043C +javax.validation.constraints.AssertTrue.message = \u0434\u043E\u043B\u0436\u043D\u043E \u0431\u044B\u0442\u044C \u0438\u0441\u0442\u0438\u043D\u043D\u044B\u043C +javax.validation.constraints.DecimalMax.message = \u0434\u043E\u043B\u0436\u043D\u043E \u0431\u044B\u0442\u044C \u043C\u0435\u043D\u044C\u0448\u0435 \u0447\u0435\u043C ${inclusive == true ? '\u0438\u043B\u0438 \u0440\u0430\u0432\u043D\u043E ' : ''}{value} +javax.validation.constraints.DecimalMin.message = \u0434\u043E\u043B\u0436\u043D\u043E \u0431\u044B\u0442\u044C \u0431\u043E\u043B\u044C\u0448\u0435 \u0447\u0435\u043C ${inclusive == true ? '\u0438\u043B\u0438 \u0440\u0430\u0432\u043D\u043E ' : ''}{value} +javax.validation.constraints.Future.message = \u0434\u043E\u043B\u0436\u043D\u043E \u0431\u044B\u0442\u044C \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043C +javax.validation.constraints.Max.message = \u0434\u043E\u043B\u0436\u043D\u043E \u0431\u044B\u0442\u044C \u043C\u0435\u043D\u044C\u0448\u0435 \u0438\u043B\u0438 \u0440\u0430\u0432\u043D\u043E {value} +javax.validation.constraints.Min.message = \u0434\u043E\u043B\u0436\u043D\u043E \u0431\u044B\u0442\u044C \u0431\u043E\u043B\u044C\u0448\u0435 \u0438\u043B\u0438 \u0440\u0430\u0432\u043D\u043E {value} +javax.validation.constraints.NotNull.message = \u0434\u043E\u043B\u0436\u043D\u043E \u0431\u044B\u0442\u044C \u0437\u0430\u0434\u0430\u043D\u043E +javax.validation.constraints.Null.message = \u0434\u043E\u043B\u0436\u043D\u043E \u0431\u044B\u0442\u044C \u043D\u0435\u0437\u0430\u0434\u0430\u043D\u043E +javax.validation.constraints.Past.message = \u0434\u043E\u043B\u0436\u043D\u043E \u0431\u044B\u0442\u044C \u0432 \u043F\u0440\u043E\u0448\u043B\u043E\u043C +javax.validation.constraints.Pattern.message = \u0434\u043E\u043B\u0436\u043D\u043E \u0441\u043E\u043E\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u043E\u0432\u0430\u0442\u044C \u0448\u0430\u0431\u043B\u043E\u043D\u0443 "{regexp}" +javax.validation.constraints.Size.message = \u0440\u0430\u0437\u043C\u0435\u0440 \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u043C\u0435\u0436\u0434\u0443 {min} \u0438 {max} + +org.hibernate.validator.constraints.CreditCardNumber.message = \u043D\u0435\u0432\u0435\u0440\u043D\u044B\u0439 \u043D\u043E\u043C\u0435\u0440 \u043A\u0440\u0435\u0434\u0438\u0442\u043D\u043E\u0439 \u043A\u0430\u0440\u0442\u044B +org.hibernate.validator.constraints.EAN.message = \u043D\u0435\u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u044B\u0439 \u0448\u0442\u0440\u0438\u0445\u043A\u043E\u0434 {type} +org.hibernate.validator.constraints.Email.message = email \u043E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D \u0432 \u043D\u0435\u0432\u0435\u0440\u043D\u043E\u043C \u0444\u043E\u0440\u043C\u0430\u0442\u0435 +org.hibernate.validator.constraints.Length.message = \u0434\u043B\u0438\u043D\u0430 \u0434\u043E\u043B\u0436\u043D\u0430 \u0431\u044B\u0442\u044C \u043C\u0435\u0436\u0434\u0443 {min} \u0438 {max} +org.hibernate.validator.constraints.LuhnCheck.message = \u041A\u043E\u043D\u0442\u0440\u043E\u043B\u044C\u043D\u0430\u044F \u0446\u0438\u0444\u0440\u0430 \u0434\u043B\u044F ${validatedValue} \u043D\u0435\u0432\u0435\u0440\u043D\u0430, \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 \u043F\u043E \u0430\u043B\u0433\u043E\u0440\u0438\u0442\u043C\u0443 \u041B\u0443\u043D\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043D\u0430 \u0441 \u043E\u0448\u0438\u0431\u043A\u043E\u0439 +org.hibernate.validator.constraints.Mod10Check.message = \u041A\u043E\u043D\u0442\u0440\u043E\u043B\u044C\u043D\u0430\u044F \u0446\u0438\u0444\u0440\u0430 \u0434\u043B\u044F ${validatedValue} \u043D\u0435\u0432\u0435\u0440\u043D\u0430, \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 \u043F\u043E \u0430\u043B\u0433\u043E\u0440\u0438\u0442\u043C\u0443 Mod10 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043D\u0430 \u0441 \u043E\u0448\u0438\u0431\u043A\u043E\u0439 +org.hibernate.validator.constraints.Mod11Check.message = \u041A\u043E\u043D\u0442\u0440\u043E\u043B\u044C\u043D\u0430\u044F \u0446\u0438\u0444\u0440\u0430 \u0434\u043B\u044F ${validatedValue} \u043D\u0435\u0432\u0435\u0440\u043D\u0430, \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 \u043F\u043E \u0430\u043B\u0433\u043E\u0440\u0438\u0442\u043C\u0443 Mod11 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043D\u0430 \u0441 \u043E\u0448\u0438\u0431\u043A\u043E\u0439 +org.hibernate.validator.constraints.ModCheck.message = \u041A\u043E\u043D\u0442\u0440\u043E\u043B\u044C\u043D\u0430\u044F \u0446\u0438\u0444\u0440\u0430 \u0434\u043B\u044F ${validatedValue} \u043D\u0435\u0432\u0435\u0440\u043D\u0430, \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 \u043F\u043E ${modType} \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043D\u0430 \u0441 \u043E\u0448\u0438\u0431\u043A\u043E\u0439 +org.hibernate.validator.constraints.NotBlank.message = \u043D\u0435 \u043C\u043E\u0436\u0435\u0442 \u0431\u044B\u0442\u044C \u043F\u0443\u0441\u0442\u043E +org.hibernate.validator.constraints.NotEmpty.message = \u043D\u0435 \u043C\u043E\u0436\u0435\u0442 \u0431\u044B\u0442\u044C \u043F\u0443\u0441\u0442\u043E +org.hibernate.validator.constraints.ParametersScriptAssert.message = \u0432\u044B\u0440\u0430\u0436\u0435\u043D\u0438\u0435 "{script}" \u043D\u0435 \u044F\u0432\u043B\u044F\u0435\u0442\u0441\u044F \u0438\u0441\u0442\u0438\u043D\u043D\u044B\u043C +org.hibernate.validator.constraints.Range.message = \u0434\u043E\u043B\u0436\u043D\u043E \u0431\u044B\u0442\u044C \u043C\u0435\u0436\u0434\u0443 {min} \u0438 {max} +org.hibernate.validator.constraints.SafeHtml.message = \u043C\u043E\u0436\u0435\u0442 \u0441\u043E\u0434\u0435\u0440\u0436\u0430\u0442\u044C \u043D\u0435\u0431\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u044B\u0439 html \u043A\u043E\u043D\u0442\u0435\u043D\u0442 +org.hibernate.validator.constraints.ScriptAssert.message = \u0432\u044B\u0440\u0430\u0436\u0435\u043D\u0438\u0435 "{script}" \u043D\u0435 \u044F\u0432\u043B\u044F\u0435\u0442\u0441\u044F \u0438\u0441\u0442\u0438\u043D\u043D\u044B\u043C +org.hibernate.validator.constraints.URL.message = \u0434\u043E\u043B\u0436\u043D\u043E \u0431\u044B\u0442\u044C \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043B\u044C\u043D\u044B\u043C URL From 01e9113be649978c8b67fa97f37feb5cf96c7585 Mon Sep 17 00:00:00 2001 From: Jenkins Date: Mon, 5 Sep 2016 12:00:47 +0000 Subject: [PATCH 016/124] [Jenkins release job] README.md updated by release build 5.3.0.CR1 --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5e890e667a..5d82c5c5f1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Hibernate Validator -*Version: 5.3.0.Alpha1, 15.01.2016* +*Version: 5.3.0.CR1 - 05-09-2016* ## What is it? @@ -35,7 +35,7 @@ Logging will delegate any log requests to that provider. org.hibernate hibernate-validator - 5.3.0.Alpha1 + 5.3.0.CR1 You also need an API and implementation of the Unified Expression Language. These dependencies must be explicitly added in an SE environment. @@ -59,7 +59,7 @@ extension by adding the following dependency: org.hibernate hibernate-validator-cdi - 5.3.0.Alpha1 + 5.3.0.CR1 * _hibernate-validator-annotation-processor-<version>.jar_ is an optional jar which can be integrated with your build From 83679ae37fa809b97da0f6741d1aace61d3cbad9 Mon Sep 17 00:00:00 2001 From: Jenkins Date: Mon, 5 Sep 2016 12:00:48 +0000 Subject: [PATCH 017/124] [Jenkins release job] changelog.txt updated by release build 5.3.0.CR1 --- changelog.txt | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/changelog.txt b/changelog.txt index 51b156dbfc..591f5713ae 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,6 +1,56 @@ Hibernate Validator Changelog ============================= +5.3.0.CR1 (05-09-2016) +------------------------- + +** Bug + * HV-1057 - engine - Group sequences don't honor inheritance relationships properly + * HV-1055 - engine - Default group sequence does not honour group hierarchy + * HV-1068 - engine - Wrong import in MessageDescriptorFormatException + * HV-1071 - engine - HV-1049 prevents annotations in the default package working + * HV-1049 - engine - Don't access annotations from "jdk.internal" package + * HV-1054 - engine - Catch correct exception type in AbstractMessageInterpolator + * HV-1072 - engine - Parameter validation does not stop when group in sequence has cascaded constraint violations. + * HV-1050 - build - Build fails under Windows + * HV-1063 - tests - Upgrade dependencies used by OSGi integration tests + * HV-1080 - engine - Validation of Java 8 Optional throws ClassCastException + * HV-1066 - validators - email domains with a 63 character length fails EmailValidator + * HV-1048 - engine - Correctly interpret version string returned by JDK 9 + * HV-1062 - validators - Use type annotations for map values with @NotNull annotation on the map + * HV-1013 - validators - Validator invokes hashCode() with null mandatory field + * HV-1046 - documentation - Fix example 11.4 in reference guide + * HV-1091 - engine - java.lang.StackOverflowError generated when using too big validation message + * HV-1031 - engine - Type parameter validations are not executed against all elements in a collection if elements contain the same object instance. + +** Improvement + * HV-1038 - build - Update to ClassMate 1.3.0 + * HV-1058 - engine - Avoid repeated retrieval of default group sequence in BeanMetadataImpl#getConstrainedPropertiesAsDescriptors() + * HV-1060 - engine - Include messages for @EAN and @ParameterScriptAssert in Brazilian Portuguese error messages + * HV-1076 - build - Improve Checkstyle configuration + * HV-1081 - build - Reuse the release scripts of OGM to automatize the release process + * HV-1077 - engine - Add missing @Override annotation + * HV-1074 - engine - Add Arabic translation + * HV-1015 - tests - Provide test case template + * HV-1082 - documentation - Upgrade maven-jdocbook-plugin and pressgang to generate valid HTML5 documentation + * HV-1078 - documentation - Update the CONTRIBUTING.md file + * HV-1075 - validators - Update and improve the French translation + * HV-1083 - build - Properly ignore hibernate-noorm-release-scripts directory in the build + * HV-1014 - documentation - Clarify what @ValidPart is in example 2.3 of the reference guide + * HV-1096 - validators - ValidationMessages for Russian + * HV-1086 - build - Update Maven dependencies and align with WildFly 10.1.0.Final + +** New Feature + * HV-1070 - build - Preparatory work for building with Java 9 + * HV-501 - engine - Extend programmatic API to allow alteration of ConstraintValidator list for a given constraint + * HV-1065 - engine - Add hibernate.validator.constraint_mapping_contributor*s* to take a list of contributors and deprecate hibernate.validator.constraint_mapping_contributor + +** Task + * HV-1053 - build - Use WildFly 10.0.0.Final for integration tests + * HV-1052 - build - Upgrade to current version of JBoss logging processor + * HV-1034 - build - Allow compilation using JDK9 + * HV-1064 - tests - Add Travis support + 5.3.0.Alpha1 (15.01.2016) ------------------------- From 8b291bee006a2f85eb57914ef7b35c4bd87db3b1 Mon Sep 17 00:00:00 2001 From: Jenkins Date: Mon, 5 Sep 2016 12:01:06 +0000 Subject: [PATCH 018/124] [Jenkins release job] Preparing release 5.3.0.CR1 --- annotation-processor/pom.xml | 2 +- build-config/pom.xml | 2 +- cdi/pom.xml | 2 +- distribution/pom.xml | 2 +- documentation/pom.xml | 2 +- engine-jdk8-tests/pom.xml | 2 +- engine/pom.xml | 2 +- integration/pom.xml | 2 +- osgi/integrationtest/pom.xml | 2 +- osgi/karaf-features/pom.xml | 2 +- osgi/pom.xml | 2 +- performance/pom.xml | 2 +- pom.xml | 2 +- tck-runner/pom.xml | 2 +- test-utils/pom.xml | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/annotation-processor/pom.xml b/annotation-processor/pom.xml index b57f4b76cf..6a4b0c4286 100644 --- a/annotation-processor/pom.xml +++ b/annotation-processor/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0-SNAPSHOT + 5.3.0.CR1 ../pom.xml diff --git a/build-config/pom.xml b/build-config/pom.xml index 3e89600681..30dd0bb6e3 100644 --- a/build-config/pom.xml +++ b/build-config/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0-SNAPSHOT + 5.3.0.CR1 ../pom.xml diff --git a/cdi/pom.xml b/cdi/pom.xml index d9c8c74b48..104def9baf 100644 --- a/cdi/pom.xml +++ b/cdi/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0-SNAPSHOT + 5.3.0.CR1 ../pom.xml diff --git a/distribution/pom.xml b/distribution/pom.xml index 16e2e2ec25..0ec4659da8 100644 --- a/distribution/pom.xml +++ b/distribution/pom.xml @@ -10,7 +10,7 @@ hibernate-validator-parent org.hibernate - 5.3.0-SNAPSHOT + 5.3.0.CR1 ../pom.xml diff --git a/documentation/pom.xml b/documentation/pom.xml index dec85332fc..a97e599bb7 100644 --- a/documentation/pom.xml +++ b/documentation/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0-SNAPSHOT + 5.3.0.CR1 ../pom.xml diff --git a/engine-jdk8-tests/pom.xml b/engine-jdk8-tests/pom.xml index a04dd88a2d..314de13141 100644 --- a/engine-jdk8-tests/pom.xml +++ b/engine-jdk8-tests/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.0-SNAPSHOT + 5.3.0.CR1 hibernate-validator-engine-jdk8-tests diff --git a/engine/pom.xml b/engine/pom.xml index b5bf8c1740..e453c96ed7 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0-SNAPSHOT + 5.3.0.CR1 ../pom.xml diff --git a/integration/pom.xml b/integration/pom.xml index 23eed0ee65..0e8196f504 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0-SNAPSHOT + 5.3.0.CR1 ../pom.xml diff --git a/osgi/integrationtest/pom.xml b/osgi/integrationtest/pom.xml index aeab64132e..dd23be1693 100644 --- a/osgi/integrationtest/pom.xml +++ b/osgi/integrationtest/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-osgi org.hibernate - 5.3.0-SNAPSHOT + 5.3.0.CR1 ../pom.xml diff --git a/osgi/karaf-features/pom.xml b/osgi/karaf-features/pom.xml index 0e7ca30c96..69c65fea48 100644 --- a/osgi/karaf-features/pom.xml +++ b/osgi/karaf-features/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-osgi org.hibernate - 5.3.0-SNAPSHOT + 5.3.0.CR1 ../pom.xml diff --git a/osgi/pom.xml b/osgi/pom.xml index 8f903a6d56..35b364d2e3 100644 --- a/osgi/pom.xml +++ b/osgi/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0-SNAPSHOT + 5.3.0.CR1 ../pom.xml diff --git a/performance/pom.xml b/performance/pom.xml index dd143f3b5d..de0ffb68f5 100644 --- a/performance/pom.xml +++ b/performance/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0-SNAPSHOT + 5.3.0.CR1 ../pom.xml diff --git a/pom.xml b/pom.xml index a48209280b..9b797ac84a 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.0-SNAPSHOT + 5.3.0.CR1 pom Hibernate Validator Aggregator diff --git a/tck-runner/pom.xml b/tck-runner/pom.xml index 71df1cefc6..16989b543f 100644 --- a/tck-runner/pom.xml +++ b/tck-runner/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0-SNAPSHOT + 5.3.0.CR1 ../pom.xml diff --git a/test-utils/pom.xml b/test-utils/pom.xml index 5953422ae9..0ce890c1f4 100644 --- a/test-utils/pom.xml +++ b/test-utils/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.0-SNAPSHOT + 5.3.0.CR1 hibernate-validator-test-utils From 3f57ec5a246be9dafafe61295e9d2a201634aeba Mon Sep 17 00:00:00 2001 From: Jenkins Date: Mon, 5 Sep 2016 12:06:37 +0000 Subject: [PATCH 019/124] [Jenkins release job] Preparing next development iteration --- annotation-processor/pom.xml | 2 +- build-config/pom.xml | 2 +- cdi/pom.xml | 2 +- distribution/pom.xml | 2 +- documentation/pom.xml | 2 +- engine-jdk8-tests/pom.xml | 2 +- engine/pom.xml | 2 +- integration/pom.xml | 2 +- osgi/integrationtest/pom.xml | 2 +- osgi/karaf-features/pom.xml | 2 +- osgi/pom.xml | 2 +- performance/pom.xml | 2 +- pom.xml | 2 +- tck-runner/pom.xml | 2 +- test-utils/pom.xml | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/annotation-processor/pom.xml b/annotation-processor/pom.xml index 6a4b0c4286..b57f4b76cf 100644 --- a/annotation-processor/pom.xml +++ b/annotation-processor/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0.CR1 + 5.3.0-SNAPSHOT ../pom.xml diff --git a/build-config/pom.xml b/build-config/pom.xml index 30dd0bb6e3..3e89600681 100644 --- a/build-config/pom.xml +++ b/build-config/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0.CR1 + 5.3.0-SNAPSHOT ../pom.xml diff --git a/cdi/pom.xml b/cdi/pom.xml index 104def9baf..d9c8c74b48 100644 --- a/cdi/pom.xml +++ b/cdi/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0.CR1 + 5.3.0-SNAPSHOT ../pom.xml diff --git a/distribution/pom.xml b/distribution/pom.xml index 0ec4659da8..16e2e2ec25 100644 --- a/distribution/pom.xml +++ b/distribution/pom.xml @@ -10,7 +10,7 @@ hibernate-validator-parent org.hibernate - 5.3.0.CR1 + 5.3.0-SNAPSHOT ../pom.xml diff --git a/documentation/pom.xml b/documentation/pom.xml index a97e599bb7..dec85332fc 100644 --- a/documentation/pom.xml +++ b/documentation/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0.CR1 + 5.3.0-SNAPSHOT ../pom.xml diff --git a/engine-jdk8-tests/pom.xml b/engine-jdk8-tests/pom.xml index 314de13141..a04dd88a2d 100644 --- a/engine-jdk8-tests/pom.xml +++ b/engine-jdk8-tests/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.0.CR1 + 5.3.0-SNAPSHOT hibernate-validator-engine-jdk8-tests diff --git a/engine/pom.xml b/engine/pom.xml index e453c96ed7..b5bf8c1740 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0.CR1 + 5.3.0-SNAPSHOT ../pom.xml diff --git a/integration/pom.xml b/integration/pom.xml index 0e8196f504..23eed0ee65 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0.CR1 + 5.3.0-SNAPSHOT ../pom.xml diff --git a/osgi/integrationtest/pom.xml b/osgi/integrationtest/pom.xml index dd23be1693..aeab64132e 100644 --- a/osgi/integrationtest/pom.xml +++ b/osgi/integrationtest/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-osgi org.hibernate - 5.3.0.CR1 + 5.3.0-SNAPSHOT ../pom.xml diff --git a/osgi/karaf-features/pom.xml b/osgi/karaf-features/pom.xml index 69c65fea48..0e7ca30c96 100644 --- a/osgi/karaf-features/pom.xml +++ b/osgi/karaf-features/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-osgi org.hibernate - 5.3.0.CR1 + 5.3.0-SNAPSHOT ../pom.xml diff --git a/osgi/pom.xml b/osgi/pom.xml index 35b364d2e3..8f903a6d56 100644 --- a/osgi/pom.xml +++ b/osgi/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0.CR1 + 5.3.0-SNAPSHOT ../pom.xml diff --git a/performance/pom.xml b/performance/pom.xml index de0ffb68f5..dd143f3b5d 100644 --- a/performance/pom.xml +++ b/performance/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0.CR1 + 5.3.0-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index 9b797ac84a..a48209280b 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.0.CR1 + 5.3.0-SNAPSHOT pom Hibernate Validator Aggregator diff --git a/tck-runner/pom.xml b/tck-runner/pom.xml index 16989b543f..71df1cefc6 100644 --- a/tck-runner/pom.xml +++ b/tck-runner/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0.CR1 + 5.3.0-SNAPSHOT ../pom.xml diff --git a/test-utils/pom.xml b/test-utils/pom.xml index 0ce890c1f4..5953422ae9 100644 --- a/test-utils/pom.xml +++ b/test-utils/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.0.CR1 + 5.3.0-SNAPSHOT hibernate-validator-test-utils From 9dda77fbebdaf7930907a21bb6097c4991c29c02 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Fri, 16 Sep 2016 17:13:05 +0200 Subject: [PATCH 020/124] HV-1101 Fix a few infelicities in the XML parsing of the mapping configuration --- .../validator/internal/util/logging/Log.java | 11 +-- .../internal/xml/MetaConstraintBuilder.java | 20 ++++-- .../test/internal/xml/MyConstraint.java | 41 +++++++++++ .../internal/xml/MyConstraintValidator.java | 22 ++++++ .../test/internal/xml/XmlParsingTest.java | 71 +++++++++++++++++++ .../xml/hv-1101-empty-element-mapping.xml | 16 +++++ .../internal/xml/hv-1101-tabs-mapping.xml | 11 +++ 7 files changed, 184 insertions(+), 8 deletions(-) create mode 100644 engine/src/test/java/org/hibernate/validator/test/internal/xml/MyConstraint.java create mode 100644 engine/src/test/java/org/hibernate/validator/test/internal/xml/MyConstraintValidator.java create mode 100644 engine/src/test/java/org/hibernate/validator/test/internal/xml/XmlParsingTest.java create mode 100644 engine/src/test/resources/org/hibernate/validator/test/internal/xml/hv-1101-empty-element-mapping.xml create mode 100644 engine/src/test/resources/org/hibernate/validator/test/internal/xml/hv-1101-tabs-mapping.xml diff --git a/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java b/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java index 880e570810..bbc0c1f98e 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java +++ b/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java @@ -5,6 +5,10 @@ * See the license.txt file in the root directory or . */ package org.hibernate.validator.internal.util.logging; +import static org.jboss.logging.Logger.Level.DEBUG; +import static org.jboss.logging.Logger.Level.INFO; +import static org.jboss.logging.Logger.Level.WARN; + import java.lang.annotation.ElementType; import java.lang.reflect.Member; import java.lang.reflect.Method; @@ -32,10 +36,6 @@ import org.jboss.logging.annotations.Message; import org.jboss.logging.annotations.MessageLogger; -import static org.jboss.logging.Logger.Level.DEBUG; -import static org.jboss.logging.Logger.Level.INFO; -import static org.jboss.logging.Logger.Level.WARN; - /** * The Hibernate Validator logger interface for JBoss Logging. *

@@ -643,4 +643,7 @@ UnexpectedTypeException getNoValidatorFoundForTypeException(String constraintTyp @Message(id = 193, value = "%s is configured more than once via the programmatic constraint definition API.") ValidationException getConstraintHasAlreadyBeenConfiguredViaProgrammaticApiException(String annotationClassName); + + @Message(id = 194, value = "An empty element is only supported when a String is expected.") + ValidationException getEmptyElementOnlySupportedWhenStringIsExpected(); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/xml/MetaConstraintBuilder.java b/engine/src/main/java/org/hibernate/validator/internal/xml/MetaConstraintBuilder.java index a52fd090a9..35a4ff3638 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/xml/MetaConstraintBuilder.java +++ b/engine/src/main/java/org/hibernate/validator/internal/xml/MetaConstraintBuilder.java @@ -6,6 +6,8 @@ */ package org.hibernate.validator.internal.xml; +import static org.hibernate.validator.internal.util.CollectionHelper.newArrayList; + import java.io.Serializable; import java.lang.annotation.Annotation; import java.lang.reflect.Array; @@ -13,6 +15,8 @@ import java.security.AccessController; import java.security.PrivilegedAction; import java.util.List; +import java.util.regex.Pattern; + import javax.validation.Payload; import javax.validation.ValidationException; import javax.xml.bind.JAXBElement; @@ -27,8 +31,6 @@ import org.hibernate.validator.internal.util.logging.LoggerFactory; import org.hibernate.validator.internal.util.privilegedactions.GetMethod; -import static org.hibernate.validator.internal.util.CollectionHelper.newArrayList; - /** * Build meta constraint from XML * @@ -37,6 +39,8 @@ class MetaConstraintBuilder { private static final Log log = LoggerFactory.make(); + private static final Pattern IS_ONLY_WHITESPACE = Pattern.compile( "\\s*" ); + private static final String MESSAGE_PARAM = "message"; private static final String GROUPS_PARAM = "groups"; private static final String PAYLOAD_PARAM = "payload"; @@ -125,7 +129,15 @@ private Object getElementValue(ElementType elementType, Class returnType, Str boolean isArray = returnType.isArray(); if ( !isArray ) { - if ( elementType.getContent().size() != 1 ) { + if ( elementType.getContent().size() == 0 ) { + if ( returnType.getName().equals( String.class.getName() ) ) { + return ""; + } + else { + throw log.getEmptyElementOnlySupportedWhenStringIsExpected(); + } + } + else if ( elementType.getContent().size() > 1 ) { throw log.getAttemptToSpecifyAnArrayWhereSingleValueIsExpectedException(); } return getSingleValue( elementType.getContent().get( 0 ), returnType, defaultPackage ); @@ -142,7 +154,7 @@ private Object getElementValue(ElementType elementType, Class returnType, Str private static void removeEmptyContentElements(ElementType elementType) { List contentToDelete = newArrayList(); for ( Serializable content : elementType.getContent() ) { - if ( content instanceof String && ( (String) content ).matches( "[\\n ].*" ) ) { + if ( content instanceof String && IS_ONLY_WHITESPACE.matcher( (String) content ).matches() ) { contentToDelete.add( content ); } } diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/xml/MyConstraint.java b/engine/src/test/java/org/hibernate/validator/test/internal/xml/MyConstraint.java new file mode 100644 index 0000000000..7063877326 --- /dev/null +++ b/engine/src/test/java/org/hibernate/validator/test/internal/xml/MyConstraint.java @@ -0,0 +1,41 @@ +/* + * Hibernate Validator, declare and validate application constraints + * + * License: Apache License, Version 2.0 + * See the license.txt file in the root directory or . + */ +package org.hibernate.validator.test.internal.xml; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import javax.validation.Constraint; +import javax.validation.Payload; + +@Documented +@Constraint(validatedBy = MyConstraintValidator.class) +@Target({ TYPE, METHOD, FIELD }) +@Retention(RUNTIME) +public @interface MyConstraint { + + String message() default "MyConstraint is not valid"; + + Class[] groups() default {}; + + Class[] payload() default {}; + + AdditionalConstraint[] additionalConstraints() default {}; + + public @interface AdditionalConstraint { + + String message() default "AdditionalConstraint is not valid"; + + String constraint(); + } +} diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/xml/MyConstraintValidator.java b/engine/src/test/java/org/hibernate/validator/test/internal/xml/MyConstraintValidator.java new file mode 100644 index 0000000000..f741730258 --- /dev/null +++ b/engine/src/test/java/org/hibernate/validator/test/internal/xml/MyConstraintValidator.java @@ -0,0 +1,22 @@ +/* + * Hibernate Validator, declare and validate application constraints + * + * License: Apache License, Version 2.0 + * See the license.txt file in the root directory or . + */ +package org.hibernate.validator.test.internal.xml; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; + +public class MyConstraintValidator implements ConstraintValidator { + + @Override + public void initialize(MyConstraint constraintAnnotation) { + } + + @Override + public boolean isValid(Object value, ConstraintValidatorContext context) { + return true; + } +} diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/xml/XmlParsingTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/xml/XmlParsingTest.java new file mode 100644 index 0000000000..4a1c0e8be0 --- /dev/null +++ b/engine/src/test/java/org/hibernate/validator/test/internal/xml/XmlParsingTest.java @@ -0,0 +1,71 @@ +/* + * Hibernate Validator, declare and validate application constraints + * + * License: Apache License, Version 2.0 + * See the license.txt file in the root directory or . + */ +package org.hibernate.validator.test.internal.xml; + +import static org.hibernate.validator.testutils.ValidatorUtil.getConfiguration; +import static org.testng.Assert.assertEquals; + +import java.util.Set; + +import javax.validation.Validator; +import javax.validation.metadata.BeanDescriptor; +import javax.validation.metadata.ConstraintDescriptor; + +import org.assertj.core.api.Assertions; +import org.hibernate.validator.internal.metadata.descriptor.ConstraintDescriptorImpl; +import org.hibernate.validator.testutil.TestForIssue; +import org.junit.Test; + +/** + * Various tests for parsing of XML mapping files. + * + * @author Guillaume Smet + */ +public class XmlParsingTest { + + @Test + @TestForIssue(jiraKey = "HV-1101") + public void xmlConstraintMappingSupportsTabsWithoutNewLines() { + Validator validator = getConfiguration() + .addMapping( + XmlParsingTest.class.getResourceAsStream("hv-1101-tabs-mapping.xml" ) ) + .buildValidatorFactory() + .getValidator(); + + ConstraintDescriptorImpl descriptor = getSingleConstraintDescriptorForClass( validator, Double.class ); + MyConstraint constraint = (MyConstraint) descriptor.getAnnotation(); + Assertions.assertThat( constraint.additionalConstraints() ).hasSize( 1 ); + Assertions.assertThat( constraint.additionalConstraints()[0].constraint() ).isEqualTo( "AA" ); + } + + @Test + @TestForIssue(jiraKey = "HV-1101") + public void xmlConstraintMappingSupportsEmptyElementForStrings() { + Validator validator = getConfiguration() + .addMapping( + XmlParsingTest.class.getResourceAsStream("hv-1101-empty-element-mapping.xml" ) ) + .buildValidatorFactory() + .getValidator(); + + ConstraintDescriptorImpl descriptor = getSingleConstraintDescriptorForClass( validator, Double.class ); + MyConstraint constraint = (MyConstraint) descriptor.getAnnotation(); + Assertions.assertThat( constraint.additionalConstraints() ).hasSize( 1 ); + Assertions.assertThat( constraint.additionalConstraints()[0].constraint() ).isEqualTo( "" ); + } + + private ConstraintDescriptorImpl getSingleConstraintDescriptorForClass(Validator validator, Class clazz) { + BeanDescriptor beanDescriptor = validator.getConstraintsForClass( clazz ); + Set> constraintDescriptorSet = beanDescriptor.getConstraintDescriptors(); + assertEquals( + constraintDescriptorSet.size(), + 1, + "There should be only one constraint descriptor" + ); + return (ConstraintDescriptorImpl) constraintDescriptorSet.iterator().next(); + } + +} diff --git a/engine/src/test/resources/org/hibernate/validator/test/internal/xml/hv-1101-empty-element-mapping.xml b/engine/src/test/resources/org/hibernate/validator/test/internal/xml/hv-1101-empty-element-mapping.xml new file mode 100644 index 0000000000..3186ef5ec6 --- /dev/null +++ b/engine/src/test/resources/org/hibernate/validator/test/internal/xml/hv-1101-empty-element-mapping.xml @@ -0,0 +1,16 @@ + + java.lang + + + + Error + + + Missing firstName + + + + + + + \ No newline at end of file diff --git a/engine/src/test/resources/org/hibernate/validator/test/internal/xml/hv-1101-tabs-mapping.xml b/engine/src/test/resources/org/hibernate/validator/test/internal/xml/hv-1101-tabs-mapping.xml new file mode 100644 index 0000000000..aca5aff32c --- /dev/null +++ b/engine/src/test/resources/org/hibernate/validator/test/internal/xml/hv-1101-tabs-mapping.xml @@ -0,0 +1,11 @@ + + java.lang + + + + Error + Missing firstName AA + + + + \ No newline at end of file From b62f6f07051c9282905e1d80afc5a4f9f48c5cda Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Mon, 19 Sep 2016 09:57:00 +0200 Subject: [PATCH 021/124] HV-1101 Misc. clean-up: * Making logging method name consistent with others * Using TestNG instead of JUnit * Making fix work for any CharSequence type --- .../validator/internal/util/logging/Log.java | 4 ++-- .../internal/xml/MetaConstraintBuilder.java | 12 ++++++------ .../validator/test/internal/xml/XmlParsingTest.java | 2 +- .../internal/xml/hv-1101-empty-element-mapping.xml | 3 ++- .../test/internal/xml/hv-1101-tabs-mapping.xml | 3 ++- 5 files changed, 13 insertions(+), 11 deletions(-) diff --git a/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java b/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java index bbc0c1f98e..e2dcc946fc 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java +++ b/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java @@ -644,6 +644,6 @@ UnexpectedTypeException getNoValidatorFoundForTypeException(String constraintTyp @Message(id = 193, value = "%s is configured more than once via the programmatic constraint definition API.") ValidationException getConstraintHasAlreadyBeenConfiguredViaProgrammaticApiException(String annotationClassName); - @Message(id = 194, value = "An empty element is only supported when a String is expected.") - ValidationException getEmptyElementOnlySupportedWhenStringIsExpected(); + @Message(id = 194, value = "An empty element is only supported when a CharSequence is expected.") + ValidationException getEmptyElementOnlySupportedWhenCharSequenceIsExpectedExpection(); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/xml/MetaConstraintBuilder.java b/engine/src/main/java/org/hibernate/validator/internal/xml/MetaConstraintBuilder.java index 35a4ff3638..aaf2784b67 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/xml/MetaConstraintBuilder.java +++ b/engine/src/main/java/org/hibernate/validator/internal/xml/MetaConstraintBuilder.java @@ -14,6 +14,7 @@ import java.lang.reflect.Method; import java.security.AccessController; import java.security.PrivilegedAction; +import java.util.Iterator; import java.util.List; import java.util.regex.Pattern; @@ -130,11 +131,11 @@ private Object getElementValue(ElementType elementType, Class returnType, Str boolean isArray = returnType.isArray(); if ( !isArray ) { if ( elementType.getContent().size() == 0 ) { - if ( returnType.getName().equals( String.class.getName() ) ) { + if ( CharSequence.class.isAssignableFrom( returnType ) ) { return ""; } else { - throw log.getEmptyElementOnlySupportedWhenStringIsExpected(); + throw log.getEmptyElementOnlySupportedWhenCharSequenceIsExpectedExpection(); } } else if ( elementType.getContent().size() > 1 ) { @@ -152,13 +153,12 @@ else if ( elementType.getContent().size() > 1 ) { } private static void removeEmptyContentElements(ElementType elementType) { - List contentToDelete = newArrayList(); - for ( Serializable content : elementType.getContent() ) { + for ( Iterator contentIterator = elementType.getContent().iterator(); contentIterator.hasNext(); ){ + Serializable content = contentIterator.next(); if ( content instanceof String && IS_ONLY_WHITESPACE.matcher( (String) content ).matches() ) { - contentToDelete.add( content ); + contentIterator.remove(); } } - elementType.getContent().removeAll( contentToDelete ); } private Object getSingleValue(Serializable serializable, Class returnType, String defaultPackage) { diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/xml/XmlParsingTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/xml/XmlParsingTest.java index 4a1c0e8be0..d93455ed6f 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/xml/XmlParsingTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/xml/XmlParsingTest.java @@ -18,7 +18,7 @@ import org.assertj.core.api.Assertions; import org.hibernate.validator.internal.metadata.descriptor.ConstraintDescriptorImpl; import org.hibernate.validator.testutil.TestForIssue; -import org.junit.Test; +import org.testng.annotations.Test; /** * Various tests for parsing of XML mapping files. diff --git a/engine/src/test/resources/org/hibernate/validator/test/internal/xml/hv-1101-empty-element-mapping.xml b/engine/src/test/resources/org/hibernate/validator/test/internal/xml/hv-1101-empty-element-mapping.xml index 3186ef5ec6..12c917af5b 100644 --- a/engine/src/test/resources/org/hibernate/validator/test/internal/xml/hv-1101-empty-element-mapping.xml +++ b/engine/src/test/resources/org/hibernate/validator/test/internal/xml/hv-1101-empty-element-mapping.xml @@ -1,3 +1,4 @@ + java.lang @@ -13,4 +14,4 @@ - \ No newline at end of file + diff --git a/engine/src/test/resources/org/hibernate/validator/test/internal/xml/hv-1101-tabs-mapping.xml b/engine/src/test/resources/org/hibernate/validator/test/internal/xml/hv-1101-tabs-mapping.xml index aca5aff32c..915a9e327d 100644 --- a/engine/src/test/resources/org/hibernate/validator/test/internal/xml/hv-1101-tabs-mapping.xml +++ b/engine/src/test/resources/org/hibernate/validator/test/internal/xml/hv-1101-tabs-mapping.xml @@ -1,3 +1,4 @@ + java.lang @@ -8,4 +9,4 @@ - \ No newline at end of file + From df30b8a0a31f00c14c937f6a9e483de9051f1db4 Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Mon, 19 Sep 2016 10:04:05 +0200 Subject: [PATCH 022/124] HV-1101 Using FEST Assert for 5.3 backport --- .../hibernate/validator/test/internal/xml/XmlParsingTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/xml/XmlParsingTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/xml/XmlParsingTest.java index d93455ed6f..ccbc6a5ec2 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/xml/XmlParsingTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/xml/XmlParsingTest.java @@ -15,7 +15,7 @@ import javax.validation.metadata.BeanDescriptor; import javax.validation.metadata.ConstraintDescriptor; -import org.assertj.core.api.Assertions; +import org.fest.assertions.Assertions; import org.hibernate.validator.internal.metadata.descriptor.ConstraintDescriptorImpl; import org.hibernate.validator.testutil.TestForIssue; import org.testng.annotations.Test; From a2c6aa2c7611d5313b179b87b002b44d1357eb0d Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Mon, 19 Sep 2016 10:36:46 +0200 Subject: [PATCH 023/124] HV-1101 Simplifying handling of annotation member types when parsing XML descriptors --- .../internal/xml/MetaConstraintBuilder.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/engine/src/main/java/org/hibernate/validator/internal/xml/MetaConstraintBuilder.java b/engine/src/main/java/org/hibernate/validator/internal/xml/MetaConstraintBuilder.java index aaf2784b67..e801db5bd0 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/xml/MetaConstraintBuilder.java +++ b/engine/src/main/java/org/hibernate/validator/internal/xml/MetaConstraintBuilder.java @@ -131,7 +131,7 @@ private Object getElementValue(ElementType elementType, Class returnType, Str boolean isArray = returnType.isArray(); if ( !isArray ) { if ( elementType.getContent().size() == 0 ) { - if ( CharSequence.class.isAssignableFrom( returnType ) ) { + if ( returnType == String.class ) { return ""; } else { @@ -196,7 +196,7 @@ else if ( serializable instanceof JAXBElement && ( (JAXBElement) serializable private Object convertStringToReturnType(Class returnType, String value, String defaultPackage) { Object returnValue; - if ( returnType.getName().equals( byte.class.getName() ) ) { + if ( returnType == byte.class ) { try { returnValue = Byte.parseByte( value ); } @@ -204,7 +204,7 @@ private Object convertStringToReturnType(Class returnType, String value, Stri throw log.getInvalidNumberFormatException( "byte", e ); } } - else if ( returnType.getName().equals( short.class.getName() ) ) { + else if ( returnType == short.class ) { try { returnValue = Short.parseShort( value ); } @@ -212,7 +212,7 @@ else if ( returnType.getName().equals( short.class.getName() ) ) { throw log.getInvalidNumberFormatException( "short", e ); } } - else if ( returnType.getName().equals( int.class.getName() ) ) { + else if ( returnType == int.class ) { try { returnValue = Integer.parseInt( value ); } @@ -220,7 +220,7 @@ else if ( returnType.getName().equals( int.class.getName() ) ) { throw log.getInvalidNumberFormatException( "int", e ); } } - else if ( returnType.getName().equals( long.class.getName() ) ) { + else if ( returnType == long.class ) { try { returnValue = Long.parseLong( value ); } @@ -228,7 +228,7 @@ else if ( returnType.getName().equals( long.class.getName() ) ) { throw log.getInvalidNumberFormatException( "long", e ); } } - else if ( returnType.getName().equals( float.class.getName() ) ) { + else if ( returnType == float.class ) { try { returnValue = Float.parseFloat( value ); } @@ -236,7 +236,7 @@ else if ( returnType.getName().equals( float.class.getName() ) ) { throw log.getInvalidNumberFormatException( "float", e ); } } - else if ( returnType.getName().equals( double.class.getName() ) ) { + else if ( returnType == double.class ) { try { returnValue = Double.parseDouble( value ); } @@ -244,19 +244,19 @@ else if ( returnType.getName().equals( double.class.getName() ) ) { throw log.getInvalidNumberFormatException( "double", e ); } } - else if ( returnType.getName().equals( boolean.class.getName() ) ) { + else if ( returnType == boolean.class ) { returnValue = Boolean.parseBoolean( value ); } - else if ( returnType.getName().equals( char.class.getName() ) ) { + else if ( returnType == char.class ) { if ( value.length() != 1 ) { throw log.getInvalidCharValueException( value ); } returnValue = value.charAt( 0 ); } - else if ( returnType.getName().equals( String.class.getName() ) ) { + else if ( returnType == String.class ) { returnValue = value; } - else if ( returnType.getName().equals( Class.class.getName() ) ) { + else if ( returnType == Class.class ) { returnValue = classLoadingHelper.loadClass( value, defaultPackage ); } else { From 9ebb5345b093f2b68bd60f75b665a83542ccf8e9 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Mon, 29 Aug 2016 18:29:56 +0200 Subject: [PATCH 024/124] HV-1093 Update the CI links --- README.md | 4 ++-- pom.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5d82c5c5f1..02128d7b80 100644 --- a/README.md +++ b/README.md @@ -96,7 +96,7 @@ Also the integration tests on WildFly will fail on Java 9 currently, hence this ## Continuous Integration -The [official Continuous Integration service for the project](https://hibernate-validator.ci.cloudbees.com/) is hosted at CloudBees. +The official Continuous Integration service for the project is hosted on [ci.hibernate.org](http://ci.hibernate.org/view/Validator/). We provide a `.travis.yml` file so that you can enable CI for your GitHub fork by enabling the build in [your Travis CI account](https://travis-ci.org/). @@ -107,4 +107,4 @@ We provide a `.travis.yml` file so that you can enable CI for your GitHub fork b * [Downloads](http://hibernate.org/validator/downloads/) * [Mailing Lists](http://hibernate.org/community/) * [Issue Tracking](https://hibernate.atlassian.net/browse/HV) -* [Continuous Integration](https://hibernate-validator.ci.cloudbees.com/) [![Build Status](https://hibernate-validator.ci.cloudbees.com/buildStatus/icon?job=HV-5-MASTER)](https://hibernate-validator.ci.cloudbees.com/view/Hibernate%20Validator%205/job/HV-5-MASTER/) +* [Continuous Integration](http://ci.hibernate.org/view/Validator/) [![Build Status](http://ci.hibernate.org/buildStatus/icon?job=hibernate-validator-master)](http://ci.hibernate.org/view/Validator/job/hibernate-validator-master/) diff --git a/pom.xml b/pom.xml index a48209280b..3d89be61fc 100644 --- a/pom.xml +++ b/pom.xml @@ -755,7 +755,7 @@ Jenkins - https://hibernate-validator.ci.cloudbees.com/ + http://ci.hibernate.org/view/Validator/ From 8531ec8ea80ae86d531a183baf0a02b5a0cc96c3 Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Tue, 30 Aug 2016 09:59:34 +0200 Subject: [PATCH 025/124] HV-1093 Using protected build status URL --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 02128d7b80..f7a632a97a 100644 --- a/README.md +++ b/README.md @@ -107,4 +107,5 @@ We provide a `.travis.yml` file so that you can enable CI for your GitHub fork b * [Downloads](http://hibernate.org/validator/downloads/) * [Mailing Lists](http://hibernate.org/community/) * [Issue Tracking](https://hibernate.atlassian.net/browse/HV) -* [Continuous Integration](http://ci.hibernate.org/view/Validator/) [![Build Status](http://ci.hibernate.org/buildStatus/icon?job=hibernate-validator-master)](http://ci.hibernate.org/view/Validator/job/hibernate-validator-master/) +* [Continuous Integration](http://ci.hibernate.org/view/Validator/) | [![Build Status](http://ci.hibernate.org/view/Validator/job/hibernate-validator-master/badge/icon)](http://ci.hibernate.org/view/Validator/job/hibernate-validator-master/) + From 5a908001c499660cbf7690e65ff89686571c2d22 Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Mon, 5 Sep 2016 09:50:26 +0200 Subject: [PATCH 026/124] HV-1098 Adapting test.policy file --- tck-runner/src/test/resources/test.policy | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tck-runner/src/test/resources/test.policy b/tck-runner/src/test/resources/test.policy index 7c7b72e704..ab976dd95e 100644 --- a/tck-runner/src/test/resources/test.policy +++ b/tck-runner/src/test/resources/test.policy @@ -55,6 +55,10 @@ grant codeBase "file:${localRepository}/org/jboss/logging/jboss-logging/-" { grant codeBase "file:${localRepository}/javax/validation/validation-api/-" { permission java.io.FilePermission "<>", "read"; + + // in some tests this property is accessed by the TCK when the API JAR is on the callstack; the TCK doesn't + // use privileged actions, hence allow this read + permission java.util.PropertyPermission "validation.provider", "read"; }; /* =================== */ From 56fbead6f2108d86b761f3604bad70a483d35320 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Thu, 22 Sep 2016 15:13:00 +0200 Subject: [PATCH 027/124] HV-1102 Remove a junit @Test annotation --- .../java/org/hibernate/validator/bugs/TooBigMessageTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/src/test/java/org/hibernate/validator/bugs/TooBigMessageTest.java b/engine/src/test/java/org/hibernate/validator/bugs/TooBigMessageTest.java index 4eb8ffc18e..dca28f2009 100644 --- a/engine/src/test/java/org/hibernate/validator/bugs/TooBigMessageTest.java +++ b/engine/src/test/java/org/hibernate/validator/bugs/TooBigMessageTest.java @@ -17,7 +17,7 @@ import org.hibernate.validator.testutil.TestForIssue; import org.hibernate.validator.testutils.ValidatorUtil; -import org.junit.Test; +import org.testng.annotations.Test; /** * Ensure large error messages can be interpolated. From b9481baf2a562012d13d5c21435312c82bd1a1af Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Wed, 28 Sep 2016 11:44:57 +0200 Subject: [PATCH 028/124] HV-1109 Fix "Using validation groups" example --- documentation/src/main/asciidoc/ch05.asciidoc | 2 +- .../hibernate/validator/referenceguide/chapter05/GroupTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/src/main/asciidoc/ch05.asciidoc b/documentation/src/main/asciidoc/ch05.asciidoc index 0e28b9fdc6..f53a787103 100644 --- a/documentation/src/main/asciidoc/ch05.asciidoc +++ b/documentation/src/main/asciidoc/ch05.asciidoc @@ -183,7 +183,7 @@ assertEquals( // let's go to the vehicle inspection car.setPassedVehicleInspection( true ); -assertEquals( 0, validator.validate( car ).size() ); +assertEquals( 0, validator.validate( car, CarChecks.class ).size() ); // now let's add a driver. He is 18, but has not passed the driving test yet Driver john = new Driver( "John Doe" ); diff --git a/documentation/src/test/java/org/hibernate/validator/referenceguide/chapter05/GroupTest.java b/documentation/src/test/java/org/hibernate/validator/referenceguide/chapter05/GroupTest.java index 5ca43d6d97..7b4156d774 100644 --- a/documentation/src/test/java/org/hibernate/validator/referenceguide/chapter05/GroupTest.java +++ b/documentation/src/test/java/org/hibernate/validator/referenceguide/chapter05/GroupTest.java @@ -39,7 +39,7 @@ public void driveAway() { // let's go to the vehicle inspection car.setPassedVehicleInspection( true ); - assertEquals( 0, validator.validate( car ).size() ); + assertEquals( 0, validator.validate( car, CarChecks.class ).size() ); // now let's add a driver. He is 18, but has not passed the driving test yet Driver john = new Driver( "John Doe" ); From 5506a6506eb203e2d05e2d53f459a38e962370a1 Mon Sep 17 00:00:00 2001 From: Ahmed Al Hafoudh Date: Fri, 30 Sep 2016 12:31:57 +0200 Subject: [PATCH 029/124] HV-1112 Adding Slovak translations file --- .../ValidationMessages_sk.properties | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 engine/src/main/resources/org/hibernate/validator/ValidationMessages_sk.properties diff --git a/engine/src/main/resources/org/hibernate/validator/ValidationMessages_sk.properties b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_sk.properties new file mode 100644 index 0000000000..5c721e3949 --- /dev/null +++ b/engine/src/main/resources/org/hibernate/validator/ValidationMessages_sk.properties @@ -0,0 +1,29 @@ +javax.validation.constraints.AssertFalse.message = mus\u00ed by\u0165 nie +javax.validation.constraints.AssertTrue.message = mus\u00ed by\u0165 \u00e1no +javax.validation.constraints.DecimalMax.message = mus\u00ed by\u0165 men\u0161ie ${inclusive == true ? 'alebo rovn\u00e9' : ''}ako {value} +javax.validation.constraints.DecimalMin.message = mus\u00ed by\u0165 v\u00e4\u010d\u0161ie ${inclusive == true ? 'alebo rovn\u00e9' : ''}ako {value} +javax.validation.constraints.Digits.message = \u010d\u00edseln\u00e1 hodnota je mimo rozsahu (o\u010dak\u00e1van\u00e9 <{integer} \u010d\u00edslic>.<{fraction} \u010d\u00edslic>) +javax.validation.constraints.Future.message = mus\u00ed by\u0165 v bud\u00facnosti +javax.validation.constraints.Max.message = mus\u00ed by\u0165 men\u0161ie alebo rovn\u00e9 {value} +javax.validation.constraints.Min.message = mus\u00ed by\u0165 v\u00e4\u010d\u0161ie alebo rovn\u00e9 {value} +javax.validation.constraints.NotNull.message = nem\u00f4\u017ee by\u0165 null +javax.validation.constraints.Null.message = mus\u00ed by\u0165 null +javax.validation.constraints.Past.message = mus\u00ed by\u0165 v minulosti +javax.validation.constraints.Pattern.message = sa mus\u00ed zhodova\u0165 s "{regexp}" +javax.validation.constraints.Size.message = ve\u013ekos\u0165 mus\u00ed by\u0165 medzi {min} a {max} + +org.hibernate.validator.constraints.CreditCardNumber.message = neplatn\u00e9 \u010d\u00edslo kreditnej karty +org.hibernate.validator.constraints.EAN.message = nespr\u00e1vny \u010diarov\u00fd k\u00f3d {type} +org.hibernate.validator.constraints.Email.message = chybn\u00e1 emailov\u00e1 adresa +org.hibernate.validator.constraints.Length.message = d\u013a\u017eka mus\u00ed by\u0165 medzi {min} a {max} +org.hibernate.validator.constraints.LuhnCheck.message = Kontroln\u00e1 \u010d\u00edslica pre ${validatedValue} nie je spr\u00e1vna, kontroln\u00fd s\u00fa\u010det Luhn Modulo 10 zlyhal +org.hibernate.validator.constraints.Mod10Check.message = Kontroln\u00e1 \u010d\u00edslica pre ${validatedValue} nie je spr\u00e1vna, kontroln\u00fd s\u00fa\u010det Modulo 10 zlyhal +org.hibernate.validator.constraints.Mod11Check.message = Kontroln\u00e1 \u010d\u00edslica pre ${validatedValue} nie je spr\u00e1vna, kontroln\u00fd s\u00fa\u010det Modulo 11 zlyhal +org.hibernate.validator.constraints.ModCheck.message = Kontroln\u00e1 \u010d\u00edslica pre ${validatedValue} nie je spr\u00e1vna, kontroln\u00fd s\u00fa\u010det ${modType} zlyhal +org.hibernate.validator.constraints.NotBlank.message = nem\u00f4\u017ee by\u0165 pr\u00e1zdne +org.hibernate.validator.constraints.NotEmpty.message = nem\u00f4\u017ee by\u0165 pr\u00e1zdne +org.hibernate.validator.constraints.ParametersScriptAssert.message = skriptovac\u00ed v\u00fdraz "{script}" nieje vyhodnoten\u00fd na \u00e1no +org.hibernate.validator.constraints.Range.message = mus\u00ed by\u0165 medzi {min} a {max} +org.hibernate.validator.constraints.SafeHtml.message = m\u00f4\u017ee obsahova\u0165 nebezpe\u010dn\u00fd html obsah +org.hibernate.validator.constraints.ScriptAssert.message = skriptovac\u00ed v\u00fdraz "{script}" nieje vyhodnoten\u00fd na \u00e1no +org.hibernate.validator.constraints.URL.message = mus\u00ed b\u00fdt platn\u00e1 URL From b53b87291ca03b565a96c1fad2a4cd6168b2d7e1 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Tue, 4 Oct 2016 17:12:50 +0200 Subject: [PATCH 030/124] HV-1117 Downgrade surefire and failsafe to 2.18.1 Newer versions cause random failures in our OSGi integration tests. --- pom.xml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 3d89be61fc..949961b662 100644 --- a/pom.xml +++ b/pom.xml @@ -470,8 +470,12 @@ + maven-surefire-plugin - 2.19.1 + 2.18.1 once true @@ -482,7 +486,7 @@ maven-surefire-report-plugin - 2.19.1 + 2.18.1 generate-test-report @@ -499,7 +503,7 @@ maven-failsafe-plugin - 2.19.1 + 2.18.1 integration-test From e7216a86ea179f165c45bba883d4f0d624786724 Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Wed, 5 Oct 2016 11:08:03 +0200 Subject: [PATCH 031/124] HV-1117 Extracting property for Surefire version --- pom.xml | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index 949961b662..7c66997e9f 100644 --- a/pom.xml +++ b/pom.xml @@ -123,6 +123,12 @@ 7.1 + + 2.18.1 + @@ -470,12 +476,8 @@ - maven-surefire-plugin - 2.18.1 + ${maven.surefire.version} once true @@ -486,7 +488,7 @@ maven-surefire-report-plugin - 2.18.1 + ${maven.surefire.version} generate-test-report @@ -503,7 +505,7 @@ maven-failsafe-plugin - 2.18.1 + ${maven.surefire.version} integration-test From e68d78072c86d4ed27aa1a7ec474a33fc1d1d13f Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Mon, 10 Oct 2016 11:35:04 +0200 Subject: [PATCH 032/124] HV-1123 Setting up japicmp instead of clirr for API/SPI change reporting --- cdi/pom.xml | 7 +++++++ engine/pom.xml | 7 +++++++ pom.xml | 39 +++++++++++++++++++++++++++------------ 3 files changed, 41 insertions(+), 12 deletions(-) diff --git a/cdi/pom.xml b/cdi/pom.xml index d9c8c74b48..abc8c7f173 100644 --- a/cdi/pom.xml +++ b/cdi/pom.xml @@ -189,6 +189,13 @@ org.apache.maven.plugins maven-release-plugin + + com.github.siom79.japicmp + japicmp-maven-plugin + + false + + diff --git a/engine/pom.xml b/engine/pom.xml index b5bf8c1740..cb2a7ab6f9 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -246,6 +246,13 @@ org.apache.maven.plugins maven-release-plugin + + com.github.siom79.japicmp + japicmp-maven-plugin + + false + + diff --git a/pom.xml b/pom.xml index 7c66997e9f..79557e0b69 100644 --- a/pom.xml +++ b/pom.xml @@ -83,6 +83,8 @@ true 1.1.0.Final + + 5.2.4.Final 2.8 2.2.4 @@ -643,20 +645,33 @@ build-helper-maven-plugin 1.12 - - - org.codehaus.mojo - clirr-maven-plugin - 2.7 - - 5.2.4.Final + + com.github.siom79.japicmp + japicmp-maven-plugin + 0.9.1 + + + + ${project.groupId} + ${project.artifactId} + ${previous.stable} + ${project.packaging} + + + true + + + ${project.build.directory}/${project.artifactId}-${project.version}.${project.packaging} + + + + true - org/hibernate/validator/internal/** + org.hibernate.validator.internal.* - true - info - - + + + org.eclipse.m2e From 5f04a7b0ff6d467876c0dd30cdcd8588128bfe1c Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Mon, 10 Oct 2016 14:35:10 +0200 Subject: [PATCH 033/124] HV-1123 Fix the indentation and add a comment --- pom.xml | 58 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/pom.xml b/pom.xml index 79557e0b69..11a368194f 100644 --- a/pom.xml +++ b/pom.xml @@ -645,33 +645,37 @@ build-helper-maven-plugin 1.12 - - com.github.siom79.japicmp - japicmp-maven-plugin - 0.9.1 - - - - ${project.groupId} - ${project.artifactId} - ${previous.stable} - ${project.packaging} - - - true - - - ${project.build.directory}/${project.artifactId}-${project.version}.${project.packaging} - - - - true - - org.hibernate.validator.internal.* - - - - + + + com.github.siom79.japicmp + japicmp-maven-plugin + 0.9.1 + + + + ${project.groupId} + ${project.artifactId} + ${previous.stable} + ${project.packaging} + + + true + + + ${project.build.directory}/${project.artifactId}-${project.version}.${project.packaging} + + + + true + + org.hibernate.validator.internal.* + + + + org.eclipse.m2e From 0884fec3f2f3b2250978741b5a7bd4179cb9b620 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Fri, 7 Oct 2016 13:45:58 +0200 Subject: [PATCH 034/124] HV-1121 Fix property path generation for type argument constraints --- documentation/src/main/asciidoc/ch02.asciidoc | 3 +- .../chapter02/ValidationTest.java | 2 +- ...ContainedSeveralTimesInCollectionTest.java | 4 +- .../TypeAnnotationConstraintTest.java | 55 ++++++++++++++----- .../internal/engine/ValidatorImpl.java | 41 ++++++++------ .../internal/engine/ValueContext.java | 5 ++ .../internal/engine/path/NodeImpl.java | 15 +++++ .../internal/engine/path/PathImpl.java | 8 +++ 8 files changed, 97 insertions(+), 36 deletions(-) diff --git a/documentation/src/main/asciidoc/ch02.asciidoc b/documentation/src/main/asciidoc/ch02.asciidoc index adc98c37ad..0b4629e172 100644 --- a/documentation/src/main/asciidoc/ch02.asciidoc +++ b/documentation/src/main/asciidoc/ch02.asciidoc @@ -187,7 +187,8 @@ assertEquals( "'null' is not a valid car part.", constraintViolations.iterator().next().getMessage() ); -assertEquals( "parts[1]", constraintViolations.iterator().next().getPropertyPath().toString() ); +assertEquals( "parts[1].", + constraintViolations.iterator().next().getPropertyPath().toString() ); ---- ==== diff --git a/documentation/src/test/java/org/hibernate/validator/referenceguide/chapter02/ValidationTest.java b/documentation/src/test/java/org/hibernate/validator/referenceguide/chapter02/ValidationTest.java index ec12815a9c..cdfb986a61 100644 --- a/documentation/src/test/java/org/hibernate/validator/referenceguide/chapter02/ValidationTest.java +++ b/documentation/src/test/java/org/hibernate/validator/referenceguide/chapter02/ValidationTest.java @@ -87,7 +87,7 @@ public void validateListTypeArgumentConstraint() { "'null' is not a valid car part.", constraintViolations.iterator().next().getMessage() ); - assertEquals( "parts[1]", constraintViolations.iterator().next().getPropertyPath().toString() ); + assertEquals( "parts[1].", constraintViolations.iterator().next().getPropertyPath().toString() ); } @Test diff --git a/engine-jdk8-tests/src/test/java/org/hibernate/validator/test/internal/engine/typeannotationconstraint/SameElementContainedSeveralTimesInCollectionTest.java b/engine-jdk8-tests/src/test/java/org/hibernate/validator/test/internal/engine/typeannotationconstraint/SameElementContainedSeveralTimesInCollectionTest.java index 27aa1227df..da1e48f51c 100644 --- a/engine-jdk8-tests/src/test/java/org/hibernate/validator/test/internal/engine/typeannotationconstraint/SameElementContainedSeveralTimesInCollectionTest.java +++ b/engine-jdk8-tests/src/test/java/org/hibernate/validator/test/internal/engine/typeannotationconstraint/SameElementContainedSeveralTimesInCollectionTest.java @@ -58,7 +58,7 @@ public void sameInvalidInstanceInListShouldBeReportedWithAllPaths() { Set> constraintViolations = validator.validate( listContainer ); - assertCorrectPropertyPaths( constraintViolations, "values[0]", "values[2]" ); + assertCorrectPropertyPaths( constraintViolations, "values[0].", "values[2]." ); } @Test @@ -74,7 +74,7 @@ public void sameInvalidInstanceInMapShouldBeReportedWithAllPaths() { Set> constraintViolations = validator.validate( withMap ); - assertCorrectPropertyPaths( constraintViolations, "values[EMPTY_1]", "values[EMPTY_2]" ); + assertCorrectPropertyPaths( constraintViolations, "values[EMPTY_1].", "values[EMPTY_2]." ); } private static class ListContainer { diff --git a/engine-jdk8-tests/src/test/java/org/hibernate/validator/test/internal/engine/typeannotationconstraint/TypeAnnotationConstraintTest.java b/engine-jdk8-tests/src/test/java/org/hibernate/validator/test/internal/engine/typeannotationconstraint/TypeAnnotationConstraintTest.java index bb1e2c47a6..a9e5856db6 100644 --- a/engine-jdk8-tests/src/test/java/org/hibernate/validator/test/internal/engine/typeannotationconstraint/TypeAnnotationConstraintTest.java +++ b/engine-jdk8-tests/src/test/java/org/hibernate/validator/test/internal/engine/typeannotationconstraint/TypeAnnotationConstraintTest.java @@ -6,6 +6,7 @@ */ package org.hibernate.validator.test.internal.engine.typeannotationconstraint; +import static org.fest.assertions.Assertions.assertThat; import static org.hibernate.validator.internal.util.CollectionHelper.newHashMap; import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertCorrectConstraintTypes; import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertCorrectPropertyPaths; @@ -15,12 +16,15 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.Arrays; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; import javax.validation.ConstraintViolation; +import javax.validation.ElementKind; +import javax.validation.Path; import javax.validation.Valid; import javax.validation.ValidationException; import javax.validation.Validator; @@ -58,7 +62,7 @@ public void field_constraint_provided_on_type_parameter_of_a_list_gets_validated Set> constraintViolations = validator.validate( a ); assertNumberOfViolations( constraintViolations, 3 ); - assertCorrectPropertyPaths( constraintViolations, "names[1]", "names[2]", "names[2]" ); + assertCorrectPropertyPaths( constraintViolations, "names[1].", "names[2].", "names[2]." ); assertCorrectConstraintTypes( constraintViolations, NotBlankTypeUse.class, @@ -82,7 +86,7 @@ public void getter_constraint_provided_on_type_parameter_of_a_list_gets_validate Set> constraintViolations = validator.validate( a ); assertNumberOfViolations( constraintViolations, 3 ); - assertCorrectPropertyPaths( constraintViolations, "strings[0]", "strings[2]", "strings[2]" ); + assertCorrectPropertyPaths( constraintViolations, "strings[0].", "strings[2].", "strings[2]." ); assertCorrectConstraintTypes( constraintViolations, NotBlankTypeUse.class, @@ -97,7 +101,7 @@ public void constraint_provided_on_custom_bean_used_as_list_parameter_gets_valid b.bars = Arrays.asList( new Bar( 2 ), null ); Set> constraintViolations = validator.validate( b ); assertNumberOfViolations( constraintViolations, 2 ); - assertCorrectPropertyPaths( constraintViolations, "bars[1]", "bars[0].number" ); + assertCorrectPropertyPaths( constraintViolations, "bars[1].", "bars[0].number" ); assertCorrectConstraintTypes( constraintViolations, Min.class, NotNullTypeUse.class ); } @@ -122,7 +126,7 @@ public void constraint_specified_on_value_type_of_map_gets_validated() { f.namesMap.put( "third", "Name 3" ); Set> constraintViolations = validator.validate( f ); assertNumberOfViolations( constraintViolations, 1 ); - assertCorrectPropertyPaths( constraintViolations, "namesMap[second]" ); + assertCorrectPropertyPaths( constraintViolations, "namesMap[second]." ); assertCorrectConstraintTypes( constraintViolations, NotBlankTypeUse.class ); } @@ -136,7 +140,7 @@ public void constraints_specified_on_map_and_on_value_type_of_map_get_validated( f.namesMap.put( "third", "Name 3" ); Set> constraintViolations = validator.validate( f ); assertNumberOfViolations( constraintViolations, 1 ); - assertCorrectPropertyPaths( constraintViolations, "namesMap[second]" ); + assertCorrectPropertyPaths( constraintViolations, "namesMap[second]." ); assertCorrectConstraintTypes( constraintViolations, NotBlankTypeUse.class ); f = new F2(); @@ -165,9 +169,9 @@ public void return_value_constraint_provided_on_type_parameter_of_a_list_gets_va assertNumberOfViolations( constraintViolations, 3 ); assertCorrectPropertyPaths( constraintViolations, - "returnStrings.[1]", - "returnStrings.[2]", - "returnStrings.[2]" + "returnStrings.[1].", + "returnStrings.[2].", + "returnStrings.[2]." ); assertCorrectConstraintTypes( constraintViolations, @@ -191,9 +195,9 @@ public void method_parameter_constraint_provided_as_type_parameter_of_a_list_get assertNumberOfViolations( constraintViolations, 4 ); assertCorrectPropertyPaths( constraintViolations, - "setValues.arg0[0]", - "setValues.arg0[2]", - "setValues.arg0[2]", + "setValues.arg0[0].", + "setValues.arg0[2].", + "setValues.arg0[2].", "setValues.arg1" ); assertCorrectConstraintTypes( @@ -218,9 +222,9 @@ public void constructor_parameter_constraint_provided_on_type_parameter_of_a_lis assertNumberOfViolations( constraintViolations, 4 ); assertCorrectPropertyPaths( constraintViolations, - "G.arg0[0]", - "G.arg0[2]", - "G.arg0[2]", + "G.arg0[0].", + "G.arg0[2].", + "G.arg0[2].", "G.arg1" ); assertCorrectConstraintTypes( @@ -247,6 +251,29 @@ public void unsupported_use_of_type_constraints_logs_warning() { log4jRootLogger.removeAppender( assertingLogger ); } + @Test + @TestForIssue(jiraKey = "HV-1121") + public void property_path_contains_index_information() { + A1 a = new A1(); + a.names = Arrays.asList( "" ); + + Set> constraintViolations = validator.validate( a ); + + assertNumberOfViolations( constraintViolations, 1 ); + + Iterator propertyPathIterator = constraintViolations.iterator().next().getPropertyPath().iterator(); + + Path.Node firstNode = propertyPathIterator.next(); + assertThat( firstNode.getIndex() ).isNull(); + assertThat( firstNode.getName() ).isEqualTo( "names" ); + assertThat( firstNode.getKind() ).isEqualTo( ElementKind.PROPERTY ); + + Path.Node secondNode = propertyPathIterator.next(); + assertThat( secondNode.getIndex() ).isEqualTo( 0 ); + assertThat( secondNode.getName() ).isEqualTo( "" ); + assertThat( secondNode.getKind() ).isEqualTo( ElementKind.PROPERTY ); + } + static class A1 { @Valid List<@NotNullTypeUse @NotBlankTypeUse String> names; diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java index b7b0e73af2..659a691a06 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java @@ -753,26 +753,11 @@ else if ( isIndexable ) { valueContext.getCurrentGroup(), valueContext.getPropertyPath() ) ) { - validateTypeArgumentConstraints( context, valueContext, value, typeArgumentsConstraint ); + // Type arguments + validateTypeArgumentConstraints( context, buildNewLocalExecutionContext( valueContext, value ), value, typeArgumentsConstraint ); // Cascade validation - ValueContext newValueContext; - if ( value != null ) { - newValueContext = ValueContext.getLocalExecutionContext( - value, - beanMetaDataManager.getBeanMetaData( value.getClass() ), - valueContext.getPropertyPath() - ); - } - else { - newValueContext = ValueContext.getLocalExecutionContext( - valueContext.getCurrentBeanType(), - beanMetaDataManager.getBeanMetaData( valueContext.getCurrentBeanType() ), - valueContext.getPropertyPath() - ); - } - - validateInContext( newValueContext, context, validationOrder ); + validateInContext( buildNewLocalExecutionContext( valueContext, value ), context, validationOrder ); if ( shouldFailFast( context ) ) { return; } @@ -781,11 +766,31 @@ else if ( isIndexable ) { } } + private ValueContext buildNewLocalExecutionContext(ValueContext valueContext, Object value) { + ValueContext newValueContext; + if ( value != null ) { + newValueContext = ValueContext.getLocalExecutionContext( + value, + beanMetaDataManager.getBeanMetaData( value.getClass() ), + valueContext.getPropertyPath() + ); + } + else { + newValueContext = ValueContext.getLocalExecutionContext( + valueContext.getCurrentBeanType(), + beanMetaDataManager.getBeanMetaData( valueContext.getCurrentBeanType() ), + valueContext.getPropertyPath() + ); + } + return newValueContext; + } + private void validateTypeArgumentConstraints(ValidationContext context, ValueContext valueContext, Object value, Set> typeArgumentsConstraints) { valueContext.setCurrentValidatedValue( value ); + valueContext.appendCollectionElementNode(); for ( MetaConstraint metaConstraint : typeArgumentsConstraints ) { metaConstraint.validateConstraint( context, valueContext ); if ( shouldFailFast( context ) ) { diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/ValueContext.java b/engine/src/main/java/org/hibernate/validator/internal/engine/ValueContext.java index 35825d71ae..8c77aa02aa 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/ValueContext.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/ValueContext.java @@ -139,6 +139,11 @@ else if ( node.getKind() == ElementKind.RETURN_VALUE ) { } } + public final void appendCollectionElementNode() { + propertyPath = PathImpl.createCopy( propertyPath ); + propertyPath.addCollectionElementNode(); + } + public final void appendBeanNode() { propertyPath = PathImpl.createCopy( propertyPath ); propertyPath.addBeanNode(); diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/path/NodeImpl.java b/engine/src/main/java/org/hibernate/validator/internal/engine/path/NodeImpl.java index 97f51a3a01..2c43d4436d 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/path/NodeImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/path/NodeImpl.java @@ -41,6 +41,7 @@ public class NodeImpl private static final String INDEX_CLOSE = "]"; private static final String RETURN_VALUE_NODE_NAME = ""; private static final String CROSS_PARAMETER_NODE_NAME = ""; + private static final String COLLECTION_ELEMENT_NODE_NAME = ""; private final String name; private final NodeImpl parent; @@ -85,6 +86,20 @@ public static NodeImpl createPropertyNode(String name, NodeImpl parent) { ); } + public static NodeImpl createCollectionElementNode(NodeImpl parent) { + return new NodeImpl( + COLLECTION_ELEMENT_NODE_NAME, + parent, + false, + null, + null, + ElementKind.PROPERTY, + EMPTY_CLASS_ARRAY, + null, + null + ); + } + public static NodeImpl createParameterNode(String name, NodeImpl parent, int parameterIndex) { return new NodeImpl( name, diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/path/PathImpl.java b/engine/src/main/java/org/hibernate/validator/internal/engine/path/PathImpl.java index ffee4dc5ee..8657fb3df5 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/path/PathImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/path/PathImpl.java @@ -119,6 +119,14 @@ public NodeImpl addPropertyNode(String nodeName) { return currentLeafNode; } + public NodeImpl addCollectionElementNode() { + NodeImpl parent = nodeList.isEmpty() ? null : (NodeImpl) nodeList.get( nodeList.size() - 1 ); + currentLeafNode = NodeImpl.createCollectionElementNode( parent ); + nodeList.add( currentLeafNode ); + hashCode = -1; + return currentLeafNode; + } + public NodeImpl addParameterNode(String nodeName, int index) { NodeImpl parent = nodeList.isEmpty() ? null : (NodeImpl) nodeList.get( nodeList.size() - 1 ); currentLeafNode = NodeImpl.createParameterNode( nodeName, parent, index ); From d9a768d168d39743e23927e0cc642019efc1dd03 Mon Sep 17 00:00:00 2001 From: Jenkins Date: Tue, 11 Oct 2016 06:44:06 +0000 Subject: [PATCH 035/124] [Jenkins release job] README.md updated by release build 5.3.0.Final --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f7a632a97a..736a186f29 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Hibernate Validator -*Version: 5.3.0.CR1 - 05-09-2016* +*Version: 5.3.0.Final - 11-10-2016* ## What is it? @@ -35,7 +35,7 @@ Logging will delegate any log requests to that provider. org.hibernate hibernate-validator - 5.3.0.CR1 + 5.3.0.Final You also need an API and implementation of the Unified Expression Language. These dependencies must be explicitly added in an SE environment. @@ -59,7 +59,7 @@ extension by adding the following dependency: org.hibernate hibernate-validator-cdi - 5.3.0.CR1 + 5.3.0.Final * _hibernate-validator-annotation-processor-<version>.jar_ is an optional jar which can be integrated with your build From 7866687e61556c326866f2c12f0a3b13bfe19226 Mon Sep 17 00:00:00 2001 From: Jenkins Date: Tue, 11 Oct 2016 06:44:07 +0000 Subject: [PATCH 036/124] [Jenkins release job] changelog.txt updated by release build 5.3.0.Final --- changelog.txt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/changelog.txt b/changelog.txt index 591f5713ae..9ac0436859 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,6 +1,23 @@ Hibernate Validator Changelog ============================= +5.3.0.Final (11-10-2016) +------------------------- + +** Bug + * HV-1117 - build - Downgrade to surefire and failsafe 2.18.1 + * HV-1109 - documentation - Fix "Using validation groups" example + * HV-1101 - engine - Issues when using XML validation configuration + +** Improvement + * HV-1123 - build - Set up japicmp tooling to create API/SPI change reports + * HV-1121 - engine - Validation error path generation for TYPE_USE annotation + * HV-1112 - translations - ValidationMessages for Slovak + * HV-1098 - tck-runner - Adapt test.policy file of TCK runner for reading "validation.provider" property + +** Task + * HV-1093 - build - Change CI links in README.md and pom.xml + 5.3.0.CR1 (05-09-2016) ------------------------- From a3fa9cee819a8e85ab99e8106c434e175b9d5a3b Mon Sep 17 00:00:00 2001 From: Jenkins Date: Tue, 11 Oct 2016 06:44:44 +0000 Subject: [PATCH 037/124] [Jenkins release job] Preparing release 5.3.0.Final --- annotation-processor/pom.xml | 2 +- build-config/pom.xml | 2 +- cdi/pom.xml | 2 +- distribution/pom.xml | 2 +- documentation/pom.xml | 2 +- engine-jdk8-tests/pom.xml | 2 +- engine/pom.xml | 2 +- integration/pom.xml | 2 +- osgi/integrationtest/pom.xml | 2 +- osgi/karaf-features/pom.xml | 2 +- osgi/pom.xml | 2 +- performance/pom.xml | 2 +- pom.xml | 2 +- tck-runner/pom.xml | 2 +- test-utils/pom.xml | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/annotation-processor/pom.xml b/annotation-processor/pom.xml index b57f4b76cf..b2d3759cba 100644 --- a/annotation-processor/pom.xml +++ b/annotation-processor/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0-SNAPSHOT + 5.3.0.Final ../pom.xml diff --git a/build-config/pom.xml b/build-config/pom.xml index 3e89600681..d5e65b136b 100644 --- a/build-config/pom.xml +++ b/build-config/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0-SNAPSHOT + 5.3.0.Final ../pom.xml diff --git a/cdi/pom.xml b/cdi/pom.xml index abc8c7f173..a24927c660 100644 --- a/cdi/pom.xml +++ b/cdi/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0-SNAPSHOT + 5.3.0.Final ../pom.xml diff --git a/distribution/pom.xml b/distribution/pom.xml index 16e2e2ec25..6efd0d4142 100644 --- a/distribution/pom.xml +++ b/distribution/pom.xml @@ -10,7 +10,7 @@ hibernate-validator-parent org.hibernate - 5.3.0-SNAPSHOT + 5.3.0.Final ../pom.xml diff --git a/documentation/pom.xml b/documentation/pom.xml index dec85332fc..6e7ac08970 100644 --- a/documentation/pom.xml +++ b/documentation/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0-SNAPSHOT + 5.3.0.Final ../pom.xml diff --git a/engine-jdk8-tests/pom.xml b/engine-jdk8-tests/pom.xml index a04dd88a2d..65de02f4ef 100644 --- a/engine-jdk8-tests/pom.xml +++ b/engine-jdk8-tests/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.0-SNAPSHOT + 5.3.0.Final hibernate-validator-engine-jdk8-tests diff --git a/engine/pom.xml b/engine/pom.xml index cb2a7ab6f9..25ef60d864 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0-SNAPSHOT + 5.3.0.Final ../pom.xml diff --git a/integration/pom.xml b/integration/pom.xml index 23eed0ee65..3a37589006 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0-SNAPSHOT + 5.3.0.Final ../pom.xml diff --git a/osgi/integrationtest/pom.xml b/osgi/integrationtest/pom.xml index aeab64132e..e4032fff8a 100644 --- a/osgi/integrationtest/pom.xml +++ b/osgi/integrationtest/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-osgi org.hibernate - 5.3.0-SNAPSHOT + 5.3.0.Final ../pom.xml diff --git a/osgi/karaf-features/pom.xml b/osgi/karaf-features/pom.xml index 0e7ca30c96..90b43d745d 100644 --- a/osgi/karaf-features/pom.xml +++ b/osgi/karaf-features/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-osgi org.hibernate - 5.3.0-SNAPSHOT + 5.3.0.Final ../pom.xml diff --git a/osgi/pom.xml b/osgi/pom.xml index 8f903a6d56..cd0f24248e 100644 --- a/osgi/pom.xml +++ b/osgi/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0-SNAPSHOT + 5.3.0.Final ../pom.xml diff --git a/performance/pom.xml b/performance/pom.xml index dd143f3b5d..2353050251 100644 --- a/performance/pom.xml +++ b/performance/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0-SNAPSHOT + 5.3.0.Final ../pom.xml diff --git a/pom.xml b/pom.xml index 11a368194f..b388b97de4 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.0-SNAPSHOT + 5.3.0.Final pom Hibernate Validator Aggregator diff --git a/tck-runner/pom.xml b/tck-runner/pom.xml index 71df1cefc6..01ed2a8173 100644 --- a/tck-runner/pom.xml +++ b/tck-runner/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0-SNAPSHOT + 5.3.0.Final ../pom.xml diff --git a/test-utils/pom.xml b/test-utils/pom.xml index 5953422ae9..6d8febaa4c 100644 --- a/test-utils/pom.xml +++ b/test-utils/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.0-SNAPSHOT + 5.3.0.Final hibernate-validator-test-utils From dc76b884c06ac4b9eae801de613761782f5484e9 Mon Sep 17 00:00:00 2001 From: Jenkins Date: Tue, 11 Oct 2016 06:52:00 +0000 Subject: [PATCH 038/124] [Jenkins release job] Preparing next development iteration --- annotation-processor/pom.xml | 2 +- build-config/pom.xml | 2 +- cdi/pom.xml | 2 +- distribution/pom.xml | 2 +- documentation/pom.xml | 2 +- engine-jdk8-tests/pom.xml | 2 +- engine/pom.xml | 2 +- integration/pom.xml | 2 +- osgi/integrationtest/pom.xml | 2 +- osgi/karaf-features/pom.xml | 2 +- osgi/pom.xml | 2 +- performance/pom.xml | 2 +- pom.xml | 2 +- tck-runner/pom.xml | 2 +- test-utils/pom.xml | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/annotation-processor/pom.xml b/annotation-processor/pom.xml index b2d3759cba..3ff2c1c21c 100644 --- a/annotation-processor/pom.xml +++ b/annotation-processor/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0.Final + 5.3.1-SNAPSHOT ../pom.xml diff --git a/build-config/pom.xml b/build-config/pom.xml index d5e65b136b..1573ff17cd 100644 --- a/build-config/pom.xml +++ b/build-config/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0.Final + 5.3.1-SNAPSHOT ../pom.xml diff --git a/cdi/pom.xml b/cdi/pom.xml index a24927c660..3e4c9b07c5 100644 --- a/cdi/pom.xml +++ b/cdi/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0.Final + 5.3.1-SNAPSHOT ../pom.xml diff --git a/distribution/pom.xml b/distribution/pom.xml index 6efd0d4142..f83ab5a2b4 100644 --- a/distribution/pom.xml +++ b/distribution/pom.xml @@ -10,7 +10,7 @@ hibernate-validator-parent org.hibernate - 5.3.0.Final + 5.3.1-SNAPSHOT ../pom.xml diff --git a/documentation/pom.xml b/documentation/pom.xml index 6e7ac08970..7790c9f8f1 100644 --- a/documentation/pom.xml +++ b/documentation/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0.Final + 5.3.1-SNAPSHOT ../pom.xml diff --git a/engine-jdk8-tests/pom.xml b/engine-jdk8-tests/pom.xml index 65de02f4ef..f4ea9855b2 100644 --- a/engine-jdk8-tests/pom.xml +++ b/engine-jdk8-tests/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.0.Final + 5.3.1-SNAPSHOT hibernate-validator-engine-jdk8-tests diff --git a/engine/pom.xml b/engine/pom.xml index 25ef60d864..4705851da8 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0.Final + 5.3.1-SNAPSHOT ../pom.xml diff --git a/integration/pom.xml b/integration/pom.xml index 3a37589006..28378e0c64 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0.Final + 5.3.1-SNAPSHOT ../pom.xml diff --git a/osgi/integrationtest/pom.xml b/osgi/integrationtest/pom.xml index e4032fff8a..c11222fd4d 100644 --- a/osgi/integrationtest/pom.xml +++ b/osgi/integrationtest/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-osgi org.hibernate - 5.3.0.Final + 5.3.1-SNAPSHOT ../pom.xml diff --git a/osgi/karaf-features/pom.xml b/osgi/karaf-features/pom.xml index 90b43d745d..e6a1b5ec53 100644 --- a/osgi/karaf-features/pom.xml +++ b/osgi/karaf-features/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-osgi org.hibernate - 5.3.0.Final + 5.3.1-SNAPSHOT ../pom.xml diff --git a/osgi/pom.xml b/osgi/pom.xml index cd0f24248e..c3740d4437 100644 --- a/osgi/pom.xml +++ b/osgi/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0.Final + 5.3.1-SNAPSHOT ../pom.xml diff --git a/performance/pom.xml b/performance/pom.xml index 2353050251..bb2b6fb25d 100644 --- a/performance/pom.xml +++ b/performance/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0.Final + 5.3.1-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index b388b97de4..f60d51a35f 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.0.Final + 5.3.1-SNAPSHOT pom Hibernate Validator Aggregator diff --git a/tck-runner/pom.xml b/tck-runner/pom.xml index 01ed2a8173..0b51fec533 100644 --- a/tck-runner/pom.xml +++ b/tck-runner/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.0.Final + 5.3.1-SNAPSHOT ../pom.xml diff --git a/test-utils/pom.xml b/test-utils/pom.xml index 6d8febaa4c..7cec0b6e95 100644 --- a/test-utils/pom.xml +++ b/test-utils/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.0.Final + 5.3.1-SNAPSHOT hibernate-validator-test-utils From d739505fa0e1c63964f9f904d2c2daae125233b3 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Mon, 10 Oct 2016 15:50:33 +0200 Subject: [PATCH 039/124] HV-1125 Latest JDK9 previews changed -addmods to --add-modules --- README.md | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 736a186f29..2b4f9f4b28 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ There are more build options available as well. For more information refer to [C To build Hibernate Validator with JDK 9, export the following environment variable: - export MAVEN_OPTS="-addmods java.annotations.common,java.xml.bind" + export MAVEN_OPTS="--add-modules java.annotations.common,java.xml.bind" Then the build can be started like this: diff --git a/pom.xml b/pom.xml index f60d51a35f..bf252f74e6 100644 --- a/pom.xml +++ b/pom.xml @@ -858,7 +858,7 @@ 9 - -addmods java.xml.bind + --add-modules java.xml.bind From 435ea736452dce28037edefd16fecceecb598bc9 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Tue, 11 Oct 2016 16:28:49 +0200 Subject: [PATCH 040/124] HV-1126 Upgrade the plexus-archiver dependency to support JDK9 The maven-assembly-plugin uses a version which does not support JDK9. See https://github.com/codehaus-plexus/plexus-archiver/pull/12 --- pom.xml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pom.xml b/pom.xml index bf252f74e6..b581d42c37 100644 --- a/pom.xml +++ b/pom.xml @@ -529,6 +529,22 @@ maven-assembly-plugin 2.6 + + + + org.codehaus.plexus + plexus-archiver + 3.4 + + + org.codehaus.plexus + plexus-io + 2.7.1 + + maven-release-plugin From e3f8b17d8db144d4981ab94dc0e9857fda7e61ce Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Thu, 13 Oct 2016 10:41:04 +0200 Subject: [PATCH 041/124] HV-1128 Enabling integration tests on JDK 9 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b581d42c37..bec28d7c0c 100644 --- a/pom.xml +++ b/pom.xml @@ -70,6 +70,7 @@ cdi tck-runner annotation-processor + integration performance @@ -840,7 +841,6 @@ 1.8 - integration osgi From b889b5b92f0ec76e2613b523bc45d6e94a8fb0bc Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Wed, 12 Oct 2016 18:30:52 +0200 Subject: [PATCH 042/124] HV-1129 Upgrading WildFly Arquillian version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index bec28d7c0c..6acf9bdcba 100644 --- a/pom.xml +++ b/pom.xml @@ -113,7 +113,7 @@ 10.1.0.Final 1.2 2.3.5.Final - 1.0.2.Final + 2.0.0.Final 1.0.0.Final 1.1.11.Final From e5a9e4c7e70a7e9c8f4538e96c32c436b852cd9f Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Mon, 17 Oct 2016 12:34:16 +0200 Subject: [PATCH 043/124] HV-1131 Adding test, fixing test class loader --- .../ValidatorFactoryNoELBootstrapTest.java | 77 +++++++++++++++---- 1 file changed, 61 insertions(+), 16 deletions(-) diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/engine/ValidatorFactoryNoELBootstrapTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/engine/ValidatorFactoryNoELBootstrapTest.java index 778b485568..228346c970 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/engine/ValidatorFactoryNoELBootstrapTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/engine/ValidatorFactoryNoELBootstrapTest.java @@ -6,6 +6,9 @@ */ package org.hibernate.validator.test.internal.engine; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; @@ -13,20 +16,19 @@ import java.lang.reflect.Method; import javax.validation.Validation; +import javax.validation.bootstrap.GenericBootstrap; import org.hibernate.validator.testutil.TestForIssue; import org.testng.annotations.Test; -import static org.testng.Assert.assertTrue; -import static org.testng.Assert.fail; - /** * @author Hardy Ferentschik + * @author Guillaume Smet */ -@TestForIssue(jiraKey = "HV-793") public class ValidatorFactoryNoELBootstrapTest { @Test + @TestForIssue(jiraKey = "HV-793") public void testMissingELDependencyThrowsExceptionDuringFactoryBootstrap() throws Exception { ClassLoader classLoader = new ELIgnoringClassLoader(); Class clazz = classLoader.loadClass( Validation.class.getName() ); @@ -41,11 +43,26 @@ public void testMissingELDependencyThrowsExceptionDuringFactoryBootstrap() throw catch (InvocationTargetException e) { assertTrue( getRootCause( e ).getMessage().startsWith( "HV000183" ), - "Bootstrapping in Validation should threw an unexpected exception: " + e.getMessage() + "Bootstrapping in Validation should throw an unexpected exception: " + e.getMessage() ); } } + @Test + @TestForIssue(jiraKey = "HV-1131") + public void testMissingELDependencyDontThrowExceptionDuringConfigurationInitialization() throws Exception { + ClassLoader classLoader = new ELIgnoringClassLoader(); + + Class validationClass = classLoader.loadClass( Validation.class.getName() ); + Method byDefaultProviderMethod = validationClass.getMethod( "byDefaultProvider" ); + + Class genericBootstrapClass = classLoader.loadClass( GenericBootstrap.class.getName() ); + Method configureMethod = genericBootstrapClass.getMethod( "configure" ); + + Object genericBootstrap = byDefaultProviderMethod.invoke( null ); + configureMethod.invoke( genericBootstrap ); + } + /** * A lot of classpath magic is happening here. The test suite has the EL dependencies on the classpath. * To test what happens if the EL classes cannot be found, we need to somehow "remove" these classes from the @@ -70,19 +87,24 @@ public Class loadClass(String className) throws ClassNotFoundException { if ( className.startsWith( EL_PACKAGE_PREFIX ) ) { throw new ClassNotFoundException(); } + // for all other classes we have to jump through some hoops - else { - // load the class via the parent class loader - Class clazz = super.loadClass( className ); - // if we have a class from the java name space we need to return it, since the security manager - // won't allow to redefine it - for ( String prefix : PASS_THROUGH_PACKAGE_PREFIXES ) { - if ( className.startsWith( prefix ) ) { - return clazz; - } + + // load the class via the parent class loader + // if we have a class from the java name space we need to return it, since the security manager + // won't allow to redefine it + for ( String prefix : PASS_THROUGH_PACKAGE_PREFIXES ) { + if ( className.startsWith( prefix ) ) { + return super.loadClass( className ); } } + // if the class is already loaded, we return it + Class clazz = findLoadedClass( className ); + if ( clazz != null ) { + return clazz; + } + // for all other classes we load the class data from disk and define the class new // this will ensure that ELIgnoringClassLoader will be the associated classloader for this class byte[] classData; @@ -92,13 +114,36 @@ public Class loadClass(String className) throws ClassNotFoundException { catch (IOException e) { throw new RuntimeException(); } - return defineClass( className, classData, 0, classData.length, null ); + clazz = defineClass( className, classData, 0, classData.length, null ); + + // it is our responsability to define the package of the class + String packageName = getPackageName( className ); + if ( packageName != null && getPackage( packageName ) == null ) { + definePackage( packageName, null, null, null, null, null, null, null ); + } + + return clazz; } } - private byte[] loadClassData(String className) throws IOException { + private static String getPackageName(String className) { + int i = className.lastIndexOf( '.' ); + if ( i > 0 ) { + return className.substring( 0, i ); + } + else { + return null; + } + } + + private byte[] loadClassData(String className) throws IOException, ClassNotFoundException { String path = "/" + className.replace( ".", "/" ) + ".class"; InputStream in = ValidatorFactoryNoELBootstrapTest.class.getResourceAsStream( path ); + + if ( in == null ) { + throw new ClassNotFoundException(); + } + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); int bytesRead; From 5a8a9553e10b90c07cc6ff460272030888c65312 Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Mon, 17 Oct 2016 12:22:15 +0200 Subject: [PATCH 044/124] HV-1131 Implementing test routines without reflection --- .../ValidatorFactoryNoELBootstrapTest.java | 128 +++++++++++------- 1 file changed, 80 insertions(+), 48 deletions(-) diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/engine/ValidatorFactoryNoELBootstrapTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/engine/ValidatorFactoryNoELBootstrapTest.java index 228346c970..90c6b6bfbf 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/engine/ValidatorFactoryNoELBootstrapTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/engine/ValidatorFactoryNoELBootstrapTest.java @@ -6,6 +6,8 @@ */ package org.hibernate.validator.test.internal.engine; +import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertCorrectConstraintViolationMessages; +import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; @@ -13,11 +15,14 @@ import java.io.IOException; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; +import java.util.Set; +import javax.validation.ConstraintViolation; import javax.validation.Validation; -import javax.validation.bootstrap.GenericBootstrap; +import javax.validation.Validator; +import javax.validation.constraints.Min; +import org.hibernate.validator.messageinterpolation.ParameterMessageInterpolator; import org.hibernate.validator.testutil.TestForIssue; import org.testng.annotations.Test; @@ -29,38 +34,52 @@ public class ValidatorFactoryNoELBootstrapTest { @Test @TestForIssue(jiraKey = "HV-793") - public void testMissingELDependencyThrowsExceptionDuringFactoryBootstrap() throws Exception { - ClassLoader classLoader = new ELIgnoringClassLoader(); - Class clazz = classLoader.loadClass( Validation.class.getName() ); + public void bootstrapFailsWhenUsingDefaultInterpolatorWithoutExpressionFactory() throws Throwable { + runWithoutElLibs( BootstrapFailsWhenUsingDefaultInterpolatorWithoutExpressionFactory.class ); + } - Object validation = clazz.newInstance(); - Method m = clazz.getMethod( "buildDefaultValidatorFactory" ); + public static class BootstrapFailsWhenUsingDefaultInterpolatorWithoutExpressionFactory { - try { - m.invoke( validation ); - fail( "An exception should have been thrown" ); - } - catch (InvocationTargetException e) { - assertTrue( - getRootCause( e ).getMessage().startsWith( "HV000183" ), - "Bootstrapping in Validation should throw an unexpected exception: " + e.getMessage() - ); + public void run() { + try { + Validation.buildDefaultValidatorFactory(); + fail( "An exception should have been thrown" ); + } + catch (Throwable e) { + assertTrue( + getRootCause( e ).getMessage().startsWith( "HV000183" ), + "Bootstrapping in Validation should throw an unexpected exception: " + e.getMessage() + ); + } } } @Test @TestForIssue(jiraKey = "HV-1131") - public void testMissingELDependencyDontThrowExceptionDuringConfigurationInitialization() throws Exception { - ClassLoader classLoader = new ELIgnoringClassLoader(); + public void canUseParameterInterpolatorWithoutExpressionFactory() throws Throwable { + runWithoutElLibs( CanUseParameterInterpolatorWithoutExpressionFactory.class ); + } - Class validationClass = classLoader.loadClass( Validation.class.getName() ); - Method byDefaultProviderMethod = validationClass.getMethod( "byDefaultProvider" ); + public static class CanUseParameterInterpolatorWithoutExpressionFactory { - Class genericBootstrapClass = classLoader.loadClass( GenericBootstrap.class.getName() ); - Method configureMethod = genericBootstrapClass.getMethod( "configure" ); + public void run() { + Validator validator = Validation.byDefaultProvider() + .configure() + .messageInterpolator( new ParameterMessageInterpolator() ) + .buildValidatorFactory() + .getValidator(); - Object genericBootstrap = byDefaultProviderMethod.invoke( null ); - configureMethod.invoke( genericBootstrap ); + assertNotNull( validator ); + + Set> violations = validator.validate( new SomeBean() ); + assertCorrectConstraintViolationMessages( violations, "must be greater than or equal to 42" ); + } + } + + public static class SomeBean { + + @Min(42) + private final long myLong = 41; } /** @@ -68,7 +87,7 @@ public void testMissingELDependencyDontThrowExceptionDuringConfigurationInitiali * To test what happens if the EL classes cannot be found, we need to somehow "remove" these classes from the * classpath. */ - public class ELIgnoringClassLoader extends ClassLoader { + private static class ELIgnoringClassLoader extends ClassLoader { private final String EL_PACKAGE_PREFIX = "javax.el"; private final String[] PASS_THROUGH_PACKAGE_PREFIXES = new String[] { "java.", @@ -124,39 +143,52 @@ public Class loadClass(String className) throws ClassNotFoundException { return clazz; } - } - private static String getPackageName(String className) { - int i = className.lastIndexOf( '.' ); - if ( i > 0 ) { - return className.substring( 0, i ); - } - else { - return null; + private String getPackageName(String className) { + int i = className.lastIndexOf( '.' ); + if ( i > 0 ) { + return className.substring( 0, i ); + } + else { + return null; + } } - } - private byte[] loadClassData(String className) throws IOException, ClassNotFoundException { - String path = "/" + className.replace( ".", "/" ) + ".class"; - InputStream in = ValidatorFactoryNoELBootstrapTest.class.getResourceAsStream( path ); + private byte[] loadClassData(String className) throws IOException, ClassNotFoundException { + String path = "/" + className.replace( ".", "/" ) + ".class"; + InputStream in = ValidatorFactoryNoELBootstrapTest.class.getResourceAsStream( path ); - if ( in == null ) { - throw new ClassNotFoundException(); - } + if ( in == null ) { + throw new ClassNotFoundException(); + } + + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + int bytesRead; + byte[] data = new byte[16384]; + while ( ( bytesRead = in.read( data, 0, data.length ) ) != -1 ) { + buffer.write( data, 0, bytesRead ); + } - int bytesRead; - byte[] data = new byte[16384]; - while ( ( bytesRead = in.read( data, 0, data.length ) ) != -1 ) { - buffer.write( data, 0, bytesRead ); + buffer.flush(); + return buffer.toByteArray(); } + } - buffer.flush(); - return buffer.toByteArray(); + /** + * Loads the given class using the EL-ignoring class loader and executes it. + */ + private void runWithoutElLibs(Class delegateType) throws Throwable { + try { + Object test = new ELIgnoringClassLoader().loadClass( delegateType.getName() ).newInstance(); + test.getClass().getMethod( "run" ).invoke( test ); + } + catch (InvocationTargetException ite) { + throw ite.getCause(); + } } - private Throwable getRootCause(Throwable throwable) { + private static Throwable getRootCause(Throwable throwable) { while ( true ) { Throwable cause = throwable.getCause(); if ( cause == null ) { From 9fddff6de0c0c79857089f2222a0f17217edcdd5 Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Tue, 18 Oct 2016 08:53:28 +0200 Subject: [PATCH 045/124] HV-1131 Deferring instantiation of default message interpolator until it's actually used --- .../internal/engine/ConfigurationImpl.java | 40 +++++++++++-------- .../internal/engine/ValidatorContextImpl.java | 3 +- .../messageinterpolation/ElTermResolver.java | 6 +-- .../ResourceBundleMessageInterpolator.java | 17 +++++++- 4 files changed, 43 insertions(+), 23 deletions(-) diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/ConfigurationImpl.java b/engine/src/main/java/org/hibernate/validator/internal/engine/ConfigurationImpl.java index 7e96191e21..506c2f2ef9 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/ConfigurationImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/ConfigurationImpl.java @@ -72,7 +72,13 @@ public class ConfigurationImpl implements HibernateValidatorConfiguration, Confi private static final Log log = LoggerFactory.make(); private final ResourceBundleLocator defaultResourceBundleLocator; - private final MessageInterpolator defaultMessageInterpolator; + + /** + * Built lazily so RBMI and its dependency on EL is only initialized if actually needed + */ + private MessageInterpolator defaultMessageInterpolator; + private MessageInterpolator messageInterpolator; + private final TraversableResolver defaultTraversableResolver; private final ConstraintValidatorFactory defaultConstraintValidatorFactory; private final ParameterNameProvider defaultParameterNameProvider; @@ -126,7 +132,6 @@ private ConfigurationImpl() { this.defaultTraversableResolver = new DefaultTraversableResolver(); this.defaultConstraintValidatorFactory = new ConstraintValidatorFactoryImpl(); this.defaultParameterNameProvider = new DefaultParameterNameProvider(); - this.defaultMessageInterpolator = new ResourceBundleMessageInterpolator( defaultResourceBundleLocator ); this.serviceLoaderBasedConstraintMappingContributor = new ServiceLoaderBasedConstraintMappingContributor( typeResolutionHelper ); @@ -347,7 +352,18 @@ public final boolean isIgnoreXmlConfiguration() { @Override public final MessageInterpolator getMessageInterpolator() { - return validationBootstrapParameters.getMessageInterpolator(); + if ( messageInterpolator == null ) { + // apply explicitly given MI, otherwise use default one + MessageInterpolator interpolator = validationBootstrapParameters.getMessageInterpolator(); + if ( interpolator != null ) { + messageInterpolator = interpolator; + } + else { + messageInterpolator = getDefaultMessageInterpolatorConfiguredWithClassLoader(); + } + } + + return messageInterpolator; } @Override @@ -401,6 +417,10 @@ public ClassLoader getExternalClassLoader() { @Override public final MessageInterpolator getDefaultMessageInterpolator() { + if ( defaultMessageInterpolator == null ) { + defaultMessageInterpolator = new ResourceBundleMessageInterpolator( defaultResourceBundleLocator ); + } + return defaultMessageInterpolator; } @@ -428,7 +448,6 @@ public final Set getProgrammaticMappings() { return programmaticMappings; } - private boolean isSpecificProvider() { return validationBootstrapParameters.getProvider() != null; } @@ -440,12 +459,6 @@ private void parseValidationXml() { if ( ignoreXmlConfiguration ) { log.ignoringXmlConfiguration(); - // make sure we use the defaults in case they haven't been provided yet - if ( validationBootstrapParameters.getMessageInterpolator() == null ) { - validationBootstrapParameters.setMessageInterpolator( - getDefaultMessageInterpolatorConfiguredWithClassLoader() - ); - } if ( validationBootstrapParameters.getTraversableResolver() == null ) { validationBootstrapParameters.setTraversableResolver( defaultTraversableResolver ); } @@ -471,11 +484,6 @@ private void applyXmlSettings(ValidationBootstrapParameters xmlParameters) { if ( xmlParameters.getMessageInterpolator() != null ) { validationBootstrapParameters.setMessageInterpolator( xmlParameters.getMessageInterpolator() ); } - else { - validationBootstrapParameters.setMessageInterpolator( - getDefaultMessageInterpolatorConfiguredWithClassLoader() - ); - } } if ( validationBootstrapParameters.getTraversableResolver() == null ) { @@ -547,7 +555,7 @@ private MessageInterpolator getDefaultMessageInterpolatorConfiguredWithClassLoad true ) ) : - defaultMessageInterpolator; + getDefaultMessageInterpolator(); } /** diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorContextImpl.java index 3d16a50b85..93dba04526 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorContextImpl.java @@ -8,6 +8,7 @@ import java.util.ArrayList; import java.util.List; + import javax.validation.ConstraintValidatorFactory; import javax.validation.MessageInterpolator; import javax.validation.ParameterNameProvider; @@ -36,7 +37,7 @@ public class ValidatorContextImpl implements HibernateValidatorContext { private boolean failFast; private final List> validatedValueHandlers; private TimeProvider timeProvider; - private MethodValidationConfiguration methodValidationConfiguration = new MethodValidationConfiguration(); + private final MethodValidationConfiguration methodValidationConfiguration = new MethodValidationConfiguration(); public ValidatorContextImpl(ValidatorFactoryImpl validatorFactory) { diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/ElTermResolver.java b/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/ElTermResolver.java index 73181fc647..3a99de311f 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/ElTermResolver.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/ElTermResolver.java @@ -53,11 +53,7 @@ public class ElTermResolver implements TermResolver { */ public ElTermResolver(Locale locale, ExpressionFactory expressionFactory) { this.locale = locale; - /* - * This call to newInstance might throw. Bad news; error is not until call to validate for case where - * EL is nonfunctional. Good news; cases that don't need EL don't get any exception. - */ - this.expressionFactory = expressionFactory != null ? expressionFactory : ExpressionFactory.newInstance(); + this.expressionFactory = expressionFactory; } @Override diff --git a/engine/src/main/java/org/hibernate/validator/messageinterpolation/ResourceBundleMessageInterpolator.java b/engine/src/main/java/org/hibernate/validator/messageinterpolation/ResourceBundleMessageInterpolator.java index 8e53370389..3453c8e082 100644 --- a/engine/src/main/java/org/hibernate/validator/messageinterpolation/ResourceBundleMessageInterpolator.java +++ b/engine/src/main/java/org/hibernate/validator/messageinterpolation/ResourceBundleMessageInterpolator.java @@ -28,7 +28,7 @@ public class ResourceBundleMessageInterpolator extends AbstractMessageInterpolat private static final Log LOG = LoggerFactory.make(); - private ExpressionFactory expressionFactory; + private final ExpressionFactory expressionFactory; // HV-793 - To fail eagerly in case we have no EL dependencies on the classpath we try to load the expression // factory type eagerly @@ -43,25 +43,30 @@ public class ResourceBundleMessageInterpolator extends AbstractMessageInterpolat public ResourceBundleMessageInterpolator() { super(); + this.expressionFactory = buildExpressionFactory(); } public ResourceBundleMessageInterpolator(ResourceBundleLocator userResourceBundleLocator) { super( userResourceBundleLocator ); + this.expressionFactory = buildExpressionFactory(); } public ResourceBundleMessageInterpolator(ResourceBundleLocator userResourceBundleLocator, ResourceBundleLocator contributorResourceBundleLocator) { super( userResourceBundleLocator, contributorResourceBundleLocator ); + this.expressionFactory = buildExpressionFactory(); } public ResourceBundleMessageInterpolator(ResourceBundleLocator userResourceBundleLocator, ResourceBundleLocator contributorResourceBundleLocator, boolean cachingEnabled) { super( userResourceBundleLocator, contributorResourceBundleLocator, cachingEnabled ); + this.expressionFactory = buildExpressionFactory(); } public ResourceBundleMessageInterpolator(ResourceBundleLocator userResourceBundleLocator, boolean cachingEnabled) { super( userResourceBundleLocator, null, cachingEnabled ); + this.expressionFactory = buildExpressionFactory(); } public ResourceBundleMessageInterpolator(ResourceBundleLocator userResourceBundleLocator, boolean cachingEnabled, ExpressionFactory expressionFactory) { @@ -74,4 +79,14 @@ public String interpolate(Context context, Locale locale, String term) { InterpolationTerm expression = new InterpolationTerm( term, locale, expressionFactory ); return expression.interpolate( context ); } + + private static ExpressionFactory buildExpressionFactory() { + try { + return ExpressionFactory.newInstance(); + } + catch (NoClassDefFoundError e) { + // HV-793 - We fail eagerly in case we have no EL dependencies on the classpath + throw LOG.getMissingELDependenciesException(); + } + } } From 4daee7527a97ba9a09ffa77e56564793673b9217 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Tue, 18 Oct 2016 11:46:41 +0200 Subject: [PATCH 046/124] HV-1131 Add org.xml and jdk.internal to pass through packages It is needed for JDK9. --- .../internal/engine/ValidatorFactoryNoELBootstrapTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/engine/ValidatorFactoryNoELBootstrapTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/engine/ValidatorFactoryNoELBootstrapTest.java index 90c6b6bfbf..36b423dbdd 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/engine/ValidatorFactoryNoELBootstrapTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/engine/ValidatorFactoryNoELBootstrapTest.java @@ -93,7 +93,9 @@ private static class ELIgnoringClassLoader extends ClassLoader { "java.", "javax.xml.", "sun.", - "org.apache." + "org.apache.", + "org.xml", + "jdk.internal" }; public ELIgnoringClassLoader() { From 138e196d4c9caa3a09d436bf93335460e9dab054 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Tue, 18 Oct 2016 12:42:05 +0200 Subject: [PATCH 047/124] HV-1131 Add javax.el implementation as a dependency Until now, we only needed the API until we had to interpolate a message but now that the ExpressionFactory is instantiated in the constructor of ResourceBundleMessageInterpolator, we need the impl as soon as we instantiate a ResourceBundleMessageInterpolator. --- engine-jdk8-tests/pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/engine-jdk8-tests/pom.xml b/engine-jdk8-tests/pom.xml index f4ea9855b2..30f525ce31 100644 --- a/engine-jdk8-tests/pom.xml +++ b/engine-jdk8-tests/pom.xml @@ -61,6 +61,11 @@ javax.el-api provided + + org.glassfish.web + javax.el + provided + + + + - + yyyy-MM-dd + + UA-45270411-3 + GTM-NJWS5L + Hibernate + + - - - - - org.jboss.maven.plugins - maven-jdocbook-plugin - - ${basedir}/target/asciidoc-docbook - index.xml - en-US - - - html_single - classpath:/xslt/org/hibernate/jdocbook/xslt/xhtml-single.xsl - - index.html - - - html - classpath:/xslt/org/hibernate/jdocbook/xslt/xhtml.xsl - - index.html - - - pdf - classpath:/xslt/org/hibernate/jdocbook/xslt/pdf.xsl - - hibernate_validator_reference.pdf - - - - true - saxon - - - - - - yyyy-MM-dd - - UA-45270411-3 - GTM-NJWS5L - Hibernate - - - - - - docbook-processing - generate-resources - - resources - generate - - - - - + + + docbook-processing + generate-resources + + resources + generate + + + + + From b2a8289b3d65d653945412bf034ff06d0bff1dd5 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Tue, 18 Oct 2016 15:34:25 +0200 Subject: [PATCH 050/124] HV-1134 Add the sourcedir attributes to the output-docbook execution --- documentation/pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/documentation/pom.xml b/documentation/pom.xml index 50bebd8bc0..11143c5c99 100644 --- a/documentation/pom.xml +++ b/documentation/pom.xml @@ -137,6 +137,10 @@ docbook target/asciidoc-docbook/en-US + + ${basedir}/src/test/java + ${basedir}/../engine/src/main/java + From 716f91a0a794d377ab3eeed9b3e225a4aa85bb74 Mon Sep 17 00:00:00 2001 From: Julien Furgerot Date: Thu, 13 Oct 2016 19:57:02 +0200 Subject: [PATCH 051/124] HV-1132 Documentation tests: force locale to "en" in surefire forked jvm --- documentation/pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/documentation/pom.xml b/documentation/pom.xml index 11143c5c99..53605ea186 100644 --- a/documentation/pom.xml +++ b/documentation/pom.xml @@ -117,6 +117,12 @@ + + maven-surefire-plugin + + -Duser.language=en + + From 01697b689ed49545b55b996b8d67befa93b782d5 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Tue, 18 Oct 2016 17:32:10 +0200 Subject: [PATCH 052/124] HV-1002 Fix collectMetaConstraintsForPath logic in the iterable case --- .../internal/engine/ValidatorImpl.java | 170 ++++++++++++------ .../internal/util/ReflectionHelper.java | 16 ++ .../validator/internal/util/logging/Log.java | 8 +- .../test/internal/engine/ValidatorTest.java | 109 +++++++++-- 4 files changed, 239 insertions(+), 64 deletions(-) diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java index 659a691a06..8efff390ca 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java @@ -82,6 +82,7 @@ * @author Hardy Ferentschik * @author Gunnar Morling * @author Kevin Pollet <kevin.pollet@serli.com> (C) 2011 SERLI + * @author Guillaume Smet */ public class ValidatorImpl implements Validator, ExecutableValidator { @@ -802,17 +803,15 @@ private void validateTypeArgumentConstraints(ValidationContext context, private Set> validatePropertyInContext(ValidationContext context, PathImpl propertyPath, ValidationOrder validationOrder) { List> metaConstraints = newArrayList(); List> typeUseConstraints = newArrayList(); - Iterator propertyIter = propertyPath.iterator(); - ValueContext valueContext = collectMetaConstraintsForPath( + ValueContext valueContext = collectMetaConstraintsForPathWithValue( context, - propertyIter, propertyPath, metaConstraints, typeUseConstraints ); if ( valueContext.getCurrentBean() == null ) { - throw log.getInvalidPropertyPathException(); + throw log.getUnableToReachPropertyToValidateException( context.getRootBean(), propertyPath ); } if ( metaConstraints.size() == 0 && typeUseConstraints.size() == 0 ) { @@ -868,8 +867,8 @@ private void assertDefaultGroupSequenceIsExpandable(ValueContext value private Set> validateValueInContext(ValidationContext context, Object value, PathImpl propertyPath, ValidationOrder validationOrder) { List> metaConstraints = newArrayList(); List> typeArgumentConstraints = newArrayList(); - ValueContext valueContext = collectMetaConstraintsForPath( - context, propertyPath.iterator(), propertyPath, metaConstraints, typeArgumentConstraints + ValueContext valueContext = collectMetaConstraintsForPathWithoutValue( + context, propertyPath, metaConstraints, typeArgumentConstraints ); valueContext.setCurrentValidatedValue( value ); @@ -1476,79 +1475,144 @@ private int validateConstraintsForGroup(ValidationContext validationContext, } /** - * Collects all {@code MetaConstraint}s which match the given path relative to the specified root class. - *

- * This method is called recursively. - *

+ * Collects all {@code MetaConstraint}s which match the given property path relative to the specified root class for a given value. * * @param validationContext The validation context. - * @param propertyIter An instance of {@code PropertyIterator} in order to iterate the items of the original property path. * @param propertyPath The property path for which constraints have to be collected. - * @param metaConstraintsList An instance of {@code Map} where {@code MetaConstraint}s which match the given path are saved for each class in the hosting class hierarchy. + * @param metaConstraints A list where {@code MetaConstraint}s which match the given path are saved. + * @param typeArgumentConstraints A list where type arguments {@code MetaConstraint}s which match the given path are saved. * * @return Returns an instance of {@code ValueContext} which describes the local validation context associated to the given property path. */ - private ValueContext collectMetaConstraintsForPath(ValidationContext validationContext, - Iterator propertyIter, + private ValueContext collectMetaConstraintsForPathWithValue(ValidationContext validationContext, PathImpl propertyPath, - List> metaConstraintsList, + List> metaConstraints, List> typeArgumentConstraints) { Class clazz = validationContext.getRootBeanClass(); Object value = validationContext.getRootBean(); + PropertyMetaData propertyMetaData = null; - // cast is ok, since we are dealing with engine internal classes - NodeImpl elem = (NodeImpl) propertyIter.next(); - Object newValue = value; + Iterator propertyPathIter = propertyPath.iterator(); - BeanMetaData metaData = beanMetaDataManager.getBeanMetaData( clazz ); - PropertyMetaData property = metaData.getMetaDataFor( elem.getName() ); + while ( propertyPathIter.hasNext() ) { + // cast is ok, since we are dealing with engine internal classes + NodeImpl propertyPathNode = (NodeImpl) propertyPathIter.next(); + propertyMetaData = getPropertyMetaData( clazz, propertyPathNode ); - // use precomputed method list as ReflectionHelper#containsMember is slow - if ( property == null ) { - throw log.getInvalidPropertyPathException( elem.getName(), metaData.getBeanClass().getName() ); - } - else if ( !propertyIter.hasNext() ) { - metaConstraintsList.addAll( property.getConstraints() ); - typeArgumentConstraints.addAll( property.getTypeArgumentsConstraints() ); - } - else { - if ( property.isCascading() ) { - Type type = property.getType(); - newValue = newValue == null ? null : getValue( newValue, validationContext, property ); - if ( elem.isIterable() ) { - if ( newValue != null && elem.getIndex() != null ) { - newValue = ReflectionHelper.getIndexedValue( newValue, elem.getIndex() ); + // if the property is not the leaf property, we set up the context for the next iteration + if ( propertyPathIter.hasNext() ) { + if ( !propertyMetaData.isCascading() ) { + throw log.getInvalidPropertyPathException( propertyPath.asString(), validationContext.getRootBeanClass().getName() ); + } + + value = getValue( value, validationContext, propertyMetaData ); + if ( value == null ) { + throw log.getUnableToReachPropertyToValidateException( validationContext.getRootBean(), propertyPath ); + } + clazz = value.getClass(); + + // if we are in the case of an iterable and we want to validate an element of this iterable, we have to get the + // element value + if ( propertyPathNode.isIterable() ) { + propertyPathNode = (NodeImpl) propertyPathIter.next(); + + if ( propertyPathNode.getIndex() != null ) { + value = ReflectionHelper.getIndexedValue( value, propertyPathNode.getIndex() ); } - else if ( newValue != null && elem.getKey() != null ) { - newValue = ReflectionHelper.getMappedValue( newValue, elem.getKey() ); + else if ( propertyPathNode.getKey() != null ) { + value = ReflectionHelper.getMappedValue( value, propertyPathNode.getKey() ); } - else if ( newValue != null ) { + else { throw log.getPropertyPathMustProvideIndexOrMapKeyException(); } - type = ReflectionHelper.getIndexedType( type ); + + if ( value == null ) { + throw log.getUnableToReachPropertyToValidateException( validationContext.getRootBean(), propertyPath ); + } + + clazz = value.getClass(); + propertyMetaData = getPropertyMetaData( clazz, propertyPathNode ); } + } + } + + if ( propertyMetaData == null ) { + // should only happen if the property path is empty, which should never happen + throw log.getInvalidPropertyPathException( propertyPath.asString(), clazz.getName() ); + } + + metaConstraints.addAll( propertyMetaData.getConstraints() ); + typeArgumentConstraints.addAll( propertyMetaData.getTypeArgumentsConstraints() ); + + return ValueContext.getLocalExecutionContext( value, null, propertyPath ); + } + + /** + * Collects all {@code MetaConstraint}s which match the given property path relative to the specified root class without a value. + *

+ * We are only able to use the static types as we don't have the value. + *

+ * + * @param validationContext The validation context. + * @param propertyPath The property path for which constraints have to be collected. + * @param metaConstraints A list where {@code MetaConstraint}s which match the given path are saved. + * @param typeArgumentConstraints A list where type arguments {@code MetaConstraint}s which match the given path are saved. + * + * @return Returns an instance of {@code ValueContext} which describes the local validation context associated to the given property path. + */ + private ValueContext collectMetaConstraintsForPathWithoutValue(ValidationContext validationContext, + PathImpl propertyPath, + List> metaConstraints, + List> typeArgumentConstraints) { + Class clazz = validationContext.getRootBeanClass(); + PropertyMetaData propertyMetaData = null; + + Iterator propertyPathIter = propertyPath.iterator(); - ValidationContext newValidationContext; - if ( newValue != null ) { - newValidationContext = getValidationContext().forValidateProperty( newValue ); + while ( propertyPathIter.hasNext() ) { + // cast is ok, since we are dealing with engine internal classes + NodeImpl propertyPathNode = (NodeImpl) propertyPathIter.next(); + propertyMetaData = getPropertyMetaData( clazz, propertyPathNode ); + + // if the property is not the leaf property, we set up the context for the next iteration + if ( propertyPathIter.hasNext() ) { + // if we are in the case of an iterable and we want to validate an element of this iterable, we have to get the + // type from the parameterized type + if ( propertyPathNode.isIterable() ) { + propertyPathNode = (NodeImpl) propertyPathIter.next(); + + clazz = ReflectionHelper.getClassFromType( ReflectionHelper.getIndexedType( propertyMetaData.getType() ) ); + propertyMetaData = getPropertyMetaData( clazz, propertyPathNode ); } else { - newValidationContext = getValidationContext().forValidateValue( (Class) type ); + clazz = ReflectionHelper.getClassFromType( propertyMetaData.getType() ); } - return collectMetaConstraintsForPath( - newValidationContext, - propertyIter, - propertyPath, - metaConstraintsList, - typeArgumentConstraints - ); } } - if ( newValue == null ) { - return ValueContext.getLocalExecutionContext( clazz, null, propertyPath ); + if ( propertyMetaData == null ) { + // should only happen if the property path is empty, which should never happen + throw log.getInvalidPropertyPathException( propertyPath.asString(), clazz.getName() ); } - return ValueContext.getLocalExecutionContext( value, null, propertyPath ); + + metaConstraints.addAll( propertyMetaData.getConstraints() ); + typeArgumentConstraints.addAll( propertyMetaData.getTypeArgumentsConstraints() ); + + return ValueContext.getLocalExecutionContext( clazz, null, propertyPath ); + } + + private PropertyMetaData getPropertyMetaData( Class beanClass, Path.Node propertyNode ) { + if ( !ElementKind.PROPERTY.equals( propertyNode.getKind() ) ) { + throw log.getInvalidPropertyPathException( propertyNode.getName(), beanClass.getName() ); + } + + BeanMetaData beanMetaData = beanMetaDataManager.getBeanMetaData( beanClass ); + PropertyMetaData propertyMetaData = beanMetaData.getMetaDataFor( propertyNode.getName() ); + + if ( propertyMetaData == null ) { + throw log.getInvalidPropertyPathException( propertyNode.getName(), beanClass.getName() ); + } + return propertyMetaData; } /** diff --git a/engine/src/main/java/org/hibernate/validator/internal/util/ReflectionHelper.java b/engine/src/main/java/org/hibernate/validator/internal/util/ReflectionHelper.java index c8d3e49475..1a69f01a83 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/util/ReflectionHelper.java +++ b/engine/src/main/java/org/hibernate/validator/internal/util/ReflectionHelper.java @@ -298,6 +298,22 @@ else if ( TypeHelper.isArray( type ) ) { return indexedType; } + /** + * Converts the given Type to a Class. + * + * @param type the type to convert + * @return the class corresponding to the type + */ + public static Class getClassFromType(Type type) { + if ( type instanceof Class ) { + return (Class) type; + } + if ( type instanceof ParameterizedType ) { + return getClassFromType( ( (ParameterizedType) type ).getRawType() ); + } + throw log.getUnableToConvertTypeToClassException( type ); + } + /** * @param type the type to check. * diff --git a/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java b/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java index e2dcc946fc..ac26360bc8 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java +++ b/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java @@ -172,7 +172,7 @@ UnexpectedTypeException getNoValidatorFoundForTypeException(String constraintTyp @Message(id = 38, value = "Invalid property path.") IllegalArgumentException getInvalidPropertyPathException(); - @Message(id = 39, value = "Invalid property path. There is no property %1$s in entity %2$s.") + @Message(id = 39, value = "Invalid property path. Either there is no property %1$s in entity %2$s or it is not possible to cascade to the property.") IllegalArgumentException getInvalidPropertyPathException(String propertyName, String beanClassName); @Message(id = 40, value = "Property path must provide index or map key.") @@ -646,4 +646,10 @@ UnexpectedTypeException getNoValidatorFoundForTypeException(String constraintTyp @Message(id = 194, value = "An empty element is only supported when a CharSequence is expected.") ValidationException getEmptyElementOnlySupportedWhenCharSequenceIsExpectedExpection(); + + @Message(id = 195, value = "Unable to reach the property to validate for the bean %s and the property path %s. A property is null along the way.") + ValidationException getUnableToReachPropertyToValidateException(Object bean, Path path); + + @Message(id = 196, value = "Unable to convert the Type %s to a Class.") + ValidationException getUnableToConvertTypeToClassException(Type type); } diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/engine/ValidatorTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/engine/ValidatorTest.java index 52b4a3c150..ea6cc2faa2 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/engine/ValidatorTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/engine/ValidatorTest.java @@ -6,10 +6,21 @@ */ package org.hibernate.validator.test.internal.engine; +import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertCorrectConstraintTypes; +import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertCorrectPropertyPaths; +import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertNumberOfViolations; +import static org.hibernate.validator.testutils.ValidatorUtil.getValidator; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertSame; +import static org.testng.Assert.assertTrue; + import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Set; + import javax.validation.ConstraintViolation; import javax.validation.GroupSequence; import javax.validation.Valid; @@ -21,25 +32,17 @@ import javax.validation.executable.ExecutableValidator; import javax.validation.metadata.BeanDescriptor; -import org.testng.annotations.Test; - import org.hibernate.validator.constraints.Length; import org.hibernate.validator.internal.engine.ValidatorImpl; import org.hibernate.validator.testutil.CountValidationCalls; import org.hibernate.validator.testutil.CountValidationCallsValidator; import org.hibernate.validator.testutil.TestForIssue; - -import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertCorrectConstraintTypes; -import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertCorrectPropertyPaths; -import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertNumberOfViolations; -import static org.hibernate.validator.testutils.ValidatorUtil.getValidator; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertSame; -import static org.testng.Assert.assertTrue; +import org.testng.annotations.Test; /** * @author Hardy Ferentschik * @author Kevin Pollet <kevin.pollet@serli.com> (C) 2011 SERLI + * @author Guillaume Smet */ public class ValidatorTest { @Test @@ -211,6 +214,53 @@ public void testValidateValueWithNestedPath() { Set> constraintViolations = validator.validateValue( X.class, "list[0].foo", null ); assertNumberOfViolations( constraintViolations, 1 ); assertCorrectPropertyPaths( constraintViolations, "list[0].foo" ); + + Set> constraintViolationsK = validator.validateValue( K.class, "foo.bar", null ); + assertNumberOfViolations( constraintViolationsK, 1 ); + assertCorrectPropertyPaths( constraintViolationsK, "foo.bar" ); + } + + @Test + @TestForIssue(jiraKey = "HV-1002") + public void testValidatePropertyWithNestedPath() { + Validator validator = getValidator(); + X someX = new X(); + someX.addZ( new Z() ); + Set> constraintViolationsX = validator.validateProperty( someX, "list[0].foo" ); + assertNumberOfViolations( constraintViolationsX, 1 ); + assertCorrectPropertyPaths( constraintViolationsX, "list[0].foo" ); + + I someI = new I(); + someI.putJ( "bar", new J() ); + Set> constraintViolationsI = validator.validateProperty( someI, "map[bar].foo" ); + assertNumberOfViolations( constraintViolationsI, 1 ); + assertCorrectPropertyPaths( constraintViolationsI, "map[bar].foo" ); + + K someK = new K(); + someK.foo = new L(); + Set> constraintViolationsK = validator.validateProperty( someK, "foo.bar" ); + assertNumberOfViolations( constraintViolationsK, 1 ); + assertCorrectPropertyPaths( constraintViolationsK, "foo.bar" ); + + constraintViolationsK = validator.validateProperty( someK, "foo.genericProperty" ); + assertNumberOfViolations( constraintViolationsK, 1 ); + assertCorrectPropertyPaths( constraintViolationsK, "foo.genericProperty" ); + } + + @Test(expectedExceptions = { ValidationException.class }, expectedExceptionsMessageRegExp = "^HV000195:.*") + @TestForIssue(jiraKey = "HV-1002") + public void testValidatePropertyWithNestedPathAndNullPropertyInTheWay() { + Validator validator = getValidator(); + X someX = new X(); + validator.validateProperty( someX, "list[0].foo" ); + } + + @Test(expectedExceptions = { IllegalArgumentException.class }, expectedExceptionsMessageRegExp = "^HV000039:.*") + @TestForIssue(jiraKey = "HV-1002") + public void testValidatePropertyWithNestedPathAndMissingValid() { + Validator validator = getValidator(); + M someM = new M(); + validator.validateProperty( someM, "foo.baz" ); } class A { @@ -325,6 +375,45 @@ public String getFoo() { } } + class I { + @Valid + Map map = new HashMap(); + + public void putJ(String key, J j) { + map.put( key, j ); + } + } + + class J { + @NotNull + String foo; + } + + class K { + @Valid + L foo; + } + + class L { + @NotNull + String bar; + + @NotNull + T genericProperty; + } + + class M { + N foo; + + @NotNull + String bar; + } + + class N { + @NotNull + String baz; + } + class X { @Valid List list = new ArrayList(); From 2d5a1534dc06b0930eabc9f2402ec786661d7822 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Tue, 18 Oct 2016 17:59:37 +0200 Subject: [PATCH 053/124] HV-1002 Improve naming and consistency of preexisting methods --- .../internal/engine/ValidatorImpl.java | 57 ++++++++++--------- .../validator/internal/util/logging/Log.java | 4 +- 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java index 8efff390ca..fa8f440ca0 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java @@ -611,9 +611,9 @@ private boolean validatePropertyTypeConstraint(ValidationContext validationCo private boolean validateMetaConstraint(ValidationContext validationContext, ValueContext valueContext, MetaConstraint metaConstraint) { if ( isValidationRequired( validationContext, valueContext, metaConstraint ) ) { if ( valueContext.getCurrentBean() != null ) { - Object valueToValidate = getValue( - metaConstraint.getLocation().getMember(), - valueContext.getCurrentBean() + Object valueToValidate = getBeanMemberValue( + valueContext.getCurrentBean(), + metaConstraint.getLocation().getMember() ); valueContext.setCurrentValidatedValue( valueToValidate ); } @@ -647,7 +647,7 @@ private void validateCascadedConstraints(ValidationContext validationContext, elementType ) ) { - Object value = getValue( valueContext.getCurrentBean(), validationContext, cascadable ); + Object value = getBeanPropertyValue( validationContext, valueContext.getCurrentBean(), cascadable ); if ( value != null ) { @@ -1497,15 +1497,15 @@ private ValueContext collectMetaConstraintsForPathWithValue(Validation while ( propertyPathIter.hasNext() ) { // cast is ok, since we are dealing with engine internal classes NodeImpl propertyPathNode = (NodeImpl) propertyPathIter.next(); - propertyMetaData = getPropertyMetaData( clazz, propertyPathNode ); + propertyMetaData = getBeanPropertyMetaData( clazz, propertyPathNode ); // if the property is not the leaf property, we set up the context for the next iteration if ( propertyPathIter.hasNext() ) { if ( !propertyMetaData.isCascading() ) { - throw log.getInvalidPropertyPathException( propertyPath.asString(), validationContext.getRootBeanClass().getName() ); + throw log.getInvalidPropertyPathException( validationContext.getRootBeanClass().getName(), propertyPath.asString() ); } - value = getValue( value, validationContext, propertyMetaData ); + value = getBeanPropertyValue( validationContext, value, propertyMetaData ); if ( value == null ) { throw log.getUnableToReachPropertyToValidateException( validationContext.getRootBean(), propertyPath ); } @@ -1531,14 +1531,14 @@ else if ( propertyPathNode.getKey() != null ) { } clazz = value.getClass(); - propertyMetaData = getPropertyMetaData( clazz, propertyPathNode ); + propertyMetaData = getBeanPropertyMetaData( clazz, propertyPathNode ); } } } if ( propertyMetaData == null ) { // should only happen if the property path is empty, which should never happen - throw log.getInvalidPropertyPathException( propertyPath.asString(), clazz.getName() ); + throw log.getInvalidPropertyPathException( clazz.getName(), propertyPath.asString() ); } metaConstraints.addAll( propertyMetaData.getConstraints() ); @@ -1572,7 +1572,7 @@ private ValueContext collectMetaConstraintsForPathWithoutValue(Validat while ( propertyPathIter.hasNext() ) { // cast is ok, since we are dealing with engine internal classes NodeImpl propertyPathNode = (NodeImpl) propertyPathIter.next(); - propertyMetaData = getPropertyMetaData( clazz, propertyPathNode ); + propertyMetaData = getBeanPropertyMetaData( clazz, propertyPathNode ); // if the property is not the leaf property, we set up the context for the next iteration if ( propertyPathIter.hasNext() ) { @@ -1582,7 +1582,7 @@ private ValueContext collectMetaConstraintsForPathWithoutValue(Validat propertyPathNode = (NodeImpl) propertyPathIter.next(); clazz = ReflectionHelper.getClassFromType( ReflectionHelper.getIndexedType( propertyMetaData.getType() ) ); - propertyMetaData = getPropertyMetaData( clazz, propertyPathNode ); + propertyMetaData = getBeanPropertyMetaData( clazz, propertyPathNode ); } else { clazz = ReflectionHelper.getClassFromType( propertyMetaData.getType() ); @@ -1592,7 +1592,7 @@ private ValueContext collectMetaConstraintsForPathWithoutValue(Validat if ( propertyMetaData == null ) { // should only happen if the property path is empty, which should never happen - throw log.getInvalidPropertyPathException( propertyPath.asString(), clazz.getName() ); + throw log.getInvalidPropertyPathException( clazz.getName(), propertyPath.asString() ); } metaConstraints.addAll( propertyMetaData.getConstraints() ); @@ -1601,20 +1601,6 @@ private ValueContext collectMetaConstraintsForPathWithoutValue(Validat return ValueContext.getLocalExecutionContext( clazz, null, propertyPath ); } - private PropertyMetaData getPropertyMetaData( Class beanClass, Path.Node propertyNode ) { - if ( !ElementKind.PROPERTY.equals( propertyNode.getKind() ) ) { - throw log.getInvalidPropertyPathException( propertyNode.getName(), beanClass.getName() ); - } - - BeanMetaData beanMetaData = beanMetaDataManager.getBeanMetaData( beanClass ); - PropertyMetaData propertyMetaData = beanMetaData.getMetaDataFor( propertyNode.getName() ); - - if ( propertyMetaData == null ) { - throw log.getInvalidPropertyPathException( propertyNode.getName(), beanClass.getName() ); - } - return propertyMetaData; - } - /** * Must be called and stored for the duration of the stack call * A new instance is returned each time @@ -1723,7 +1709,22 @@ private boolean shouldFailFast(ValidationContext context) { return context.isFailFastModeEnabled() && !context.getFailingConstraints().isEmpty(); } - private Object getValue(Object object, ValidationContext validationContext, Cascadable cascadable) { + private PropertyMetaData getBeanPropertyMetaData( Class beanClass, Path.Node propertyNode ) { + if ( !ElementKind.PROPERTY.equals( propertyNode.getKind() ) ) { + throw log.getInvalidPropertyPathException( beanClass.getName(), propertyNode.getName() ); + } + + BeanMetaData beanMetaData = beanMetaDataManager.getBeanMetaData( beanClass ); + PropertyMetaData propertyMetaData = beanMetaData.getMetaDataFor( propertyNode.getName() ); + + if ( propertyMetaData == null ) { + throw log.getInvalidPropertyPathException( beanClass.getName(), propertyNode.getName() ); + } + return propertyMetaData; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + private Object getBeanPropertyValue(ValidationContext validationContext, Object object, Cascadable cascadable) { Object value = cascadable.getValue( object ); // Value can be wrapped (e.g. Optional
). Try to unwrap it @@ -1738,7 +1739,7 @@ private Object getValue(Object object, ValidationContext validationContext, Casc return value; } - private Object getValue(Member member, Object object) { + private Object getBeanMemberValue(Object object, Member member) { if ( member == null ) { return object; } diff --git a/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java b/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java index ac26360bc8..7f6a6bdab7 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java +++ b/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java @@ -172,8 +172,8 @@ UnexpectedTypeException getNoValidatorFoundForTypeException(String constraintTyp @Message(id = 38, value = "Invalid property path.") IllegalArgumentException getInvalidPropertyPathException(); - @Message(id = 39, value = "Invalid property path. Either there is no property %1$s in entity %2$s or it is not possible to cascade to the property.") - IllegalArgumentException getInvalidPropertyPathException(String propertyName, String beanClassName); + @Message(id = 39, value = "Invalid property path. Either there is no property %2$s in entity %1$s or it is not possible to cascade to the property.") + IllegalArgumentException getInvalidPropertyPathException(String beanClassName, String propertyName); @Message(id = 40, value = "Property path must provide index or map key.") IllegalArgumentException getPropertyPathMustProvideIndexOrMapKeyException(); From b533faee01c685c88d99fd9a1ad61b0dc6a3acfc Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Wed, 19 Oct 2016 15:08:45 +0200 Subject: [PATCH 054/124] HV-1032 Avoid infinite loop in TypeHelper.isAssignable --- .../validator/internal/util/TypeHelper.java | 5 ++++- .../validator/test/internal/util/ChildEntity.java | 14 ++++++++++++++ .../validator/test/internal/util/ParentEntity.java | 14 ++++++++++++++ .../test/internal/util/TypeHelperTest.java | 12 +++++++++++- 4 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 engine/src/test/java/org/hibernate/validator/test/internal/util/ChildEntity.java create mode 100644 engine/src/test/java/org/hibernate/validator/test/internal/util/ParentEntity.java diff --git a/engine/src/main/java/org/hibernate/validator/internal/util/TypeHelper.java b/engine/src/main/java/org/hibernate/validator/internal/util/TypeHelper.java index 3e89ef0fcd..ac300527a8 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/util/TypeHelper.java +++ b/engine/src/main/java/org/hibernate/validator/internal/util/TypeHelper.java @@ -571,7 +571,10 @@ private static Map getActualTypeArgumentsByParameterInternal(Type ty Map actualTypeArgumentsByParameter = new LinkedHashMap(); for ( int i = 0; i < typeParameters.length; i++ ) { - actualTypeArgumentsByParameter.put( typeParameters[i], typeArguments[i] ); + // we only add the mapping if it is not a cyclic dependency (see HV-1032) + if ( !typeParameters[i].equals( typeArguments[i] ) ) { + actualTypeArgumentsByParameter.put( typeParameters[i], typeArguments[i] ); + } } return actualTypeArgumentsByParameter; diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/util/ChildEntity.java b/engine/src/test/java/org/hibernate/validator/test/internal/util/ChildEntity.java new file mode 100644 index 0000000000..97bda50c2b --- /dev/null +++ b/engine/src/test/java/org/hibernate/validator/test/internal/util/ChildEntity.java @@ -0,0 +1,14 @@ +/* + * Hibernate Validator, declare and validate application constraints + * + * License: Apache License, Version 2.0 + * See the license.txt file in the root directory or . + */ +package org.hibernate.validator.test.internal.util; + +/** + * @author Guillaume Smet + */ +public class ChildEntity extends ParentEntity { + +} diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/util/ParentEntity.java b/engine/src/test/java/org/hibernate/validator/test/internal/util/ParentEntity.java new file mode 100644 index 0000000000..547d43045f --- /dev/null +++ b/engine/src/test/java/org/hibernate/validator/test/internal/util/ParentEntity.java @@ -0,0 +1,14 @@ +/* + * Hibernate Validator, declare and validate application constraints + * + * License: Apache License, Version 2.0 + * See the license.txt file in the root directory or . + */ +package org.hibernate.validator.test.internal.util; + +/** + * @author Guillaume Smet + */ +public class ParentEntity { + +} diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/util/TypeHelperTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/util/TypeHelperTest.java index a3679ee8d0..1323b6291e 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/util/TypeHelperTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/util/TypeHelperTest.java @@ -21,6 +21,7 @@ import java.lang.reflect.GenericDeclaration; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; import java.lang.reflect.Proxy; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; @@ -37,8 +38,8 @@ import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; - import org.hibernate.validator.internal.util.TypeHelper; +import org.hibernate.validator.testutil.TestForIssue; import static org.hibernate.validator.internal.util.CollectionHelper.newArrayList; import static org.testng.Assert.assertEquals; @@ -866,6 +867,15 @@ public void testTypeDiscovery() { assertNull( validatorsTypes.get( String.class ) ); } + @Test + @TestForIssue(jiraKey = "HV-1032") + public void testTypeHelperDoesntGoIntoInfiniteLoop() { + Type parentEntityType = ChildEntity.class.getGenericSuperclass(); + ParameterizedType childEntityType = TypeHelper.parameterizedType( ChildEntity.class, ChildEntity.class.getTypeParameters() ); + + assertTrue( TypeHelper.isAssignable( parentEntityType, childEntityType ) ); + } + private static void assertAsymmetricallyAssignable(Type supertype, Type type) { assertAssignable( supertype, type ); assertUnassignable( type, supertype ); From e4c7094aacb0ab659d2aa57a3e30f389b1294972 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mert=20C=CC=A7ALIS=CC=A7KAN?= Date: Fri, 21 Oct 2016 10:05:10 +0300 Subject: [PATCH 055/124] HV-1140 Use ROOT locale in StringHelper#decapitalize Before that, we could have locale specific behaviors when lowercasing. It was especially true for the Turkish locale - which is often cited as an example of this issue. --- .../validator/internal/util/StringHelper.java | 3 ++- .../test/internal/util/StringHelperTest.java | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/engine/src/main/java/org/hibernate/validator/internal/util/StringHelper.java b/engine/src/main/java/org/hibernate/validator/internal/util/StringHelper.java index 618252b5c1..67ce1d4b97 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/util/StringHelper.java +++ b/engine/src/main/java/org/hibernate/validator/internal/util/StringHelper.java @@ -7,6 +7,7 @@ package org.hibernate.validator.internal.util; import java.util.Arrays; +import java.util.Locale; /** * Helper class dealing with strings. @@ -81,7 +82,7 @@ public static String decapitalize(String string) { return string; } else { - return string.substring( 0, 1 ).toLowerCase() + string.substring( 1 ); + return string.substring( 0, 1 ).toLowerCase( Locale.ROOT ) + string.substring( 1 ); } } diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/util/StringHelperTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/util/StringHelperTest.java index 2aa128902b..5106418133 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/util/StringHelperTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/util/StringHelperTest.java @@ -7,7 +7,9 @@ package org.hibernate.validator.test.internal.util; import java.util.Arrays; +import java.util.Locale; +import org.hibernate.validator.testutil.TestForIssue; import org.testng.annotations.Test; import org.hibernate.validator.internal.util.StringHelper; @@ -87,6 +89,15 @@ public void decapitalizeShouldReturnDecapizalizedWord() { assertEquals( StringHelper.decapitalize( "Giraffe" ), "giraffe" ); } + @Test + @TestForIssue(jiraKey = "HV-1140") + public void decapitalizeShouldReturnDecapizalizedWordOnTurkishLocale() { + Locale defaultLocale = Locale.getDefault(); + Locale.setDefault( new Locale( "tr" , "TR" ) ); + assertEquals( StringHelper.decapitalize( "IsIsolationLevelGuaranteed" ), "isIsolationLevelGuaranteed" ); + Locale.setDefault( defaultLocale ); + } + @Test public void decapitalizeShouldReturnSameWordForDecapizalizedWord() { assertEquals( StringHelper.decapitalize( "giraffe" ), "giraffe" ); From bda55793cd37da8ad8d6fa35b06cd6849969215b Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Thu, 27 Oct 2016 14:03:58 +0200 Subject: [PATCH 056/124] Update copyright.txt --- copyright.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/copyright.txt b/copyright.txt index 1666fa3cdd..191969d0d4 100644 --- a/copyright.txt +++ b/copyright.txt @@ -26,6 +26,7 @@ Henno Vermeulen Jan-Willem Willebrands Jason T. Greene Julien May +Julien Furgerot Juraci Krohling Justin Nauman Kathryn Killebrew @@ -35,6 +36,7 @@ Lee KyoungIl Leonardo Loch Zanivan Lucas Pouzac Mark Hobson +Mert Çalişkan Paolo Perrotta Pete Muir Sanne Grinovero From 913c7707e37b06d0d4bde8586506cf8cb25b42b1 Mon Sep 17 00:00:00 2001 From: Jenkins Date: Thu, 27 Oct 2016 14:26:18 +0000 Subject: [PATCH 057/124] [Jenkins release job] README.md updated by release build 5.3.1.Final --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2b4f9f4b28..b55d4a85d2 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Hibernate Validator -*Version: 5.3.0.Final - 11-10-2016* +*Version: 5.3.1.Final - 27-10-2016* ## What is it? @@ -35,7 +35,7 @@ Logging will delegate any log requests to that provider. org.hibernate hibernate-validator - 5.3.0.Final + 5.3.1.Final You also need an API and implementation of the Unified Expression Language. These dependencies must be explicitly added in an SE environment. @@ -59,7 +59,7 @@ extension by adding the following dependency: org.hibernate hibernate-validator-cdi - 5.3.0.Final + 5.3.1.Final * _hibernate-validator-annotation-processor-<version>.jar_ is an optional jar which can be integrated with your build From 5d1938e1a33176cfb5d0836d32c33342408c6426 Mon Sep 17 00:00:00 2001 From: Jenkins Date: Thu, 27 Oct 2016 14:26:18 +0000 Subject: [PATCH 058/124] [Jenkins release job] changelog.txt updated by release build 5.3.1.Final --- changelog.txt | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/changelog.txt b/changelog.txt index 9ac0436859..16fdd2d699 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,6 +1,26 @@ Hibernate Validator Changelog ============================= +5.3.1.Final (27-10-2016) +------------------------- + +** Bug + * HV-1140 - engine - StringHelper#decapitalize not working properly on turkish locale + * HV-1134 - documentation - Asciidoc Docbook processing is missing the sourcedir attribute + * HV-1132 - documentation - Force language in documentation tests + * HV-1131 - engine - EL once again a hard requirement + * HV-1032 - engine - Infinite Loop when validating custom type constraint under certain inheritance scheme + * HV-1002 - engine - validateProperty() behaviour for prop paths with a Set/ List inconsistent with validateValue() + +** Improvement + * HV-1130 - build - Ensure 5.3 runs on JDK 9 + * HV-1129 - tests - Upgrade WildFly Arquillian version + * HV-1128 - tests - Enable integration tests on JDK 9 + * HV-1126 - build - Upgrade the plexus-archiver dependency used by the assembly plugin to support JDK9 + +** Task + * HV-1125 - build - Latest Java 9 preview builds need --add-modules instead of -addmods as build option + 5.3.0.Final (11-10-2016) ------------------------- From 823b6764b690ba04017f4bb6062e5c67648c46bb Mon Sep 17 00:00:00 2001 From: Jenkins Date: Thu, 27 Oct 2016 14:26:37 +0000 Subject: [PATCH 059/124] [Jenkins release job] Preparing release 5.3.1.Final --- annotation-processor/pom.xml | 2 +- build-config/pom.xml | 2 +- cdi/pom.xml | 2 +- distribution/pom.xml | 2 +- documentation/pom.xml | 2 +- engine-jdk8-tests/pom.xml | 2 +- engine/pom.xml | 2 +- integration/pom.xml | 2 +- osgi/integrationtest/pom.xml | 2 +- osgi/karaf-features/pom.xml | 2 +- osgi/pom.xml | 2 +- performance/pom.xml | 2 +- pom.xml | 2 +- tck-runner/pom.xml | 2 +- test-utils/pom.xml | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/annotation-processor/pom.xml b/annotation-processor/pom.xml index 3ff2c1c21c..eec8a30fa1 100644 --- a/annotation-processor/pom.xml +++ b/annotation-processor/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.1-SNAPSHOT + 5.3.1.Final ../pom.xml diff --git a/build-config/pom.xml b/build-config/pom.xml index 1573ff17cd..769bbead90 100644 --- a/build-config/pom.xml +++ b/build-config/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.1-SNAPSHOT + 5.3.1.Final ../pom.xml diff --git a/cdi/pom.xml b/cdi/pom.xml index 3e4c9b07c5..ee300195b5 100644 --- a/cdi/pom.xml +++ b/cdi/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.1-SNAPSHOT + 5.3.1.Final ../pom.xml diff --git a/distribution/pom.xml b/distribution/pom.xml index f83ab5a2b4..24297b0a5a 100644 --- a/distribution/pom.xml +++ b/distribution/pom.xml @@ -10,7 +10,7 @@ hibernate-validator-parent org.hibernate - 5.3.1-SNAPSHOT + 5.3.1.Final ../pom.xml diff --git a/documentation/pom.xml b/documentation/pom.xml index 53605ea186..e465aa9dae 100644 --- a/documentation/pom.xml +++ b/documentation/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.1-SNAPSHOT + 5.3.1.Final ../pom.xml diff --git a/engine-jdk8-tests/pom.xml b/engine-jdk8-tests/pom.xml index 30f525ce31..1309777956 100644 --- a/engine-jdk8-tests/pom.xml +++ b/engine-jdk8-tests/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.1-SNAPSHOT + 5.3.1.Final hibernate-validator-engine-jdk8-tests diff --git a/engine/pom.xml b/engine/pom.xml index 4705851da8..3e5fbfd8da 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.1-SNAPSHOT + 5.3.1.Final ../pom.xml diff --git a/integration/pom.xml b/integration/pom.xml index 28378e0c64..e27982e0d5 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.1-SNAPSHOT + 5.3.1.Final ../pom.xml diff --git a/osgi/integrationtest/pom.xml b/osgi/integrationtest/pom.xml index c11222fd4d..2f496ce2f0 100644 --- a/osgi/integrationtest/pom.xml +++ b/osgi/integrationtest/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-osgi org.hibernate - 5.3.1-SNAPSHOT + 5.3.1.Final ../pom.xml diff --git a/osgi/karaf-features/pom.xml b/osgi/karaf-features/pom.xml index e6a1b5ec53..21ef784e7b 100644 --- a/osgi/karaf-features/pom.xml +++ b/osgi/karaf-features/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-osgi org.hibernate - 5.3.1-SNAPSHOT + 5.3.1.Final ../pom.xml diff --git a/osgi/pom.xml b/osgi/pom.xml index c3740d4437..a73b7d3db1 100644 --- a/osgi/pom.xml +++ b/osgi/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.1-SNAPSHOT + 5.3.1.Final ../pom.xml diff --git a/performance/pom.xml b/performance/pom.xml index bb2b6fb25d..e2e02ca236 100644 --- a/performance/pom.xml +++ b/performance/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.1-SNAPSHOT + 5.3.1.Final ../pom.xml diff --git a/pom.xml b/pom.xml index 6acf9bdcba..a02c1bc076 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.1-SNAPSHOT + 5.3.1.Final pom Hibernate Validator Aggregator diff --git a/tck-runner/pom.xml b/tck-runner/pom.xml index 0b51fec533..e774dfd2a8 100644 --- a/tck-runner/pom.xml +++ b/tck-runner/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.1-SNAPSHOT + 5.3.1.Final ../pom.xml diff --git a/test-utils/pom.xml b/test-utils/pom.xml index 7cec0b6e95..2353395315 100644 --- a/test-utils/pom.xml +++ b/test-utils/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.1-SNAPSHOT + 5.3.1.Final hibernate-validator-test-utils From 699e54ad51dffa11e0c28ab2e70540af1fe714ef Mon Sep 17 00:00:00 2001 From: Jenkins Date: Thu, 27 Oct 2016 14:30:53 +0000 Subject: [PATCH 060/124] [Jenkins release job] Preparing next development iteration --- annotation-processor/pom.xml | 2 +- build-config/pom.xml | 2 +- cdi/pom.xml | 2 +- distribution/pom.xml | 2 +- documentation/pom.xml | 2 +- engine-jdk8-tests/pom.xml | 2 +- engine/pom.xml | 2 +- integration/pom.xml | 2 +- osgi/integrationtest/pom.xml | 2 +- osgi/karaf-features/pom.xml | 2 +- osgi/pom.xml | 2 +- performance/pom.xml | 2 +- pom.xml | 2 +- tck-runner/pom.xml | 2 +- test-utils/pom.xml | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/annotation-processor/pom.xml b/annotation-processor/pom.xml index eec8a30fa1..999a68f6c8 100644 --- a/annotation-processor/pom.xml +++ b/annotation-processor/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.1.Final + 5.3.2-SNAPSHOT ../pom.xml diff --git a/build-config/pom.xml b/build-config/pom.xml index 769bbead90..7475e50adc 100644 --- a/build-config/pom.xml +++ b/build-config/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.1.Final + 5.3.2-SNAPSHOT ../pom.xml diff --git a/cdi/pom.xml b/cdi/pom.xml index ee300195b5..4beb407563 100644 --- a/cdi/pom.xml +++ b/cdi/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.1.Final + 5.3.2-SNAPSHOT ../pom.xml diff --git a/distribution/pom.xml b/distribution/pom.xml index 24297b0a5a..c5615b79d7 100644 --- a/distribution/pom.xml +++ b/distribution/pom.xml @@ -10,7 +10,7 @@ hibernate-validator-parent org.hibernate - 5.3.1.Final + 5.3.2-SNAPSHOT ../pom.xml diff --git a/documentation/pom.xml b/documentation/pom.xml index e465aa9dae..5893a2e2ff 100644 --- a/documentation/pom.xml +++ b/documentation/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.1.Final + 5.3.2-SNAPSHOT ../pom.xml diff --git a/engine-jdk8-tests/pom.xml b/engine-jdk8-tests/pom.xml index 1309777956..15771616fd 100644 --- a/engine-jdk8-tests/pom.xml +++ b/engine-jdk8-tests/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.1.Final + 5.3.2-SNAPSHOT hibernate-validator-engine-jdk8-tests diff --git a/engine/pom.xml b/engine/pom.xml index 3e5fbfd8da..f2efa850a4 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.1.Final + 5.3.2-SNAPSHOT ../pom.xml diff --git a/integration/pom.xml b/integration/pom.xml index e27982e0d5..179b3db8b2 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.1.Final + 5.3.2-SNAPSHOT ../pom.xml diff --git a/osgi/integrationtest/pom.xml b/osgi/integrationtest/pom.xml index 2f496ce2f0..b233c514d0 100644 --- a/osgi/integrationtest/pom.xml +++ b/osgi/integrationtest/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-osgi org.hibernate - 5.3.1.Final + 5.3.2-SNAPSHOT ../pom.xml diff --git a/osgi/karaf-features/pom.xml b/osgi/karaf-features/pom.xml index 21ef784e7b..89630dba8a 100644 --- a/osgi/karaf-features/pom.xml +++ b/osgi/karaf-features/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-osgi org.hibernate - 5.3.1.Final + 5.3.2-SNAPSHOT ../pom.xml diff --git a/osgi/pom.xml b/osgi/pom.xml index a73b7d3db1..360318c8ca 100644 --- a/osgi/pom.xml +++ b/osgi/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.1.Final + 5.3.2-SNAPSHOT ../pom.xml diff --git a/performance/pom.xml b/performance/pom.xml index e2e02ca236..6f68fb68f6 100644 --- a/performance/pom.xml +++ b/performance/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.1.Final + 5.3.2-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index a02c1bc076..19f3eb4a10 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.1.Final + 5.3.2-SNAPSHOT pom Hibernate Validator Aggregator diff --git a/tck-runner/pom.xml b/tck-runner/pom.xml index e774dfd2a8..1bda417b4d 100644 --- a/tck-runner/pom.xml +++ b/tck-runner/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.1.Final + 5.3.2-SNAPSHOT ../pom.xml diff --git a/test-utils/pom.xml b/test-utils/pom.xml index 2353395315..eb0b4e5686 100644 --- a/test-utils/pom.xml +++ b/test-utils/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.1.Final + 5.3.2-SNAPSHOT hibernate-validator-test-utils From 538c72e7160eb0f178a77a310b43125bc6adabc3 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Thu, 10 Nov 2016 14:26:11 +0100 Subject: [PATCH 061/124] HV-1153 Missing javax.el impl should throw a ValidationException --- .../validator/internal/util/logging/Log.java | 4 +- .../ResourceBundleMessageInterpolator.java | 5 +- .../ValidatorFactoryNoELBootstrapTest.java | 103 +++++++++++++++--- 3 files changed, 92 insertions(+), 20 deletions(-) diff --git a/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java b/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java index 7f6a6bdab7..aff3df834f 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java +++ b/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java @@ -604,8 +604,8 @@ UnexpectedTypeException getNoValidatorFoundForTypeException(String constraintTyp ValidationException getNoUnwrapperFoundForTypeException(String typeName); @Message(id = 183, - value = "Unable to load 'javax.el.ExpressionFactory'. Check that you have the EL dependencies on the classpath, or use ParameterMessageInterpolator instead") - ValidationException getMissingELDependenciesException(); + value = "Unable to initialize 'javax.el.ExpressionFactory'. Check that you have the EL dependencies on the classpath, or use ParameterMessageInterpolator instead") + ValidationException getUnableToInitializeELExpressionFactoryException(@Cause Throwable e); @LogMessage(level = WARN) @Message(id = 184, value = "ParameterMessageInterpolator has been chosen, EL interpolation will not be supported") diff --git a/engine/src/main/java/org/hibernate/validator/messageinterpolation/ResourceBundleMessageInterpolator.java b/engine/src/main/java/org/hibernate/validator/messageinterpolation/ResourceBundleMessageInterpolator.java index 63f3465f44..6f327516f0 100644 --- a/engine/src/main/java/org/hibernate/validator/messageinterpolation/ResourceBundleMessageInterpolator.java +++ b/engine/src/main/java/org/hibernate/validator/messageinterpolation/ResourceBundleMessageInterpolator.java @@ -23,6 +23,7 @@ * @author Gunnar Morling * @author Kevin Pollet <kevin.pollet@serli.com> (C) 2011 SERLI * @author Adam Stawicki + * @author Guillaume Smet */ public class ResourceBundleMessageInterpolator extends AbstractMessageInterpolator { @@ -73,9 +74,9 @@ private static ExpressionFactory buildExpressionFactory() { try { return ExpressionFactory.newInstance(); } - catch (NoClassDefFoundError e) { + catch (Throwable e) { // HV-793 - We fail eagerly in case we have no EL dependencies on the classpath - throw LOG.getMissingELDependenciesException(); + throw LOG.getUnableToInitializeELExpressionFactoryException( e ); } } } diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/engine/ValidatorFactoryNoELBootstrapTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/engine/ValidatorFactoryNoELBootstrapTest.java index 36b423dbdd..2171c70e5d 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/engine/ValidatorFactoryNoELBootstrapTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/engine/ValidatorFactoryNoELBootstrapTest.java @@ -6,6 +6,7 @@ */ package org.hibernate.validator.test.internal.engine; +import static org.fest.assertions.Assertions.assertThat; import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertCorrectConstraintViolationMessages; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertTrue; @@ -15,13 +16,19 @@ import java.io.IOException; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.Set; +import javax.el.ExpressionFactory; import javax.validation.ConstraintViolation; import javax.validation.Validation; +import javax.validation.ValidationException; import javax.validation.Validator; import javax.validation.constraints.Min; +import org.hibernate.validator.internal.util.Contracts; +import org.hibernate.validator.internal.util.privilegedactions.GetClassLoader; import org.hibernate.validator.messageinterpolation.ParameterMessageInterpolator; import org.hibernate.validator.testutil.TestForIssue; import org.testng.annotations.Test; @@ -32,10 +39,14 @@ */ public class ValidatorFactoryNoELBootstrapTest { + private final String EL_PACKAGE_PREFIX = "javax.el"; + + private final String EL_IMPL_PACKAGE_PREFIX = "com.sun.el"; + @Test @TestForIssue(jiraKey = "HV-793") public void bootstrapFailsWhenUsingDefaultInterpolatorWithoutExpressionFactory() throws Throwable { - runWithoutElLibs( BootstrapFailsWhenUsingDefaultInterpolatorWithoutExpressionFactory.class ); + runWithoutElLibs( BootstrapFailsWhenUsingDefaultInterpolatorWithoutExpressionFactory.class, EL_PACKAGE_PREFIX ); } public static class BootstrapFailsWhenUsingDefaultInterpolatorWithoutExpressionFactory { @@ -46,8 +57,9 @@ public void run() { fail( "An exception should have been thrown" ); } catch (Throwable e) { + assertThat( e ).isInstanceOf( ValidationException.class ); assertTrue( - getRootCause( e ).getMessage().startsWith( "HV000183" ), + e.getMessage().startsWith( "HV000183" ), "Bootstrapping in Validation should throw an unexpected exception: " + e.getMessage() ); } @@ -57,7 +69,7 @@ public void run() { @Test @TestForIssue(jiraKey = "HV-1131") public void canUseParameterInterpolatorWithoutExpressionFactory() throws Throwable { - runWithoutElLibs( CanUseParameterInterpolatorWithoutExpressionFactory.class ); + runWithoutElLibs( CanUseParameterInterpolatorWithoutExpressionFactory.class, EL_PACKAGE_PREFIX ); } public static class CanUseParameterInterpolatorWithoutExpressionFactory { @@ -76,6 +88,29 @@ public void run() { } } + @Test + @TestForIssue(jiraKey = "HV-1153") + public void missingImplementationThrowsValidationException() throws Throwable { + runWithoutElLibs( MissingImplementationThrowsValidationException.class, EL_IMPL_PACKAGE_PREFIX ); + } + + public static class MissingImplementationThrowsValidationException { + + public void run() { + try { + Validation.buildDefaultValidatorFactory(); + fail( "An exception should have been thrown" ); + } + catch (Throwable e) { + assertThat( e ).isInstanceOf( ValidationException.class ); + assertTrue( + e.getMessage().startsWith( "HV000183" ), + "Bootstrapping in Validation should throw an unexpected exception: " + e.getMessage() + ); + } + } + } + public static class SomeBean { @Min(42) @@ -88,7 +123,6 @@ public static class SomeBean { * classpath. */ private static class ELIgnoringClassLoader extends ClassLoader { - private final String EL_PACKAGE_PREFIX = "javax.el"; private final String[] PASS_THROUGH_PACKAGE_PREFIXES = new String[] { "java.", "javax.xml.", @@ -98,14 +132,17 @@ private static class ELIgnoringClassLoader extends ClassLoader { "jdk.internal" }; - public ELIgnoringClassLoader() { + private final String packageMissing; + + public ELIgnoringClassLoader( String packageMissing ) { super( ELIgnoringClassLoader.class.getClassLoader() ); + this.packageMissing = packageMissing; } @Override public Class loadClass(String className) throws ClassNotFoundException { // This is what we in the end want to achieve. Throw ClassNotFoundException for javax.el classes - if ( className.startsWith( EL_PACKAGE_PREFIX ) ) { + if ( className.startsWith( packageMissing ) ) { throw new ClassNotFoundException(); } @@ -179,24 +216,58 @@ private byte[] loadClassData(String className) throws IOException, ClassNotFound /** * Loads the given class using the EL-ignoring class loader and executes it. + * + * We need to override the Thread context class loader temporarily as {@link javax.el.FactoryFinder} is directly using it to load the + * {@link ExpressionFactory} in {@link ExpressionFactory#newInstance(java.util.Properties)}. */ - private void runWithoutElLibs(Class delegateType) throws Throwable { + private void runWithoutElLibs(Class delegateType, String packageMissing) throws Throwable { try { - Object test = new ELIgnoringClassLoader().loadClass( delegateType.getName() ).newInstance(); - test.getClass().getMethod( "run" ).invoke( test ); + ClassLoader originClassLoader = run( GetClassLoader.fromContext() ); + try { + ClassLoader classLoader = new ELIgnoringClassLoader( packageMissing ); + run( SetClassLoader.ofContext( classLoader ) ); + + Object test = classLoader.loadClass( delegateType.getName() ).newInstance(); + test.getClass().getMethod( "run" ).invoke( test ); + } + finally { + run( SetClassLoader.ofContext( originClassLoader ) ); + } } catch (InvocationTargetException ite) { throw ite.getCause(); } } - private static Throwable getRootCause(Throwable throwable) { - while ( true ) { - Throwable cause = throwable.getCause(); - if ( cause == null ) { - return throwable; - } - throwable = cause; + /** + * Runs the given privileged action, using a privileged block if required. + *

+ * NOTE: This must never be changed into a publicly available method to avoid execution of arbitrary + * privileged actions within HV's protection domain. + */ + private T run(PrivilegedAction action) { + return System.getSecurityManager() != null ? AccessController.doPrivileged( action ) : action.run(); + } + + /** + * Privileged action used to set the Thread context class loader. + */ + private static final class SetClassLoader implements PrivilegedAction { + private final ClassLoader classLoader; + + public static SetClassLoader ofContext(ClassLoader classLoader) { + Contracts.assertNotNull( classLoader, "class loader must not be null" ); + return new SetClassLoader( classLoader ); + } + + private SetClassLoader(ClassLoader classLoader) { + this.classLoader = classLoader; + } + + @Override + public Void run() { + Thread.currentThread().setContextClassLoader( classLoader ); + return null; } } } From 067d8ca175dd9e7dc18b77c0bd9deabd68807b08 Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Tue, 8 Nov 2016 10:35:11 +0100 Subject: [PATCH 062/124] HV-1154 Allowing documentation build to pass on JDK 9 by * upgrading used JRuby version * amending Surefire arg line with required module exports --- cdi/pom.xml | 7 ------- documentation/pom.xml | 14 ++++++++------ engine/pom.xml | 1 - pom.xml | 9 +++++++-- tck-runner/pom.xml | 1 - 5 files changed, 15 insertions(+), 17 deletions(-) diff --git a/cdi/pom.xml b/cdi/pom.xml index 4beb407563..0f0d334039 100644 --- a/cdi/pom.xml +++ b/cdi/pom.xml @@ -174,13 +174,6 @@ - - org.apache.maven.plugins - maven-surefire-plugin - - ${surefire.argLine.extension} - - org.apache.maven.plugins maven-surefire-report-plugin diff --git a/documentation/pom.xml b/documentation/pom.xml index 5893a2e2ff..4fd9733ad2 100644 --- a/documentation/pom.xml +++ b/documentation/pom.xml @@ -25,6 +25,7 @@ false true + -Duser.language=en @@ -95,6 +96,13 @@ + + + org.jruby + jruby-complete + 1.7.26 + + org.apache.maven.plugins @@ -117,12 +125,6 @@ - - maven-surefire-plugin - - -Duser.language=en - - diff --git a/engine/pom.xml b/engine/pom.xml index f2efa850a4..ba2ef03f5e 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -235,7 +235,6 @@ methods 4 - ${surefire.argLine.extension} diff --git a/pom.xml b/pom.xml index 19f3eb4a10..f4d050174a 100644 --- a/pom.xml +++ b/pom.xml @@ -132,8 +132,12 @@ --> 2.18.1 - + + + + + java.xml.bind @@ -487,6 +491,7 @@ **/*Test.java + ${surefire.argLine} ${surefire.argLine.extension} @@ -874,7 +879,7 @@ 9 - --add-modules java.xml.bind + --add-modules ${jigsaw.modules} diff --git a/tck-runner/pom.xml b/tck-runner/pom.xml index 1bda417b4d..3924185bb7 100644 --- a/tck-runner/pom.xml +++ b/tck-runner/pom.xml @@ -217,7 +217,6 @@ true - ${surefire.argLine} ${surefire.argLine.extension} From 656d89bbc2aba993ddc149053c1e0e960ac6ba2b Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Tue, 8 Nov 2016 10:36:01 +0100 Subject: [PATCH 063/124] HV-1154 Making distribution build work on JDK 9 by adding required "--add-modules" to javadoc execution --- distribution/pom.xml | 13 +++++++++++++ .../main/java/org/hibernate/validator/overview.html | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/distribution/pom.xml b/distribution/pom.xml index c5615b79d7..9f64c35922 100644 --- a/distribution/pom.xml +++ b/distribution/pom.xml @@ -23,6 +23,7 @@ true false + @@ -131,6 +132,7 @@ org.hibernate.validator.ap* + ${javadoc.additional.param} @@ -164,4 +166,15 @@ + + + jdk9 + + 9 + + + --add-modules=${jigsaw.modules} + + + diff --git a/engine/src/main/java/org/hibernate/validator/overview.html b/engine/src/main/java/org/hibernate/validator/overview.html index 9006149641..2f9e125a9b 100644 --- a/engine/src/main/java/org/hibernate/validator/overview.html +++ b/engine/src/main/java/org/hibernate/validator/overview.html @@ -14,6 +14,7 @@

All classes fall into three categories: +

  • spi: Classes with spi in the package name are service provider interfaces intended to be implemented or extended by users of Hibernate Validator. @@ -26,6 +27,5 @@ extended by users. If changes to this classes are necessary there will be a deprecation first.
-

From 2b949b74b0bd9512d42cb459ca4ea571e92dda97 Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Tue, 8 Nov 2016 13:05:21 +0100 Subject: [PATCH 064/124] HV-1154 Removing superfluous suite file; only using parallelism on tests level; The presence of the suite file suppressed the parallel=methods config. Removing the file makes the parallel config kick in which made some tests fail that aren't prepared for parallel execution on the method level. The same issue would have appeared before when running a single test via "-Dtest=..." as in that case also the parallel config was applied. --- engine/pom.xml | 5 +---- engine/src/test/suite/unit-tests.xml | 9 --------- 2 files changed, 1 insertion(+), 13 deletions(-) delete mode 100644 engine/src/test/suite/unit-tests.xml diff --git a/engine/pom.xml b/engine/pom.xml index ba2ef03f5e..4e8e9fc245 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -230,10 +230,7 @@ org.apache.maven.plugins maven-surefire-plugin - - ${basedir}/src/test/suite/unit-tests.xml - - methods + tests 4 diff --git a/engine/src/test/suite/unit-tests.xml b/engine/src/test/suite/unit-tests.xml deleted file mode 100644 index cbb98ec4e7..0000000000 --- a/engine/src/test/suite/unit-tests.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - From 7c73ab28b226d107909bb3f90c506c413aee2f97 Mon Sep 17 00:00:00 2001 From: Jenkins Date: Thu, 10 Nov 2016 16:33:32 +0000 Subject: [PATCH 065/124] [Jenkins release job] README.md updated by release build 5.3.2.Final --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b55d4a85d2..faa958680e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Hibernate Validator -*Version: 5.3.1.Final - 27-10-2016* +*Version: 5.3.2.Final - 10-11-2016* ## What is it? @@ -35,7 +35,7 @@ Logging will delegate any log requests to that provider. org.hibernate hibernate-validator - 5.3.1.Final + 5.3.2.Final You also need an API and implementation of the Unified Expression Language. These dependencies must be explicitly added in an SE environment. @@ -59,7 +59,7 @@ extension by adding the following dependency: org.hibernate hibernate-validator-cdi - 5.3.1.Final + 5.3.2.Final * _hibernate-validator-annotation-processor-<version>.jar_ is an optional jar which can be integrated with your build From 439d4a2a807096f831223f298ad989838a826250 Mon Sep 17 00:00:00 2001 From: Jenkins Date: Thu, 10 Nov 2016 16:33:32 +0000 Subject: [PATCH 066/124] [Jenkins release job] changelog.txt updated by release build 5.3.2.Final --- changelog.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/changelog.txt b/changelog.txt index 16fdd2d699..e731916739 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,6 +1,15 @@ Hibernate Validator Changelog ============================= +5.3.2.Final (10-11-2016) +------------------------- + +** Bug + * HV-1153 - engine - Missing javax.el impl throws a javax.el.ELException instead of a ValidationException + +** Improvement + * HV-1154 - build - Make distribution and documentation buildable with JDK9 + 5.3.1.Final (27-10-2016) ------------------------- From dc07a58ed8673960227c6a9d9c9851a8b2407146 Mon Sep 17 00:00:00 2001 From: Jenkins Date: Thu, 10 Nov 2016 16:33:45 +0000 Subject: [PATCH 067/124] [Jenkins release job] Preparing release 5.3.2.Final --- annotation-processor/pom.xml | 2 +- build-config/pom.xml | 2 +- cdi/pom.xml | 2 +- distribution/pom.xml | 2 +- documentation/pom.xml | 2 +- engine-jdk8-tests/pom.xml | 2 +- engine/pom.xml | 2 +- integration/pom.xml | 2 +- osgi/integrationtest/pom.xml | 2 +- osgi/karaf-features/pom.xml | 2 +- osgi/pom.xml | 2 +- performance/pom.xml | 2 +- pom.xml | 2 +- tck-runner/pom.xml | 2 +- test-utils/pom.xml | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/annotation-processor/pom.xml b/annotation-processor/pom.xml index 999a68f6c8..f25c358cca 100644 --- a/annotation-processor/pom.xml +++ b/annotation-processor/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.2-SNAPSHOT + 5.3.2.Final ../pom.xml diff --git a/build-config/pom.xml b/build-config/pom.xml index 7475e50adc..8774a92f8a 100644 --- a/build-config/pom.xml +++ b/build-config/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.2-SNAPSHOT + 5.3.2.Final ../pom.xml diff --git a/cdi/pom.xml b/cdi/pom.xml index 0f0d334039..8aca614bab 100644 --- a/cdi/pom.xml +++ b/cdi/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.2-SNAPSHOT + 5.3.2.Final ../pom.xml diff --git a/distribution/pom.xml b/distribution/pom.xml index 9f64c35922..792575f35d 100644 --- a/distribution/pom.xml +++ b/distribution/pom.xml @@ -10,7 +10,7 @@ hibernate-validator-parent org.hibernate - 5.3.2-SNAPSHOT + 5.3.2.Final ../pom.xml diff --git a/documentation/pom.xml b/documentation/pom.xml index 4fd9733ad2..5d119dabf1 100644 --- a/documentation/pom.xml +++ b/documentation/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.2-SNAPSHOT + 5.3.2.Final ../pom.xml diff --git a/engine-jdk8-tests/pom.xml b/engine-jdk8-tests/pom.xml index 15771616fd..1371d702f5 100644 --- a/engine-jdk8-tests/pom.xml +++ b/engine-jdk8-tests/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.2-SNAPSHOT + 5.3.2.Final hibernate-validator-engine-jdk8-tests diff --git a/engine/pom.xml b/engine/pom.xml index 4e8e9fc245..c01e6be1ed 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.2-SNAPSHOT + 5.3.2.Final ../pom.xml diff --git a/integration/pom.xml b/integration/pom.xml index 179b3db8b2..326a056a5e 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.2-SNAPSHOT + 5.3.2.Final ../pom.xml diff --git a/osgi/integrationtest/pom.xml b/osgi/integrationtest/pom.xml index b233c514d0..a06e68aec4 100644 --- a/osgi/integrationtest/pom.xml +++ b/osgi/integrationtest/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-osgi org.hibernate - 5.3.2-SNAPSHOT + 5.3.2.Final ../pom.xml diff --git a/osgi/karaf-features/pom.xml b/osgi/karaf-features/pom.xml index 89630dba8a..b8e8abe332 100644 --- a/osgi/karaf-features/pom.xml +++ b/osgi/karaf-features/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-osgi org.hibernate - 5.3.2-SNAPSHOT + 5.3.2.Final ../pom.xml diff --git a/osgi/pom.xml b/osgi/pom.xml index 360318c8ca..7ba396b8ac 100644 --- a/osgi/pom.xml +++ b/osgi/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.2-SNAPSHOT + 5.3.2.Final ../pom.xml diff --git a/performance/pom.xml b/performance/pom.xml index 6f68fb68f6..2f4fbd5791 100644 --- a/performance/pom.xml +++ b/performance/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.2-SNAPSHOT + 5.3.2.Final ../pom.xml diff --git a/pom.xml b/pom.xml index f4d050174a..b8ad880059 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.2-SNAPSHOT + 5.3.2.Final pom Hibernate Validator Aggregator diff --git a/tck-runner/pom.xml b/tck-runner/pom.xml index 3924185bb7..f8b2d40227 100644 --- a/tck-runner/pom.xml +++ b/tck-runner/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.2-SNAPSHOT + 5.3.2.Final ../pom.xml diff --git a/test-utils/pom.xml b/test-utils/pom.xml index eb0b4e5686..58bced7d88 100644 --- a/test-utils/pom.xml +++ b/test-utils/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.2-SNAPSHOT + 5.3.2.Final hibernate-validator-test-utils From 7cda7e4d04bff7c2083699880529af7c5c4c0485 Mon Sep 17 00:00:00 2001 From: Jenkins Date: Thu, 10 Nov 2016 16:38:07 +0000 Subject: [PATCH 068/124] [Jenkins release job] Preparing next development iteration --- annotation-processor/pom.xml | 2 +- build-config/pom.xml | 2 +- cdi/pom.xml | 2 +- distribution/pom.xml | 2 +- documentation/pom.xml | 2 +- engine-jdk8-tests/pom.xml | 2 +- engine/pom.xml | 2 +- integration/pom.xml | 2 +- osgi/integrationtest/pom.xml | 2 +- osgi/karaf-features/pom.xml | 2 +- osgi/pom.xml | 2 +- performance/pom.xml | 2 +- pom.xml | 2 +- tck-runner/pom.xml | 2 +- test-utils/pom.xml | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/annotation-processor/pom.xml b/annotation-processor/pom.xml index f25c358cca..5746771af8 100644 --- a/annotation-processor/pom.xml +++ b/annotation-processor/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.2.Final + 5.3.3-SNAPSHOT ../pom.xml diff --git a/build-config/pom.xml b/build-config/pom.xml index 8774a92f8a..0b13cf5895 100644 --- a/build-config/pom.xml +++ b/build-config/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.2.Final + 5.3.3-SNAPSHOT ../pom.xml diff --git a/cdi/pom.xml b/cdi/pom.xml index 8aca614bab..38b090366f 100644 --- a/cdi/pom.xml +++ b/cdi/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.2.Final + 5.3.3-SNAPSHOT ../pom.xml diff --git a/distribution/pom.xml b/distribution/pom.xml index 792575f35d..616648d725 100644 --- a/distribution/pom.xml +++ b/distribution/pom.xml @@ -10,7 +10,7 @@ hibernate-validator-parent org.hibernate - 5.3.2.Final + 5.3.3-SNAPSHOT ../pom.xml diff --git a/documentation/pom.xml b/documentation/pom.xml index 5d119dabf1..b9786c80f1 100644 --- a/documentation/pom.xml +++ b/documentation/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.2.Final + 5.3.3-SNAPSHOT ../pom.xml diff --git a/engine-jdk8-tests/pom.xml b/engine-jdk8-tests/pom.xml index 1371d702f5..44ebd9822e 100644 --- a/engine-jdk8-tests/pom.xml +++ b/engine-jdk8-tests/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.2.Final + 5.3.3-SNAPSHOT hibernate-validator-engine-jdk8-tests diff --git a/engine/pom.xml b/engine/pom.xml index c01e6be1ed..1bd0f1b3c9 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.2.Final + 5.3.3-SNAPSHOT ../pom.xml diff --git a/integration/pom.xml b/integration/pom.xml index 326a056a5e..ed50418819 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.2.Final + 5.3.3-SNAPSHOT ../pom.xml diff --git a/osgi/integrationtest/pom.xml b/osgi/integrationtest/pom.xml index a06e68aec4..0977ef6e85 100644 --- a/osgi/integrationtest/pom.xml +++ b/osgi/integrationtest/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-osgi org.hibernate - 5.3.2.Final + 5.3.3-SNAPSHOT ../pom.xml diff --git a/osgi/karaf-features/pom.xml b/osgi/karaf-features/pom.xml index b8e8abe332..0e8e1a0b0d 100644 --- a/osgi/karaf-features/pom.xml +++ b/osgi/karaf-features/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-osgi org.hibernate - 5.3.2.Final + 5.3.3-SNAPSHOT ../pom.xml diff --git a/osgi/pom.xml b/osgi/pom.xml index 7ba396b8ac..edb1dcc1b0 100644 --- a/osgi/pom.xml +++ b/osgi/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.2.Final + 5.3.3-SNAPSHOT ../pom.xml diff --git a/performance/pom.xml b/performance/pom.xml index 2f4fbd5791..506590aaec 100644 --- a/performance/pom.xml +++ b/performance/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.2.Final + 5.3.3-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index b8ad880059..20a71f7024 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.2.Final + 5.3.3-SNAPSHOT pom Hibernate Validator Aggregator diff --git a/tck-runner/pom.xml b/tck-runner/pom.xml index f8b2d40227..9331cd8f36 100644 --- a/tck-runner/pom.xml +++ b/tck-runner/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.2.Final + 5.3.3-SNAPSHOT ../pom.xml diff --git a/test-utils/pom.xml b/test-utils/pom.xml index 58bced7d88..ed9a2c166d 100644 --- a/test-utils/pom.xml +++ b/test-utils/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.2.Final + 5.3.3-SNAPSHOT hibernate-validator-test-utils From 2830ccb4232477b53366994ef2f9dc325ccbaa5b Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Sun, 20 Nov 2016 17:56:04 +0100 Subject: [PATCH 069/124] HV-1155 Move SetContextClassLoader privileged action to a shared package --- .../SetContextClassLoader.java | 35 +++++++++++++++++++ .../ValidatorFactoryNoELBootstrapTest.java | 28 ++------------- 2 files changed, 38 insertions(+), 25 deletions(-) create mode 100644 engine/src/main/java/org/hibernate/validator/internal/util/privilegedactions/SetContextClassLoader.java diff --git a/engine/src/main/java/org/hibernate/validator/internal/util/privilegedactions/SetContextClassLoader.java b/engine/src/main/java/org/hibernate/validator/internal/util/privilegedactions/SetContextClassLoader.java new file mode 100644 index 0000000000..f96c2562bd --- /dev/null +++ b/engine/src/main/java/org/hibernate/validator/internal/util/privilegedactions/SetContextClassLoader.java @@ -0,0 +1,35 @@ +/* + * Hibernate Validator, declare and validate application constraints + * + * License: Apache License, Version 2.0 + * See the license.txt file in the root directory or . + */ +package org.hibernate.validator.internal.util.privilegedactions; + +import java.security.PrivilegedAction; + +import org.hibernate.validator.internal.util.Contracts; + +/** + * Privileged action used to set the Thread context class loader. + * + * @author Guillaume Smet + */ +public final class SetContextClassLoader implements PrivilegedAction { + private final ClassLoader classLoader; + + public static SetContextClassLoader action(ClassLoader classLoader) { + Contracts.assertNotNull( classLoader, "class loader must not be null" ); + return new SetContextClassLoader( classLoader ); + } + + private SetContextClassLoader(ClassLoader classLoader) { + this.classLoader = classLoader; + } + + @Override + public Void run() { + Thread.currentThread().setContextClassLoader( classLoader ); + return null; + } +} diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/engine/ValidatorFactoryNoELBootstrapTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/engine/ValidatorFactoryNoELBootstrapTest.java index 2171c70e5d..13a1841627 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/engine/ValidatorFactoryNoELBootstrapTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/engine/ValidatorFactoryNoELBootstrapTest.java @@ -27,8 +27,8 @@ import javax.validation.Validator; import javax.validation.constraints.Min; -import org.hibernate.validator.internal.util.Contracts; import org.hibernate.validator.internal.util.privilegedactions.GetClassLoader; +import org.hibernate.validator.internal.util.privilegedactions.SetContextClassLoader; import org.hibernate.validator.messageinterpolation.ParameterMessageInterpolator; import org.hibernate.validator.testutil.TestForIssue; import org.testng.annotations.Test; @@ -225,13 +225,13 @@ private void runWithoutElLibs(Class delegateType, String packageMissing) thro ClassLoader originClassLoader = run( GetClassLoader.fromContext() ); try { ClassLoader classLoader = new ELIgnoringClassLoader( packageMissing ); - run( SetClassLoader.ofContext( classLoader ) ); + run( SetContextClassLoader.action( classLoader ) ); Object test = classLoader.loadClass( delegateType.getName() ).newInstance(); test.getClass().getMethod( "run" ).invoke( test ); } finally { - run( SetClassLoader.ofContext( originClassLoader ) ); + run( SetContextClassLoader.action( originClassLoader ) ); } } catch (InvocationTargetException ite) { @@ -248,26 +248,4 @@ private void runWithoutElLibs(Class delegateType, String packageMissing) thro private T run(PrivilegedAction action) { return System.getSecurityManager() != null ? AccessController.doPrivileged( action ) : action.run(); } - - /** - * Privileged action used to set the Thread context class loader. - */ - private static final class SetClassLoader implements PrivilegedAction { - private final ClassLoader classLoader; - - public static SetClassLoader ofContext(ClassLoader classLoader) { - Contracts.assertNotNull( classLoader, "class loader must not be null" ); - return new SetClassLoader( classLoader ); - } - - private SetClassLoader(ClassLoader classLoader) { - this.classLoader = classLoader; - } - - @Override - public Void run() { - Thread.currentThread().setContextClassLoader( classLoader ); - return null; - } - } } From 55c091e71fd7a187e813e71132e22a5e88466606 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Sun, 20 Nov 2016 18:21:03 +0100 Subject: [PATCH 070/124] HV-1155 Upgrade pax-exam to 4.9.2 It apparently has a stricter classloading and allows us to check OSGi classloading issues. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 20a71f7024..2bd700bd33 100644 --- a/pom.xml +++ b/pom.xml @@ -119,7 +119,7 @@ 1.1.11.Final - 4.8.0 + 4.9.2 2.4.7 3.0.6 6.0.0 From c3e07001d7894d738e6f8e63e9ddcec54feeb7db Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Sun, 20 Nov 2016 18:02:09 +0100 Subject: [PATCH 071/124] HV-1155 Fall back to the HV class loader if no ExpressionFactory impl is found in the TCCL --- .../ResourceBundleMessageInterpolator.java | 36 +++++++++++++++++++ .../integrationtest/OsgiIntegrationTest.java | 12 ++++++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/engine/src/main/java/org/hibernate/validator/messageinterpolation/ResourceBundleMessageInterpolator.java b/engine/src/main/java/org/hibernate/validator/messageinterpolation/ResourceBundleMessageInterpolator.java index 6f327516f0..94f48e4cb0 100644 --- a/engine/src/main/java/org/hibernate/validator/messageinterpolation/ResourceBundleMessageInterpolator.java +++ b/engine/src/main/java/org/hibernate/validator/messageinterpolation/ResourceBundleMessageInterpolator.java @@ -6,6 +6,8 @@ */ package org.hibernate.validator.messageinterpolation; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.Locale; import javax.el.ExpressionFactory; @@ -13,6 +15,8 @@ import org.hibernate.validator.internal.engine.messageinterpolation.InterpolationTerm; import org.hibernate.validator.internal.util.logging.Log; import org.hibernate.validator.internal.util.logging.LoggerFactory; +import org.hibernate.validator.internal.util.privilegedactions.GetClassLoader; +import org.hibernate.validator.internal.util.privilegedactions.SetContextClassLoader; import org.hibernate.validator.spi.resourceloading.ResourceBundleLocator; /** @@ -70,13 +74,45 @@ public String interpolate(Context context, Locale locale, String term) { return expression.interpolate( context ); } + /** + * The javax.el FactoryFinder uses the TCCL to load the {@link ExpressionFactory} implementation so we need to be + * extra careful when initializing it. + * + * @return the {@link ExpressionFactory} + */ private static ExpressionFactory buildExpressionFactory() { + // First, we try to load the instance from the TCCL. try { return ExpressionFactory.newInstance(); } + catch (Throwable e) { + // we ignore the error in this case as we will try the Hibernate Validator class loader. + } + + // Then we try the Hibernate Validator class loader. In a fully-functional modular environment such as + // WildFly or Jigsaw, it is the way to go. + final ClassLoader originalContextClassLoader = run( GetClassLoader.fromContext() ); + + try { + run( SetContextClassLoader.action( ResourceBundleMessageInterpolator.class.getClassLoader() ) ); + return ExpressionFactory.newInstance(); + } catch (Throwable e) { // HV-793 - We fail eagerly in case we have no EL dependencies on the classpath throw LOG.getUnableToInitializeELExpressionFactoryException( e ); } + finally { + run( SetContextClassLoader.action( originalContextClassLoader ) ); + } + } + + /** + * Runs the given privileged action, using a privileged block if required. + *

+ * NOTE: This must never be changed into a publicly available method to avoid execution of arbitrary + * privileged actions within HV's protection domain. + */ + private static T run(PrivilegedAction action) { + return System.getSecurityManager() != null ? AccessController.doPrivileged( action ) : action.run(); } } diff --git a/osgi/integrationtest/src/test/java/org/hibernate/validator/osgi/integrationtest/OsgiIntegrationTest.java b/osgi/integrationtest/src/test/java/org/hibernate/validator/osgi/integrationtest/OsgiIntegrationTest.java index db44ac2521..930c69728d 100644 --- a/osgi/integrationtest/src/test/java/org/hibernate/validator/osgi/integrationtest/OsgiIntegrationTest.java +++ b/osgi/integrationtest/src/test/java/org/hibernate/validator/osgi/integrationtest/OsgiIntegrationTest.java @@ -108,6 +108,8 @@ public static void setLocaleToEnglish() { @Test public void canObtainValidatorFactoryAndPerformValidation() { + Thread.currentThread().setContextClassLoader( getClass().getClassLoader() ); + Set> constraintViolations = Validation.byDefaultProvider() .providerResolver( new MyValidationProviderResolver() ) .configure() @@ -116,11 +118,13 @@ public void canObtainValidatorFactoryAndPerformValidation() { .validate( new Customer() ); assertEquals( 1, constraintViolations.size() ); - assertEquals( "must be greater than or equal to 1", constraintViolations.iterator().next().getMessage() ); + assertEquals( "must be greater than or equal to 2", constraintViolations.iterator().next().getMessage() ); } @Test public void canConfigureCustomConstraintValidatorFactoryViaValidationXml() { + Thread.currentThread().setContextClassLoader( getClass().getClassLoader() ); + ExampleConstraintValidatorFactory.invocationCounter.set( 0 ); HibernateValidatorConfiguration configuration = Validation.byProvider( HibernateValidator.class ) @@ -146,6 +150,8 @@ public void canConfigureCustomConstraintValidatorFactoryViaValidationXml() { @Test public void canConfigureConstraintViaXmlMapping() { + Thread.currentThread().setContextClassLoader( getClass().getClassLoader() ); + Set> constraintViolations = Validation.byProvider( HibernateValidator.class ) .providerResolver( new MyValidationProviderResolver() ) .configure() @@ -160,6 +166,8 @@ public void canConfigureConstraintViaXmlMapping() { @Test public void canConfigureCustomConstraintViaXmlMapping() { + Thread.currentThread().setContextClassLoader( getClass().getClassLoader() ); + Set> constraintViolations = Validation.byProvider( HibernateValidator.class ) .providerResolver( new MyValidationProviderResolver() ) .configure() @@ -174,6 +182,8 @@ public void canConfigureCustomConstraintViaXmlMapping() { @Test public void canObtainValuesFromValidationMessages() { + Thread.currentThread().setContextClassLoader( getClass().getClassLoader() ); + Set> constraintViolations = Validation.byProvider( HibernateValidator.class ) .providerResolver( new MyValidationProviderResolver() ) .configure() From 91563e0b47a00e7ba387299cf3b6e6d212517d45 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Sun, 20 Nov 2016 18:22:48 +0100 Subject: [PATCH 072/124] HV-1155 If defined, use the externalClassLoader to load the ExpressionFactory --- .../internal/engine/ConfigurationImpl.java | 21 +++++++++--- .../integrationtest/OsgiIntegrationTest.java | 33 +++++++++---------- 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/ConfigurationImpl.java b/engine/src/main/java/org/hibernate/validator/internal/engine/ConfigurationImpl.java index 506c2f2ef9..fba43998ad 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/ConfigurationImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/ConfigurationImpl.java @@ -38,7 +38,9 @@ import org.hibernate.validator.internal.util.Version; import org.hibernate.validator.internal.util.logging.Log; import org.hibernate.validator.internal.util.logging.LoggerFactory; +import org.hibernate.validator.internal.util.privilegedactions.GetClassLoader; import org.hibernate.validator.internal.util.privilegedactions.LoadClass; +import org.hibernate.validator.internal.util.privilegedactions.SetContextClassLoader; import org.hibernate.validator.internal.xml.ValidationBootstrapParameters; import org.hibernate.validator.internal.xml.ValidationXmlParser; import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator; @@ -543,8 +545,12 @@ private boolean isClassPresent(String className, boolean fallbackOnTCCL) { * Returns the default message interpolator, configured with the given user class loader, if present. */ private MessageInterpolator getDefaultMessageInterpolatorConfiguredWithClassLoader() { - return externalClassLoader != null ? - new ResourceBundleMessageInterpolator( + if ( externalClassLoader != null ) { + final ClassLoader originalContextClassLoader = run( GetClassLoader.fromContext() ); + + try { + run( SetContextClassLoader.action( externalClassLoader ) ); + return new ResourceBundleMessageInterpolator( new PlatformResourceBundleLocator( ResourceBundleMessageInterpolator.USER_VALIDATION_MESSAGES, externalClassLoader @@ -554,8 +560,15 @@ private MessageInterpolator getDefaultMessageInterpolatorConfiguredWithClassLoad externalClassLoader, true ) - ) : - getDefaultMessageInterpolator(); + ); + } + finally { + run( SetContextClassLoader.action( originalContextClassLoader ) ); + } + } + else { + return getDefaultMessageInterpolator(); + } } /** diff --git a/osgi/integrationtest/src/test/java/org/hibernate/validator/osgi/integrationtest/OsgiIntegrationTest.java b/osgi/integrationtest/src/test/java/org/hibernate/validator/osgi/integrationtest/OsgiIntegrationTest.java index 930c69728d..3a8b704ffc 100644 --- a/osgi/integrationtest/src/test/java/org/hibernate/validator/osgi/integrationtest/OsgiIntegrationTest.java +++ b/osgi/integrationtest/src/test/java/org/hibernate/validator/osgi/integrationtest/OsgiIntegrationTest.java @@ -108,23 +108,28 @@ public static void setLocaleToEnglish() { @Test public void canObtainValidatorFactoryAndPerformValidation() { - Thread.currentThread().setContextClassLoader( getClass().getClassLoader() ); + ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader(); - Set> constraintViolations = Validation.byDefaultProvider() - .providerResolver( new MyValidationProviderResolver() ) - .configure() - .buildValidatorFactory() - .getValidator() - .validate( new Customer() ); + try { + Thread.currentThread().setContextClassLoader( getClass().getClassLoader() ); - assertEquals( 1, constraintViolations.size() ); - assertEquals( "must be greater than or equal to 2", constraintViolations.iterator().next().getMessage() ); + Set> constraintViolations = Validation.byDefaultProvider() + .providerResolver( new MyValidationProviderResolver() ) + .configure() + .buildValidatorFactory() + .getValidator() + .validate( new Customer() ); + + assertEquals( 1, constraintViolations.size() ); + assertEquals( "must be greater than or equal to 2", constraintViolations.iterator().next().getMessage() ); + } + finally { + Thread.currentThread().setContextClassLoader( originalClassLoader ); + } } @Test public void canConfigureCustomConstraintValidatorFactoryViaValidationXml() { - Thread.currentThread().setContextClassLoader( getClass().getClassLoader() ); - ExampleConstraintValidatorFactory.invocationCounter.set( 0 ); HibernateValidatorConfiguration configuration = Validation.byProvider( HibernateValidator.class ) @@ -150,8 +155,6 @@ public void canConfigureCustomConstraintValidatorFactoryViaValidationXml() { @Test public void canConfigureConstraintViaXmlMapping() { - Thread.currentThread().setContextClassLoader( getClass().getClassLoader() ); - Set> constraintViolations = Validation.byProvider( HibernateValidator.class ) .providerResolver( new MyValidationProviderResolver() ) .configure() @@ -166,8 +169,6 @@ public void canConfigureConstraintViaXmlMapping() { @Test public void canConfigureCustomConstraintViaXmlMapping() { - Thread.currentThread().setContextClassLoader( getClass().getClassLoader() ); - Set> constraintViolations = Validation.byProvider( HibernateValidator.class ) .providerResolver( new MyValidationProviderResolver() ) .configure() @@ -182,8 +183,6 @@ public void canConfigureCustomConstraintViaXmlMapping() { @Test public void canObtainValuesFromValidationMessages() { - Thread.currentThread().setContextClassLoader( getClass().getClassLoader() ); - Set> constraintViolations = Validation.byProvider( HibernateValidator.class ) .providerResolver( new MyValidationProviderResolver() ) .configure() From 6f0da1dfbd1a36f7c02725141cad2f2da3dee9fe Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Mon, 21 Nov 2016 15:25:03 +0100 Subject: [PATCH 073/124] HV-1155 Initialize the ExpressionFactory properly in the ELContext --- .../engine/messageinterpolation/ElTermResolver.java | 2 +- .../messageinterpolation/el/SimpleELContext.java | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/ElTermResolver.java b/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/ElTermResolver.java index 3a99de311f..d1a23d78ec 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/ElTermResolver.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/ElTermResolver.java @@ -59,7 +59,7 @@ public ElTermResolver(Locale locale, ExpressionFactory expressionFactory) { @Override public String interpolate(MessageInterpolator.Context context, String expression) { String resolvedExpression = expression; - SimpleELContext elContext = new SimpleELContext(); + SimpleELContext elContext = new SimpleELContext( expressionFactory ); try { ValueExpression valueExpression = bindContextValues( expression, context, elContext ); resolvedExpression = (String) valueExpression.getValue( elContext ); diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/el/SimpleELContext.java b/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/el/SimpleELContext.java index 321729442b..c739819d2d 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/el/SimpleELContext.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/messageinterpolation/el/SimpleELContext.java @@ -7,11 +7,13 @@ package org.hibernate.validator.internal.engine.messageinterpolation.el; import java.lang.reflect.Method; + import javax.el.ArrayELResolver; import javax.el.BeanELResolver; import javax.el.CompositeELResolver; import javax.el.ELContext; import javax.el.ELResolver; +import javax.el.ExpressionFactory; import javax.el.ListELResolver; import javax.el.MapELResolver; import javax.el.ResourceBundleELResolver; @@ -37,7 +39,14 @@ public class SimpleELContext extends ELContext { private final VariableMapper variableMapper; private final ELResolver resolver; - public SimpleELContext() { + public SimpleELContext(ExpressionFactory expressionFactory) { + // In javax.el.ELContext, the ExpressionFactory is extracted from the context map. If it is not found, it + // defaults to ELUtil.getExpressionFactory() which, if we provided the ExpressionFactory to the + // ResourceBundleMessageInterpolator, might not be the same, thus potentially instantiating another + // ExpressionFactory outside of the boundaries of the class loader safe loading mechanism of + // ResourceBundleMessageInterpolator. + putContext( ExpressionFactory.class, expressionFactory ); + functions = new MapBasedFunctionMapper(); variableMapper = new MapBasedVariableMapper(); resolver = DEFAULT_RESOLVER; From 97dacc2ce4d566276257715379844c7a642bcb9c Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Tue, 22 Nov 2016 09:25:00 +0100 Subject: [PATCH 074/124] HV-1155 Limiting redefinition of TCCL to invocation of RBMI constructor; also * Extending OSGi tests a bit * Adding one note to the docs --- documentation/src/main/asciidoc/ch11.asciidoc | 1 + .../internal/engine/ConfigurationImpl.java | 33 ++++++++------- .../ResourceBundleMessageInterpolator.java | 2 +- .../integrationtest/OsgiIntegrationTest.java | 42 ++++++++++++------- 4 files changed, 49 insertions(+), 29 deletions(-) diff --git a/documentation/src/main/asciidoc/ch11.asciidoc b/documentation/src/main/asciidoc/ch11.asciidoc index 4d817d029e..34a1cde088 100644 --- a/documentation/src/main/asciidoc/ch11.asciidoc +++ b/documentation/src/main/asciidoc/ch11.asciidoc @@ -846,6 +846,7 @@ There are several cases in which Hibernate Validator needs to load resources or * XML descriptors (_META-INF/validation.xml_ as well as XML constraint mappings) * classes specified by name in XML descriptors (e.g. custom message interpolators etc.) * the _ValidationMessages_ resource bundle +* the `ExpressionFactory` implementation used for expression based message interpolation By default Hibernate Validator tries to load these resources via the current thread context classloader. If that's not successful, Hibernate Validator's own classloader will be tried as a fallback. diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/ConfigurationImpl.java b/engine/src/main/java/org/hibernate/validator/internal/engine/ConfigurationImpl.java index fba43998ad..720af5b353 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/ConfigurationImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/ConfigurationImpl.java @@ -6,6 +6,10 @@ */ package org.hibernate.validator.internal.engine; +import static org.hibernate.validator.internal.util.CollectionHelper.newArrayList; +import static org.hibernate.validator.internal.util.CollectionHelper.newHashSet; +import static org.hibernate.validator.internal.util.logging.Messages.MESSAGES; + import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; @@ -50,10 +54,6 @@ import org.hibernate.validator.spi.time.TimeProvider; import org.hibernate.validator.spi.valuehandling.ValidatedValueUnwrapper; -import static org.hibernate.validator.internal.util.CollectionHelper.newArrayList; -import static org.hibernate.validator.internal.util.CollectionHelper.newHashSet; -import static org.hibernate.validator.internal.util.logging.Messages.MESSAGES; - /** * Hibernate specific {@code Configuration} implementation. * @@ -98,7 +98,7 @@ public class ConfigurationImpl implements HibernateValidatorConfiguration, Confi private final List> validatedValueHandlers = newArrayList(); private ClassLoader externalClassLoader; private TimeProvider timeProvider; - private MethodValidationConfiguration methodValidationConfiguration = new MethodValidationConfiguration(); + private final MethodValidationConfiguration methodValidationConfiguration = new MethodValidationConfiguration(); public ConfigurationImpl(BootstrapState state) { this(); @@ -546,20 +546,25 @@ private boolean isClassPresent(String className, boolean fallbackOnTCCL) { */ private MessageInterpolator getDefaultMessageInterpolatorConfiguredWithClassLoader() { if ( externalClassLoader != null ) { + PlatformResourceBundleLocator userResourceBundleLocator = new PlatformResourceBundleLocator( + ResourceBundleMessageInterpolator.USER_VALIDATION_MESSAGES, + externalClassLoader + ); + PlatformResourceBundleLocator contributorResourceBundleLocator = new PlatformResourceBundleLocator( + ResourceBundleMessageInterpolator.CONTRIBUTOR_VALIDATION_MESSAGES, + externalClassLoader, + true + ); + + // Within RBMI, the expression factory implementation is loaded from the TCCL; thus we set the TCCL to the + // given external class loader for this call final ClassLoader originalContextClassLoader = run( GetClassLoader.fromContext() ); try { run( SetContextClassLoader.action( externalClassLoader ) ); return new ResourceBundleMessageInterpolator( - new PlatformResourceBundleLocator( - ResourceBundleMessageInterpolator.USER_VALIDATION_MESSAGES, - externalClassLoader - ), - new PlatformResourceBundleLocator( - ResourceBundleMessageInterpolator.CONTRIBUTOR_VALIDATION_MESSAGES, - externalClassLoader, - true - ) + userResourceBundleLocator, + contributorResourceBundleLocator ); } finally { diff --git a/engine/src/main/java/org/hibernate/validator/messageinterpolation/ResourceBundleMessageInterpolator.java b/engine/src/main/java/org/hibernate/validator/messageinterpolation/ResourceBundleMessageInterpolator.java index 94f48e4cb0..82a4d9d4db 100644 --- a/engine/src/main/java/org/hibernate/validator/messageinterpolation/ResourceBundleMessageInterpolator.java +++ b/engine/src/main/java/org/hibernate/validator/messageinterpolation/ResourceBundleMessageInterpolator.java @@ -81,7 +81,7 @@ public String interpolate(Context context, Locale locale, String term) { * @return the {@link ExpressionFactory} */ private static ExpressionFactory buildExpressionFactory() { - // First, we try to load the instance from the TCCL. + // First, we try to load the instance from the original TCCL. try { return ExpressionFactory.newInstance(); } diff --git a/osgi/integrationtest/src/test/java/org/hibernate/validator/osgi/integrationtest/OsgiIntegrationTest.java b/osgi/integrationtest/src/test/java/org/hibernate/validator/osgi/integrationtest/OsgiIntegrationTest.java index 3a8b704ffc..1af7ed0f8b 100644 --- a/osgi/integrationtest/src/test/java/org/hibernate/validator/osgi/integrationtest/OsgiIntegrationTest.java +++ b/osgi/integrationtest/src/test/java/org/hibernate/validator/osgi/integrationtest/OsgiIntegrationTest.java @@ -6,6 +6,18 @@ */ package org.hibernate.validator.osgi.integrationtest; +import static org.junit.Assert.assertEquals; +import static org.ops4j.pax.exam.CoreOptions.maven; +import static org.ops4j.pax.exam.CoreOptions.options; +import static org.ops4j.pax.exam.CoreOptions.when; +import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.configureConsole; +import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.debugConfiguration; +import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut; +import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.features; +import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.karafDistributionConfiguration; +import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder; +import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.logLevel; + import java.io.File; import java.util.Collections; import java.util.List; @@ -39,18 +51,6 @@ import com.example.Order; import com.example.RetailOrder; -import static org.junit.Assert.assertEquals; -import static org.ops4j.pax.exam.CoreOptions.maven; -import static org.ops4j.pax.exam.CoreOptions.options; -import static org.ops4j.pax.exam.CoreOptions.when; -import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.configureConsole; -import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.debugConfiguration; -import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut; -import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.features; -import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.karafDistributionConfiguration; -import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder; -import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.logLevel; - /** * Integration test for Bean Validation and Hibernate Validator under OSGi. *

@@ -107,7 +107,7 @@ public static void setLocaleToEnglish() { } @Test - public void canObtainValidatorFactoryAndPerformValidation() { + public void canObtainValidatorFactoryAndPerformValidationWithExpressionFactoryFromTccl() { ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader(); try { @@ -128,6 +128,20 @@ public void canObtainValidatorFactoryAndPerformValidation() { } } + @Test + public void canObtainValidatorFactoryAndPerformValidationWithExpressionFactoryFromExternalClassLoader() { + Set> constraintViolations = Validation.byProvider( HibernateValidator.class ) + .providerResolver( new MyValidationProviderResolver() ) + .configure() + .externalClassLoader( getClass().getClassLoader() ) + .buildValidatorFactory() + .getValidator() + .validate( new Customer() ); + + assertEquals( 1, constraintViolations.size() ); + assertEquals( "must be greater than or equal to 2", constraintViolations.iterator().next().getMessage() ); + } + @Test public void canConfigureCustomConstraintValidatorFactoryViaValidationXml() { ExampleConstraintValidatorFactory.invocationCounter.set( 0 ); @@ -196,7 +210,7 @@ public void canObtainValuesFromValidationMessages() { } @Test - public void canUseExpressionLanguageInConstraintMessage() { + public void canUseExpressionLanguageInConstraintMessageWithExternallyConfiguredExpressionFactory() { ExpressionFactory expressionFactory = buildExpressionFactory(); Set> constraintViolations = Validation.byProvider( HibernateValidator.class ) From 22519af8ad8e71c28c55f0814b9519407b4a9b32 Mon Sep 17 00:00:00 2001 From: Jenkins Date: Tue, 22 Nov 2016 17:44:43 +0000 Subject: [PATCH 075/124] [Jenkins release job] README.md updated by release build 5.3.3.Final --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index faa958680e..676d30a656 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Hibernate Validator -*Version: 5.3.2.Final - 10-11-2016* +*Version: 5.3.3.Final - 22-11-2016* ## What is it? @@ -35,7 +35,7 @@ Logging will delegate any log requests to that provider. org.hibernate hibernate-validator - 5.3.2.Final + 5.3.3.Final You also need an API and implementation of the Unified Expression Language. These dependencies must be explicitly added in an SE environment. @@ -59,7 +59,7 @@ extension by adding the following dependency: org.hibernate hibernate-validator-cdi - 5.3.2.Final + 5.3.3.Final * _hibernate-validator-annotation-processor-<version>.jar_ is an optional jar which can be integrated with your build From 81481245c6569af9b89bde946e789395098ca24f Mon Sep 17 00:00:00 2001 From: Jenkins Date: Tue, 22 Nov 2016 17:44:43 +0000 Subject: [PATCH 076/124] [Jenkins release job] changelog.txt updated by release build 5.3.3.Final --- changelog.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/changelog.txt b/changelog.txt index e731916739..ca576f2965 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,6 +1,12 @@ Hibernate Validator Changelog ============================= +5.3.3.Final (22-11-2016) +------------------------- + +** Bug + * HV-1155 - engine - ClassLoader issues in modularized environments + 5.3.2.Final (10-11-2016) ------------------------- From 4d4d5b054f22eecbe006170040c759e221941f64 Mon Sep 17 00:00:00 2001 From: Jenkins Date: Tue, 22 Nov 2016 17:45:12 +0000 Subject: [PATCH 077/124] [Jenkins release job] Preparing release 5.3.3.Final --- annotation-processor/pom.xml | 2 +- build-config/pom.xml | 2 +- cdi/pom.xml | 2 +- distribution/pom.xml | 2 +- documentation/pom.xml | 2 +- engine-jdk8-tests/pom.xml | 2 +- engine/pom.xml | 2 +- integration/pom.xml | 2 +- osgi/integrationtest/pom.xml | 2 +- osgi/karaf-features/pom.xml | 2 +- osgi/pom.xml | 2 +- performance/pom.xml | 2 +- pom.xml | 2 +- tck-runner/pom.xml | 2 +- test-utils/pom.xml | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/annotation-processor/pom.xml b/annotation-processor/pom.xml index 5746771af8..dd097dca02 100644 --- a/annotation-processor/pom.xml +++ b/annotation-processor/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.3-SNAPSHOT + 5.3.3.Final ../pom.xml diff --git a/build-config/pom.xml b/build-config/pom.xml index 0b13cf5895..d99f012c7d 100644 --- a/build-config/pom.xml +++ b/build-config/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.3-SNAPSHOT + 5.3.3.Final ../pom.xml diff --git a/cdi/pom.xml b/cdi/pom.xml index 38b090366f..383d800a92 100644 --- a/cdi/pom.xml +++ b/cdi/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.3-SNAPSHOT + 5.3.3.Final ../pom.xml diff --git a/distribution/pom.xml b/distribution/pom.xml index 616648d725..cd5479ef96 100644 --- a/distribution/pom.xml +++ b/distribution/pom.xml @@ -10,7 +10,7 @@ hibernate-validator-parent org.hibernate - 5.3.3-SNAPSHOT + 5.3.3.Final ../pom.xml diff --git a/documentation/pom.xml b/documentation/pom.xml index b9786c80f1..537d8753c4 100644 --- a/documentation/pom.xml +++ b/documentation/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.3-SNAPSHOT + 5.3.3.Final ../pom.xml diff --git a/engine-jdk8-tests/pom.xml b/engine-jdk8-tests/pom.xml index 44ebd9822e..83542d8d5f 100644 --- a/engine-jdk8-tests/pom.xml +++ b/engine-jdk8-tests/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.3-SNAPSHOT + 5.3.3.Final hibernate-validator-engine-jdk8-tests diff --git a/engine/pom.xml b/engine/pom.xml index 1bd0f1b3c9..bf054fdfb9 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.3-SNAPSHOT + 5.3.3.Final ../pom.xml diff --git a/integration/pom.xml b/integration/pom.xml index ed50418819..af89f46f5a 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.3-SNAPSHOT + 5.3.3.Final ../pom.xml diff --git a/osgi/integrationtest/pom.xml b/osgi/integrationtest/pom.xml index 0977ef6e85..e35e06de9b 100644 --- a/osgi/integrationtest/pom.xml +++ b/osgi/integrationtest/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-osgi org.hibernate - 5.3.3-SNAPSHOT + 5.3.3.Final ../pom.xml diff --git a/osgi/karaf-features/pom.xml b/osgi/karaf-features/pom.xml index 0e8e1a0b0d..451fa178b3 100644 --- a/osgi/karaf-features/pom.xml +++ b/osgi/karaf-features/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-osgi org.hibernate - 5.3.3-SNAPSHOT + 5.3.3.Final ../pom.xml diff --git a/osgi/pom.xml b/osgi/pom.xml index edb1dcc1b0..ca9a8388d8 100644 --- a/osgi/pom.xml +++ b/osgi/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.3-SNAPSHOT + 5.3.3.Final ../pom.xml diff --git a/performance/pom.xml b/performance/pom.xml index 506590aaec..bfaf40f646 100644 --- a/performance/pom.xml +++ b/performance/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.3-SNAPSHOT + 5.3.3.Final ../pom.xml diff --git a/pom.xml b/pom.xml index 2bd700bd33..b41b6d98e7 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.3-SNAPSHOT + 5.3.3.Final pom Hibernate Validator Aggregator diff --git a/tck-runner/pom.xml b/tck-runner/pom.xml index 9331cd8f36..eb404a25bf 100644 --- a/tck-runner/pom.xml +++ b/tck-runner/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.3-SNAPSHOT + 5.3.3.Final ../pom.xml diff --git a/test-utils/pom.xml b/test-utils/pom.xml index ed9a2c166d..ebc3514ee3 100644 --- a/test-utils/pom.xml +++ b/test-utils/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.3-SNAPSHOT + 5.3.3.Final hibernate-validator-test-utils From 6c504858636af59d3c744864589042afd1271a11 Mon Sep 17 00:00:00 2001 From: Jenkins Date: Tue, 22 Nov 2016 17:49:58 +0000 Subject: [PATCH 078/124] [Jenkins release job] Preparing next development iteration --- annotation-processor/pom.xml | 2 +- build-config/pom.xml | 2 +- cdi/pom.xml | 2 +- distribution/pom.xml | 2 +- documentation/pom.xml | 2 +- engine-jdk8-tests/pom.xml | 2 +- engine/pom.xml | 2 +- integration/pom.xml | 2 +- osgi/integrationtest/pom.xml | 2 +- osgi/karaf-features/pom.xml | 2 +- osgi/pom.xml | 2 +- performance/pom.xml | 2 +- pom.xml | 2 +- tck-runner/pom.xml | 2 +- test-utils/pom.xml | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/annotation-processor/pom.xml b/annotation-processor/pom.xml index dd097dca02..9b108e6127 100644 --- a/annotation-processor/pom.xml +++ b/annotation-processor/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.3.Final + 5.3.4-SNAPSHOT ../pom.xml diff --git a/build-config/pom.xml b/build-config/pom.xml index d99f012c7d..5b7e658035 100644 --- a/build-config/pom.xml +++ b/build-config/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.3.Final + 5.3.4-SNAPSHOT ../pom.xml diff --git a/cdi/pom.xml b/cdi/pom.xml index 383d800a92..432af78655 100644 --- a/cdi/pom.xml +++ b/cdi/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.3.Final + 5.3.4-SNAPSHOT ../pom.xml diff --git a/distribution/pom.xml b/distribution/pom.xml index cd5479ef96..78fb6e8c5e 100644 --- a/distribution/pom.xml +++ b/distribution/pom.xml @@ -10,7 +10,7 @@ hibernate-validator-parent org.hibernate - 5.3.3.Final + 5.3.4-SNAPSHOT ../pom.xml diff --git a/documentation/pom.xml b/documentation/pom.xml index 537d8753c4..3c6fd8fd66 100644 --- a/documentation/pom.xml +++ b/documentation/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.3.Final + 5.3.4-SNAPSHOT ../pom.xml diff --git a/engine-jdk8-tests/pom.xml b/engine-jdk8-tests/pom.xml index 83542d8d5f..548e91f11d 100644 --- a/engine-jdk8-tests/pom.xml +++ b/engine-jdk8-tests/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.3.Final + 5.3.4-SNAPSHOT hibernate-validator-engine-jdk8-tests diff --git a/engine/pom.xml b/engine/pom.xml index bf054fdfb9..f55b2d2178 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.3.Final + 5.3.4-SNAPSHOT ../pom.xml diff --git a/integration/pom.xml b/integration/pom.xml index af89f46f5a..490a54fb07 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.3.Final + 5.3.4-SNAPSHOT ../pom.xml diff --git a/osgi/integrationtest/pom.xml b/osgi/integrationtest/pom.xml index e35e06de9b..fe354c3639 100644 --- a/osgi/integrationtest/pom.xml +++ b/osgi/integrationtest/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-osgi org.hibernate - 5.3.3.Final + 5.3.4-SNAPSHOT ../pom.xml diff --git a/osgi/karaf-features/pom.xml b/osgi/karaf-features/pom.xml index 451fa178b3..4154f66c50 100644 --- a/osgi/karaf-features/pom.xml +++ b/osgi/karaf-features/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-osgi org.hibernate - 5.3.3.Final + 5.3.4-SNAPSHOT ../pom.xml diff --git a/osgi/pom.xml b/osgi/pom.xml index ca9a8388d8..c2f44eda12 100644 --- a/osgi/pom.xml +++ b/osgi/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.3.Final + 5.3.4-SNAPSHOT ../pom.xml diff --git a/performance/pom.xml b/performance/pom.xml index bfaf40f646..14ea622bdc 100644 --- a/performance/pom.xml +++ b/performance/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.3.Final + 5.3.4-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index b41b6d98e7..27dc12c20a 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.3.Final + 5.3.4-SNAPSHOT pom Hibernate Validator Aggregator diff --git a/tck-runner/pom.xml b/tck-runner/pom.xml index eb404a25bf..7c56bb4bb0 100644 --- a/tck-runner/pom.xml +++ b/tck-runner/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.3.Final + 5.3.4-SNAPSHOT ../pom.xml diff --git a/test-utils/pom.xml b/test-utils/pom.xml index ebc3514ee3..c0b33932c9 100644 --- a/test-utils/pom.xml +++ b/test-utils/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.3.Final + 5.3.4-SNAPSHOT hibernate-validator-test-utils From 3ffafbc81672991e79f03ac3c8110e000907ad4c Mon Sep 17 00:00:00 2001 From: bayerls Date: Mon, 28 Nov 2016 22:40:05 +0100 Subject: [PATCH 079/124] HV-1164 Only cast dynamicPayload if it is != null and add a test case --- .../internal/engine/ConstraintViolationImpl.java | 2 +- .../HibernateConstraintValidatorContextTest.java | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/ConstraintViolationImpl.java b/engine/src/main/java/org/hibernate/validator/internal/engine/ConstraintViolationImpl.java index 72daa74505..fc4aa722d3 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/ConstraintViolationImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/ConstraintViolationImpl.java @@ -228,7 +228,7 @@ public Object getExecutableReturnValue() { @Override public C getDynamicPayload(Class type) { - if ( type.isAssignableFrom( this.dynamicPayload.getClass() ) ) { + if ( dynamicPayload != null && type.isAssignableFrom( this.dynamicPayload.getClass() ) ) { return type.cast( this.dynamicPayload ); } else { diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/engine/constraintvalidation/HibernateConstraintValidatorContextTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/engine/constraintvalidation/HibernateConstraintValidatorContextTest.java index 2f2c357467..0e6facf7dc 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/engine/constraintvalidation/HibernateConstraintValidatorContextTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/engine/constraintvalidation/HibernateConstraintValidatorContextTest.java @@ -130,6 +130,21 @@ public void testNullIsReturnedForNonExistingPayloadType() { Assert.assertNull( hibernateConstraintViolation.getDynamicPayload( String.class ) ); } + @Test + @TestForIssue( jiraKey = "HV-1164") + public void testNullIsReturnedIfPayloadIsNull() { + Validator validator = getValidator(); + Set> constraintViolations = validator.validate( new Foo( QUESTION_1 ) ); + + assertNumberOfViolations( constraintViolations, 1 ); + + ConstraintViolation constraintViolation = constraintViolations.iterator().next(); + @SuppressWarnings("unchecked") + HibernateConstraintViolation hibernateConstraintViolation = constraintViolation.unwrap( HibernateConstraintViolation.class ); + + Assert.assertNull( hibernateConstraintViolation.getDynamicPayload( Object.class ) ); + } + public class Foo { @OracleConstraint private final String question; From fe240319f72ac1889db580e8b79e9f523373191c Mon Sep 17 00:00:00 2001 From: bayerls Date: Mon, 28 Nov 2016 23:44:23 +0100 Subject: [PATCH 080/124] HV-1164 remove occurences of this. for consistency --- .../validator/internal/engine/ConstraintViolationImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/ConstraintViolationImpl.java b/engine/src/main/java/org/hibernate/validator/internal/engine/ConstraintViolationImpl.java index fc4aa722d3..68d8fe30d4 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/ConstraintViolationImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/ConstraintViolationImpl.java @@ -228,8 +228,8 @@ public Object getExecutableReturnValue() { @Override public C getDynamicPayload(Class type) { - if ( dynamicPayload != null && type.isAssignableFrom( this.dynamicPayload.getClass() ) ) { - return type.cast( this.dynamicPayload ); + if ( dynamicPayload != null && type.isAssignableFrom( dynamicPayload.getClass() ) ) { + return type.cast( dynamicPayload ); } else { return null; From 743c5dd803139472ddce88104ade59a1de08fc3c Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Wed, 30 Nov 2016 09:07:12 +0100 Subject: [PATCH 081/124] HV-1164 Improving JavaDocs, removing superfluous empty lines --- .../validator/engine/HibernateConstraintViolation.java | 7 +++++-- .../HibernateConstraintValidatorContextTest.java | 3 --- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/engine/src/main/java/org/hibernate/validator/engine/HibernateConstraintViolation.java b/engine/src/main/java/org/hibernate/validator/engine/HibernateConstraintViolation.java index 5f73222a53..47106a75c7 100644 --- a/engine/src/main/java/org/hibernate/validator/engine/HibernateConstraintViolation.java +++ b/engine/src/main/java/org/hibernate/validator/engine/HibernateConstraintViolation.java @@ -8,17 +8,20 @@ import javax.validation.ConstraintViolation; +import org.hibernate.validator.constraintvalidation.HibernateConstraintValidatorContext; + /** * A custom {@link ConstraintViolation} which allows to get additional information for a constraint violation. * * @since 5.3 */ public interface HibernateConstraintViolation extends ConstraintViolation { + /** * @param type The type of payload to retrieve - * * @return an instance of the specified type set by the user via - * {@link org.hibernate.validator.constraintvalidation.HibernateConstraintValidatorContext#withDynamicPayload(Object)}. + * {@link HibernateConstraintValidatorContext#withDynamicPayload(Object)} or {@code null} if no constraint payload + * if the given type has been set. */ C getDynamicPayload(Class type); } diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/engine/constraintvalidation/HibernateConstraintValidatorContextTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/engine/constraintvalidation/HibernateConstraintValidatorContextTest.java index 0e6facf7dc..419bc14e2f 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/engine/constraintvalidation/HibernateConstraintValidatorContextTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/engine/constraintvalidation/HibernateConstraintValidatorContextTest.java @@ -176,7 +176,6 @@ public void initialize(OracleConstraint constraintAnnotation) { public boolean isValid(String question, ConstraintValidatorContext context) { HibernateConstraintValidatorContext hibernateContext = context.unwrap( HibernateConstraintValidatorContext.class ); - if ( question.equals( QUESTION_1 ) ) { createSingleConstraintViolation( hibernateContext ); } @@ -219,5 +218,3 @@ private void createSingleConstraintViolation(HibernateConstraintValidatorContext } } } - - From 822614cba55c4a1c6cc7db22f8841c5a156644b1 Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Wed, 30 Nov 2016 09:08:53 +0100 Subject: [PATCH 082/124] HV-1164 Adding Sebastian to copyright.txt --- copyright.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/copyright.txt b/copyright.txt index 191969d0d4..2248e388de 100644 --- a/copyright.txt +++ b/copyright.txt @@ -40,6 +40,7 @@ Mert Çalişkan Paolo Perrotta Pete Muir Sanne Grinovero +Sebastian Bayerl Shane Bryzak Shelly McGowan Steve Ebersole From 509a4c2ec043fcd4b5446b96eab7fb8d5dbffa0e Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Wed, 30 Nov 2016 10:13:10 +0100 Subject: [PATCH 083/124] HV-1164 Fixing formatting glitch --- .../HibernateConstraintValidatorContextTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/engine/constraintvalidation/HibernateConstraintValidatorContextTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/engine/constraintvalidation/HibernateConstraintValidatorContextTest.java index 419bc14e2f..82fa64ec03 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/engine/constraintvalidation/HibernateConstraintValidatorContextTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/engine/constraintvalidation/HibernateConstraintValidatorContextTest.java @@ -84,7 +84,7 @@ public void testExpressionTermAsAttributeValueIsTreatedAsString() { } @Test - @TestForIssue( jiraKey = "HV-951") + @TestForIssue(jiraKey = "HV-951") public void testExpressionVariablesAreExposedInConstraintViolation() throws Exception { Validator validator = getValidator(); Set> constraintViolations = validator.validate( new Foo( QUESTION_1 ) ); @@ -99,7 +99,7 @@ public void testExpressionVariablesAreExposedInConstraintViolation() throws Exce } @Test - @TestForIssue( jiraKey = "HV-1020") + @TestForIssue(jiraKey = "HV-1020") public void testDynamicPayloadExposedInHibernateConstraintViolation() { Validator validator = getValidator(); Set> constraintViolations = validator.validate( new Foo( QUESTION_4 ) ); @@ -116,7 +116,7 @@ public void testDynamicPayloadExposedInHibernateConstraintViolation() { } @Test - @TestForIssue( jiraKey = "HV-1020") + @TestForIssue(jiraKey = "HV-1020") public void testNullIsReturnedForNonExistingPayloadType() { Validator validator = getValidator(); Set> constraintViolations = validator.validate( new Foo( QUESTION_4 ) ); @@ -131,7 +131,7 @@ public void testNullIsReturnedForNonExistingPayloadType() { } @Test - @TestForIssue( jiraKey = "HV-1164") + @TestForIssue(jiraKey = "HV-1164") public void testNullIsReturnedIfPayloadIsNull() { Validator validator = getValidator(); Set> constraintViolations = validator.validate( new Foo( QUESTION_1 ) ); From 02b2ba28c571b780ed6f8f99a4d097c1ef0c4639 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Fri, 2 Dec 2016 17:04:36 +0100 Subject: [PATCH 084/124] HV-1165 Support type argument constraints for Set This is a follow-up of HV-1062: it fixed the Map case but introduced a regression for the Set case. Also unify the tests so that they cover correctly all cases. Also fix a misleading comment which led to this mistake. Note that a few tests for Optional method validation got removed, they will be reintroduced in a follow-up commit. --- .../TypeAnnotationConstraintTest.java | 720 +++++++++++++++--- .../internal/engine/ValidatorImpl.java | 2 +- .../provider/AnnotationMetaDataProvider.java | 16 +- .../internal/util/ReflectionHelper.java | 49 +- .../internal/util/ReflectionHelperTest.java | 78 +- 5 files changed, 698 insertions(+), 167 deletions(-) diff --git a/engine-jdk8-tests/src/test/java/org/hibernate/validator/test/internal/engine/typeannotationconstraint/TypeAnnotationConstraintTest.java b/engine-jdk8-tests/src/test/java/org/hibernate/validator/test/internal/engine/typeannotationconstraint/TypeAnnotationConstraintTest.java index a9e5856db6..5da294edce 100644 --- a/engine-jdk8-tests/src/test/java/org/hibernate/validator/test/internal/engine/typeannotationconstraint/TypeAnnotationConstraintTest.java +++ b/engine-jdk8-tests/src/test/java/org/hibernate/validator/test/internal/engine/typeannotationconstraint/TypeAnnotationConstraintTest.java @@ -15,7 +15,9 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.Arrays; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -30,8 +32,11 @@ import javax.validation.Validator; import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; import org.apache.log4j.Logger; +import org.hibernate.validator.constraints.NotBlank; +import org.hibernate.validator.internal.util.CollectionHelper; import org.hibernate.validator.testutil.MessageLoggedAssertionLogger; import org.hibernate.validator.testutil.TestForIssue; import org.hibernate.validator.testutils.constraints.NotBlankTypeUse; @@ -44,6 +49,7 @@ * * @author Khalid Alqinyah * @author Hardy Ferentschik + * @author Guillaume Smet */ public class TypeAnnotationConstraintTest { @@ -54,12 +60,14 @@ public void setup() { validator = getValidator(); } + // List + @Test public void field_constraint_provided_on_type_parameter_of_a_list_gets_validated() { - A1 a = new A1(); - a.names = Arrays.asList( "First", "", null ); + TypeWithList1 l = new TypeWithList1(); + l.names = Arrays.asList( "First", "", null ); - Set> constraintViolations = validator.validate( a ); + Set> constraintViolations = validator.validate( l ); assertNumberOfViolations( constraintViolations, 3 ); assertCorrectPropertyPaths( constraintViolations, "names[1].", "names[2].", "names[2]." ); @@ -72,18 +80,46 @@ public void field_constraint_provided_on_type_parameter_of_a_list_gets_validated } @Test(expectedExceptions = ValidationException.class, expectedExceptionsMessageRegExp = "HV000187.*") - public void valid_annotation_required_for_constraint_on_type_parameter_of_iterable() { - A2 a = new A2(); - a.names = Arrays.asList( "First", "", null ); - validator.validate( a ); + public void valid_annotation_required_for_constraint_on_type_parameter_of_list() { + TypeWithList2 l = new TypeWithList2(); + l.names = Arrays.asList( "First", "", null ); + validator.validate( l ); + } + + @Test + public void constraint_provided_on_custom_bean_used_as_list_parameter_gets_validated() { + TypeWithList3 l = new TypeWithList3(); + l.bars = Arrays.asList( new Bar( 2 ), null ); + Set> constraintViolations = validator.validate( l ); + assertNumberOfViolations( constraintViolations, 2 ); + assertCorrectPropertyPaths( constraintViolations, "bars[1].", "bars[0].number" ); + assertCorrectConstraintTypes( constraintViolations, Min.class, NotNullTypeUse.class ); + } + + @Test + @TestForIssue(jiraKey = "HV-1165") + public void constraints_specified_on_list_and_on_type_parameter_of_list_get_validated() { + TypeWithList4 l = new TypeWithList4(); + l.names = Arrays.asList( "First", "", null ); + Set> constraintViolations = validator.validate( l ); + assertNumberOfViolations( constraintViolations, 2 ); + assertCorrectPropertyPaths( constraintViolations, "names[1].", "names[2]." ); + assertCorrectConstraintTypes( constraintViolations, NotBlankTypeUse.class, NotBlankTypeUse.class ); + + l = new TypeWithList4(); + l.names = new ArrayList(); + constraintViolations = validator.validate( l ); + assertNumberOfViolations( constraintViolations, 1 ); + assertCorrectPropertyPaths( constraintViolations, "names" ); + assertCorrectConstraintTypes( constraintViolations, Size.class ); } @Test public void getter_constraint_provided_on_type_parameter_of_a_list_gets_validated() { - A3 a = new A3(); - a.strings = Arrays.asList( "", "First", null ); + TypeWithList5 l = new TypeWithList5(); + l.strings = Arrays.asList( "", "First", null ); - Set> constraintViolations = validator.validate( a ); + Set> constraintViolations = validator.validate( l ); assertNumberOfViolations( constraintViolations, 3 ); assertCorrectPropertyPaths( constraintViolations, "strings[0].", "strings[2].", "strings[2]." ); @@ -96,82 +132,349 @@ public void getter_constraint_provided_on_type_parameter_of_a_list_gets_validate } @Test - public void constraint_provided_on_custom_bean_used_as_list_parameter_gets_validated() { - B b = new B(); - b.bars = Arrays.asList( new Bar( 2 ), null ); - Set> constraintViolations = validator.validate( b ); + public void return_value_constraint_provided_on_type_parameter_of_a_list_gets_validated() throws Exception { + Method method = TypeWithList6.class.getDeclaredMethod( "returnStrings" ); + Set> constraintViolations = validator.forExecutables().validateReturnValue( + new TypeWithList6(), + method, + Arrays.asList( "First", "", null ) + ); + assertNumberOfViolations( constraintViolations, 3 ); + assertCorrectPropertyPaths( + constraintViolations, + "returnStrings.[1].", + "returnStrings.[2].", + "returnStrings.[2]." + ); + assertCorrectConstraintTypes( + constraintViolations, + NotBlankTypeUse.class, + NotBlankTypeUse.class, + NotNullTypeUse.class + ); + } + + @Test + @TestForIssue(jiraKey = "HV-1121") + public void property_path_contains_index_information_for_list() { + TypeWithList1 l = new TypeWithList1(); + l.names = Arrays.asList( "" ); + + Set> constraintViolations = validator.validate( l ); + + assertNumberOfViolations( constraintViolations, 1 ); + + Iterator propertyPathIterator = constraintViolations.iterator().next().getPropertyPath().iterator(); + + Path.Node firstNode = propertyPathIterator.next(); + assertThat( firstNode.getIndex() ).isNull(); + assertThat( firstNode.getName() ).isEqualTo( "names" ); + assertThat( firstNode.getKind() ).isEqualTo( ElementKind.PROPERTY ); + + Path.Node secondNode = propertyPathIterator.next(); + assertThat( secondNode.getIndex() ).isEqualTo( 0 ); + assertThat( secondNode.getName() ).isEqualTo( "" ); + assertThat( secondNode.getKind() ).isEqualTo( ElementKind.PROPERTY ); + } + + @Test + public void method_parameter_constraint_provided_as_type_parameter_of_a_list_gets_validated() throws Exception { + Method method = TypeWithList7.class.getDeclaredMethod( "setValues", List.class ); + Object[] values = new Object[] { Arrays.asList( "", "First", null ) }; + + Set> constraintViolations = validator.forExecutables().validateParameters( + new TypeWithList7(), + method, + values + ); + assertNumberOfViolations( constraintViolations, 3 ); + assertCorrectPropertyPaths( + constraintViolations, + "setValues.arg0[0].", + "setValues.arg0[2].", + "setValues.arg0[2]." + ); + assertCorrectConstraintTypes( + constraintViolations, + NotBlankTypeUse.class, + NotBlankTypeUse.class, + NotNullTypeUse.class + ); + } + + @Test + public void constructor_parameter_constraint_provided_on_type_parameter_of_a_list_gets_validated() throws Exception { + Constructor constructor = TypeWithList8.class.getDeclaredConstructor( List.class ); + Object[] values = new Object[] { Arrays.asList( "", "First", null ) }; + + Set> constraintViolations = validator.forExecutables().validateConstructorParameters( + constructor, + values + ); + assertNumberOfViolations( constraintViolations, 3 ); + assertCorrectPropertyPaths( + constraintViolations, + "TypeWithList8.arg0[0].", + "TypeWithList8.arg0[2].", + "TypeWithList8.arg0[2]." + ); + assertCorrectConstraintTypes( + constraintViolations, + NotBlankTypeUse.class, + NotBlankTypeUse.class, + NotNullTypeUse.class + ); + } + + // Set + + @Test + @TestForIssue(jiraKey = "HV-1165") + public void field_constraint_provided_on_type_parameter_of_a_set_gets_validated() { + TypeWithSet1 s = new TypeWithSet1(); + s.names = CollectionHelper.asSet( "First", "", null ); + + Set> constraintViolations = validator.validate( s ); + + assertNumberOfViolations( constraintViolations, 3 ); + assertCorrectPropertyPaths( constraintViolations, "names[].", "names[].", "names[]." ); + assertCorrectConstraintTypes( + constraintViolations, + NotBlankTypeUse.class, + NotBlankTypeUse.class, + NotNullTypeUse.class + ); + } + + @Test(expectedExceptions = ValidationException.class, expectedExceptionsMessageRegExp = "HV000187.*") + @TestForIssue(jiraKey = "HV-1165") + public void valid_annotation_required_for_constraint_on_type_parameter_of_set() { + TypeWithSet2 s = new TypeWithSet2(); + s.names = CollectionHelper.asSet( "First", "", null ); + validator.validate( s ); + } + + @Test + @TestForIssue(jiraKey = "HV-1165") + public void constraint_provided_on_custom_bean_used_as_set_parameter_gets_validated() { + TypeWithSet3 s = new TypeWithSet3(); + s.bars = CollectionHelper.asSet( new Bar( 2 ), null ); + Set> constraintViolations = validator.validate( s ); assertNumberOfViolations( constraintViolations, 2 ); - assertCorrectPropertyPaths( constraintViolations, "bars[1].", "bars[0].number" ); + assertCorrectPropertyPaths( constraintViolations, "bars[].", "bars[].number" ); assertCorrectConstraintTypes( constraintViolations, Min.class, NotNullTypeUse.class ); } @Test - public void constraint_specified_on_type_parameter_of_optional_gets_validated() { - C c = new C(); - c.stringOptional = Optional.of( "" ); - - Set> constraintViolations = validator.validate( c ); + @TestForIssue(jiraKey = "HV-1165") + public void constraints_specified_on_set_and_on_type_parameter_of_set_get_validated() { + TypeWithSet4 s = new TypeWithSet4(); + s.names = CollectionHelper.asSet( "First", "", null ); + Set> constraintViolations = validator.validate( s ); + assertNumberOfViolations( constraintViolations, 2 ); + assertCorrectPropertyPaths( constraintViolations, "names[].", "names[]." ); + assertCorrectConstraintTypes( constraintViolations, NotBlankTypeUse.class, NotBlankTypeUse.class ); + s = new TypeWithSet4(); + s.names = new HashSet(); + constraintViolations = validator.validate( s ); assertNumberOfViolations( constraintViolations, 1 ); - assertCorrectPropertyPaths( constraintViolations, "stringOptional" ); - assertCorrectConstraintTypes( constraintViolations, NotBlankTypeUse.class ); + assertCorrectPropertyPaths( constraintViolations, "names" ); + assertCorrectConstraintTypes( constraintViolations, Size.class ); } + @Test + @TestForIssue(jiraKey = "HV-1165") + public void getter_constraint_provided_on_type_parameter_of_a_set_gets_validated() { + TypeWithSet5 s = new TypeWithSet5(); + s.strings = new HashSet(); + s.strings.add( "First" ); + s.strings.add( "" ); + s.strings.add( null ); + + Set> constraintViolations = validator.validate( s ); + + assertNumberOfViolations( constraintViolations, 3 ); + assertCorrectPropertyPaths( constraintViolations, "strings[].", "strings[].", "strings[]." ); + assertCorrectConstraintTypes( + constraintViolations, + NotBlankTypeUse.class, + NotBlankTypeUse.class, + NotNullTypeUse.class + ); + } + + @Test + @TestForIssue(jiraKey = "HV-1165") + public void return_value_constraint_provided_on_type_parameter_of_a_set_gets_validated() throws Exception { + Method method = TypeWithSet6.class.getDeclaredMethod( "returnStrings" ); + Set> constraintViolations = validator.forExecutables().validateReturnValue( + new TypeWithSet6(), + method, + CollectionHelper.asSet( "First", "", null ) + ); + assertNumberOfViolations( constraintViolations, 3 ); + assertCorrectPropertyPaths( + constraintViolations, + "returnStrings.[].", + "returnStrings.[].", + "returnStrings.[]." + ); + assertCorrectConstraintTypes( + constraintViolations, + NotBlankTypeUse.class, + NotBlankTypeUse.class, + NotNullTypeUse.class + ); + } + + @Test + public void method_parameter_constraint_provided_as_type_parameter_of_a_set_gets_validated() throws Exception { + Method method = TypeWithSet7.class.getDeclaredMethod( "setValues", Set.class ); + Object[] values = new Object[] { CollectionHelper.asSet( "", "First", null ) }; + + Set> constraintViolations = validator.forExecutables().validateParameters( + new TypeWithSet7(), + method, + values + ); + assertNumberOfViolations( constraintViolations, 3 ); + assertCorrectPropertyPaths( + constraintViolations, + "setValues.arg0[].", + "setValues.arg0[].", + "setValues.arg0[]." + ); + assertCorrectConstraintTypes( + constraintViolations, + NotBlankTypeUse.class, + NotBlankTypeUse.class, + NotNullTypeUse.class + ); + } + + @Test + public void constructor_parameter_constraint_provided_on_type_parameter_of_a_set_gets_validated() throws Exception { + Constructor constructor = TypeWithSet8.class.getDeclaredConstructor( Set.class ); + Object[] values = new Object[] { CollectionHelper.asSet( "", "First", null ) }; + + Set> constraintViolations = validator.forExecutables().validateConstructorParameters( + constructor, + values + ); + assertNumberOfViolations( constraintViolations, 3 ); + assertCorrectPropertyPaths( + constraintViolations, + "TypeWithSet8.arg0[].", + "TypeWithSet8.arg0[].", + "TypeWithSet8.arg0[]." + ); + assertCorrectConstraintTypes( + constraintViolations, + NotBlankTypeUse.class, + NotBlankTypeUse.class, + NotNullTypeUse.class + ); + } + + // Map + @Test public void constraint_specified_on_value_type_of_map_gets_validated() { - F1 f = new F1(); - f.namesMap = newHashMap(); - f.namesMap.put( "first", "Name 1" ); - f.namesMap.put( "second", "" ); - f.namesMap.put( "third", "Name 3" ); - Set> constraintViolations = validator.validate( f ); + TypeWithMap1 m = new TypeWithMap1(); + m.nameMap = newHashMap(); + m.nameMap.put( "first", "Name 1" ); + m.nameMap.put( "second", "" ); + m.nameMap.put( "third", "Name 3" ); + Set> constraintViolations = validator.validate( m ); assertNumberOfViolations( constraintViolations, 1 ); - assertCorrectPropertyPaths( constraintViolations, "namesMap[second]." ); + assertCorrectPropertyPaths( constraintViolations, "nameMap[second]." ); assertCorrectConstraintTypes( constraintViolations, NotBlankTypeUse.class ); } + @Test(expectedExceptions = ValidationException.class, expectedExceptionsMessageRegExp = "HV000187.*") + public void valid_annotation_required_for_constraint_on_type_parameter_of_map() { + TypeWithMap2 m = new TypeWithMap2(); + m.nameMap = newHashMap(); + m.nameMap.put( "first", "Name 1" ); + m.nameMap.put( "second", "" ); + m.nameMap.put( "third", "Name 3" ); + validator.validate( m ); + } + + @Test + public void constraint_provided_on_custom_bean_used_as_map_parameter_gets_validated() { + TypeWithMap3 m = new TypeWithMap3(); + m.barMap = newHashMap(); + m.barMap.put( "bar", new Bar( 2 ) ); + m.barMap.put( "foo", null ); + Set> constraintViolations = validator.validate( m ); + assertNumberOfViolations( constraintViolations, 2 ); + assertCorrectPropertyPaths( constraintViolations, "barMap[foo].", "barMap[bar].number" ); + assertCorrectConstraintTypes( constraintViolations, Min.class, NotNullTypeUse.class ); + } + @Test @TestForIssue(jiraKey = "HV-1062") public void constraints_specified_on_map_and_on_value_type_of_map_get_validated() { - F2 f = new F2(); - f.namesMap = newHashMap(); - f.namesMap.put( "first", "Name 1" ); - f.namesMap.put( "second", "" ); - f.namesMap.put( "third", "Name 3" ); - Set> constraintViolations = validator.validate( f ); + TypeWithMap4 m = new TypeWithMap4(); + m.nameMap = newHashMap(); + m.nameMap.put( "first", "Name 1" ); + m.nameMap.put( "second", "" ); + m.nameMap.put( "third", "Name 3" ); + Set> constraintViolations = validator.validate( m ); assertNumberOfViolations( constraintViolations, 1 ); - assertCorrectPropertyPaths( constraintViolations, "namesMap[second]." ); + assertCorrectPropertyPaths( constraintViolations, "nameMap[second]." ); assertCorrectConstraintTypes( constraintViolations, NotBlankTypeUse.class ); - f = new F2(); - constraintViolations = validator.validate( f ); + m = new TypeWithMap4(); + constraintViolations = validator.validate( m ); assertNumberOfViolations( constraintViolations, 1 ); - assertCorrectPropertyPaths( constraintViolations, "namesMap" ); + assertCorrectPropertyPaths( constraintViolations, "nameMap" ); assertCorrectConstraintTypes( constraintViolations, NotNull.class ); } - @Test(expectedExceptions = ValidationException.class, expectedExceptionsMessageRegExp = "HV000182.*") - public void custom_generic_type_with_type_annotation_constraint_but_no_unwrapper_throws_exception() { - // No unwrapper is registered for Baz - BazHolder bazHolder = new BazHolder(); - bazHolder.baz = null; - validator.validate( bazHolder ); + @Test + public void getter_constraint_provided_on_type_parameter_of_a_map_gets_validated() { + TypeWithMap5 m = new TypeWithMap5(); + m.stringMap = newHashMap(); + m.stringMap.put( "first", "" ); + m.stringMap.put( "second", "Second" ); + m.stringMap.put( "third", null ); + + Set> constraintViolations = validator.validate( m ); + + assertNumberOfViolations( constraintViolations, 3 ); + assertCorrectPropertyPaths( constraintViolations, "stringMap[first].", "stringMap[third].", + "stringMap[third]." ); + assertCorrectConstraintTypes( + constraintViolations, + NotBlankTypeUse.class, + NotBlankTypeUse.class, + NotNullTypeUse.class + ); } @Test - public void return_value_constraint_provided_on_type_parameter_of_a_list_gets_validated() throws Exception { - Method method = E.class.getDeclaredMethod( "returnStrings" ); - Set> constraintViolations = validator.forExecutables().validateReturnValue( - new E(), + public void return_value_constraint_provided_on_type_parameter_of_a_map_gets_validated() throws Exception { + Method method = TypeWithMap6.class.getDeclaredMethod( "returnStringMap" ); + + Map parameter = newHashMap(); + parameter.put( "first", "First" ); + parameter.put( "second", "" ); + parameter.put( "third", null ); + + Set> constraintViolations = validator.forExecutables().validateReturnValue( + new TypeWithMap6(), method, - Arrays.asList( "First", "", null ) + parameter ); assertNumberOfViolations( constraintViolations, 3 ); assertCorrectPropertyPaths( constraintViolations, - "returnStrings.[1].", - "returnStrings.[2].", - "returnStrings.[2]." + "returnStringMap.[second].", + "returnStringMap.[third].", + "returnStringMap.[third]." ); assertCorrectConstraintTypes( constraintViolations, @@ -182,60 +485,155 @@ public void return_value_constraint_provided_on_type_parameter_of_a_list_gets_va } @Test - public void method_parameter_constraint_provided_as_type_parameter_of_a_list_gets_validated() - throws Exception { - Method method = H.class.getDeclaredMethod( "setValues", List.class, Optional.class ); - Object[] values = new Object[] { Arrays.asList( "", "First", null ), Optional.of( "" ) }; + public void property_path_contains_index_information_for_map() { + TypeWithMap1 m = new TypeWithMap1(); + m.nameMap = newHashMap(); + m.nameMap.put( "first", "" ); + + Set> constraintViolations = validator.validate( m ); + + assertNumberOfViolations( constraintViolations, 1 ); + + Iterator propertyPathIterator = constraintViolations.iterator().next().getPropertyPath().iterator(); + + Path.Node firstNode = propertyPathIterator.next(); + assertThat( firstNode.getKey() ).isNull(); + assertThat( firstNode.getName() ).isEqualTo( "nameMap" ); + assertThat( firstNode.getKind() ).isEqualTo( ElementKind.PROPERTY ); + + Path.Node secondNode = propertyPathIterator.next(); + assertThat( secondNode.getKey() ).isEqualTo( "first" ); + assertThat( secondNode.getName() ).isEqualTo( "" ); + assertThat( secondNode.getKind() ).isEqualTo( ElementKind.PROPERTY ); + } + + @Test + public void method_parameter_constraint_provided_as_type_parameter_of_a_map_gets_validated() throws Exception { + Method method = TypeWithMap7.class.getDeclaredMethod( "setValues", Map.class ); + + Map parameter = newHashMap(); + parameter.put( "first", "First" ); + parameter.put( "second", "" ); + parameter.put( "third", null ); + Object[] values = new Object[] { parameter }; - Set> constraintViolations = validator.forExecutables().validateParameters( - new H(), + Set> constraintViolations = validator.forExecutables().validateParameters( + new TypeWithMap7(), method, values ); - assertNumberOfViolations( constraintViolations, 4 ); + assertNumberOfViolations( constraintViolations, 3 ); assertCorrectPropertyPaths( constraintViolations, - "setValues.arg0[0].", - "setValues.arg0[2].", - "setValues.arg0[2].", - "setValues.arg1" + "setValues.arg0[second].", + "setValues.arg0[third].", + "setValues.arg0[third]." ); assertCorrectConstraintTypes( constraintViolations, NotBlankTypeUse.class, NotBlankTypeUse.class, - NotNullTypeUse.class, - NotBlankTypeUse.class + NotNullTypeUse.class ); } @Test - public void constructor_parameter_constraint_provided_on_type_parameter_of_a_list_gets_validated() - throws Exception { - Constructor constructor = G.class.getDeclaredConstructor( List.class, Optional.class ); - Object[] values = new Object[] { Arrays.asList( "", "First", null ), Optional.of( "" ) }; + public void constructor_parameter_constraint_provided_on_type_parameter_of_a_map_gets_validated() throws Exception { + Constructor constructor = TypeWithMap8.class.getDeclaredConstructor( Map.class ); - Set> constraintViolations = validator.forExecutables().validateConstructorParameters( + Map parameter = newHashMap(); + parameter.put( "first", "First" ); + parameter.put( "second", "" ); + parameter.put( "third", null ); + Object[] values = new Object[] { parameter }; + + Set> constraintViolations = validator.forExecutables().validateConstructorParameters( constructor, values ); - assertNumberOfViolations( constraintViolations, 4 ); + assertNumberOfViolations( constraintViolations, 3 ); assertCorrectPropertyPaths( constraintViolations, - "G.arg0[0].", - "G.arg0[2].", - "G.arg0[2].", - "G.arg1" + "TypeWithMap8.arg0[second].", + "TypeWithMap8.arg0[third].", + "TypeWithMap8.arg0[third]." ); assertCorrectConstraintTypes( constraintViolations, NotBlankTypeUse.class, NotBlankTypeUse.class, - NotNullTypeUse.class, + NotNullTypeUse.class + ); + } + + // Optional + + @Test + public void constraint_specified_on_type_parameter_of_optional_gets_validated() { + TypeWithOptional1 o = new TypeWithOptional1(); + o.stringOptional = Optional.of( "" ); + + Set> constraintViolations = validator.validate( o ); + + assertNumberOfViolations( constraintViolations, 1 ); + assertCorrectPropertyPaths( constraintViolations, "stringOptional" ); + assertCorrectConstraintTypes( constraintViolations, NotBlankTypeUse.class ); + } + + // Case 2 does not make sense here so we skip it + + @Test + public void constraint_provided_on_custom_bean_used_as_optional_parameter_gets_validated() { + TypeWithOptional3 o = new TypeWithOptional3(); + o.bar = Optional.empty(); + Set> constraintViolations = validator.validate( o ); + assertNumberOfViolations( constraintViolations, 1 ); + assertCorrectPropertyPaths( constraintViolations, "bar" ); + assertCorrectConstraintTypes( constraintViolations, NotNullTypeUse.class ); + } + + @Test + public void constraints_specified_on_optional_and_on_type_parameter_of_optional_get_validated() { + TypeWithOptional4 o = new TypeWithOptional4(); + o.stringOptional = Optional.of( "" ); + Set> constraintViolations = validator.validate( o ); + assertNumberOfViolations( constraintViolations, 1 ); + assertCorrectPropertyPaths( constraintViolations, "stringOptional" ); + assertCorrectConstraintTypes( constraintViolations, NotBlankTypeUse.class ); + + o = new TypeWithOptional4(); + o.stringOptional = null; + constraintViolations = validator.validate( o ); + assertNumberOfViolations( constraintViolations, 2 ); + assertCorrectPropertyPaths( constraintViolations, "stringOptional", "stringOptional" ); + assertCorrectConstraintTypes( constraintViolations, NotNull.class, NotBlankTypeUse.class ); + } + + @Test + public void getter_constraint_provided_on_type_parameter_of_an_optional_gets_validated() { + TypeWithOptional5 o = new TypeWithOptional5(); + o.stringOptional = Optional.of( "" ); + + Set> constraintViolations = validator.validate( o ); + + assertNumberOfViolations( constraintViolations, 1 ); + assertCorrectPropertyPaths( constraintViolations, "stringOptional" ); + assertCorrectConstraintTypes( + constraintViolations, NotBlankTypeUse.class ); } + // No unwrapper available + + @Test(expectedExceptions = ValidationException.class, expectedExceptionsMessageRegExp = "HV000182.*") + public void custom_generic_type_with_type_annotation_constraint_but_no_unwrapper_throws_exception() { + // No unwrapper is registered for Baz + BazHolder bazHolder = new BazHolder(); + bazHolder.baz = null; + validator.validate( bazHolder ); + } + @Test public void unsupported_use_of_type_constraints_logs_warning() { Logger log4jRootLogger = Logger.getRootLogger(); @@ -251,48 +649,29 @@ public void unsupported_use_of_type_constraints_logs_warning() { log4jRootLogger.removeAppender( assertingLogger ); } - @Test - @TestForIssue(jiraKey = "HV-1121") - public void property_path_contains_index_information() { - A1 a = new A1(); - a.names = Arrays.asList( "" ); - - Set> constraintViolations = validator.validate( a ); + // List - assertNumberOfViolations( constraintViolations, 1 ); - - Iterator propertyPathIterator = constraintViolations.iterator().next().getPropertyPath().iterator(); - - Path.Node firstNode = propertyPathIterator.next(); - assertThat( firstNode.getIndex() ).isNull(); - assertThat( firstNode.getName() ).isEqualTo( "names" ); - assertThat( firstNode.getKind() ).isEqualTo( ElementKind.PROPERTY ); - - Path.Node secondNode = propertyPathIterator.next(); - assertThat( secondNode.getIndex() ).isEqualTo( 0 ); - assertThat( secondNode.getName() ).isEqualTo( "" ); - assertThat( secondNode.getKind() ).isEqualTo( ElementKind.PROPERTY ); - } - - static class A1 { + static class TypeWithList1 { @Valid List<@NotNullTypeUse @NotBlankTypeUse String> names; } - static class A2 { + static class TypeWithList2 { List<@NotNullTypeUse @NotBlankTypeUse String> names; } - static class B { + static class TypeWithList3 { @Valid List<@NotNullTypeUse Bar> bars; } - static class C { - Optional<@NotBlankTypeUse String> stringOptional; + static class TypeWithList4 { + @Valid + @Size(min = 1) + List<@NotBlankTypeUse String> names; } - static class A3 { + static class TypeWithList5 { List strings; @Valid @@ -301,7 +680,7 @@ static class A3 { } } - static class E { + static class TypeWithList6 { List strings; @Valid @@ -310,29 +689,141 @@ static class E { } } - static class F1 { + static class TypeWithList7 { + public void setValues(@Valid List<@NotNullTypeUse @NotBlankTypeUse String> listParameter) { + } + } + + static class TypeWithList8 { + public TypeWithList8(@Valid List<@NotNullTypeUse @NotBlankTypeUse String> listParameter) { + } + } + + // Set + + static class TypeWithSet1 { + @Valid + Set<@NotNullTypeUse @NotBlankTypeUse String> names; + } + + static class TypeWithSet2 { + Set<@NotNullTypeUse @NotBlankTypeUse String> names; + } + + static class TypeWithSet3 { + @Valid + Set<@NotNullTypeUse Bar> bars; + } + + static class TypeWithSet4 { @Valid - Map namesMap; + @Size(min = 1) + Set<@NotBlankTypeUse String> names; } - static class F2 { + static class TypeWithSet5 { + Set strings; + + @Valid + public Set<@NotNullTypeUse @NotBlankTypeUse String> getStrings() { + return strings; + } + } + + static class TypeWithSet6 { + Set strings; + + @Valid + public Set<@NotNullTypeUse @NotBlankTypeUse String> returnStrings() { + return strings; + } + } + + static class TypeWithSet7 { + public void setValues(@Valid Set<@NotNullTypeUse @NotBlankTypeUse String> setParameter) { + } + } + + static class TypeWithSet8 { + public TypeWithSet8(@Valid Set<@NotNullTypeUse @NotBlankTypeUse String> setParameter) { + } + } + + // Map + + static class TypeWithMap1 { + @Valid + Map nameMap; + } + + static class TypeWithMap2 { + Map nameMap; + } + + static class TypeWithMap3 { + @Valid + Map barMap; + } + + static class TypeWithMap4 { @Valid @NotNull - Map namesMap; + Map nameMap; + } + + static class TypeWithMap5 { + Map stringMap; + + @Valid + public Map getStringMap() { + return stringMap; + } } - static class G { - public G(@Valid List<@NotNullTypeUse @NotBlankTypeUse String> names, Optional<@NotBlankTypeUse String> optionalParameter) { + static class TypeWithMap6 { + Map stringMap; + @Valid + public Map returnStringMap() { + return stringMap; } } - static class H { - public void setValues(@Valid List<@NotNullTypeUse @NotBlankTypeUse String> listParameter, Optional<@NotBlankTypeUse String> optionalParameter) { + static class TypeWithMap7 { + public void setValues(@Valid Map mapParameter) { + } + } + + static class TypeWithMap8 { + public TypeWithMap8(@Valid Map mapParameter) { + } + } + + // Optional + + static class TypeWithOptional1 { + Optional<@NotBlankTypeUse String> stringOptional; + } + + static class TypeWithOptional3 { + Optional<@NotNullTypeUse Bar> bar; + } + static class TypeWithOptional4 { + @NotNull + Optional<@NotBlankTypeUse String> stringOptional; + } + + static class TypeWithOptional5 { + Optional stringOptional; + + public Optional<@NotNullTypeUse @NotBlankTypeUse String> getStringOptional() { + return stringOptional; } } + // No wrapper available + static class Bar { @Min(4) Integer number; @@ -357,4 +848,5 @@ class FooHolder { class Foo { } + } diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java index fa8f440ca0..8b67f64beb 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java @@ -1581,7 +1581,7 @@ private ValueContext collectMetaConstraintsForPathWithoutValue(Validat if ( propertyPathNode.isIterable() ) { propertyPathNode = (NodeImpl) propertyPathIter.next(); - clazz = ReflectionHelper.getClassFromType( ReflectionHelper.getIndexedType( propertyMetaData.getType() ) ); + clazz = ReflectionHelper.getClassFromType( ReflectionHelper.getCollectionElementType( propertyMetaData.getType() ) ); propertyMetaData = getBeanPropertyMetaData( clazz, propertyPathNode ); } else { diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java index 39fcf6cb40..671089d47a 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/provider/AnnotationMetaDataProvider.java @@ -258,15 +258,15 @@ private ConstrainedField findPropertyMetaData(Field field) { } private UnwrapMode unwrapMode(Field field, boolean typeArgumentAnnotated) { - boolean indexable = ReflectionHelper.isIndexable( ReflectionHelper.typeOf( field ) ); + boolean isCollection = ReflectionHelper.isCollection( ReflectionHelper.typeOf( field ) ); UnwrapValidatedValue unwrapValidatedValue = field.getAnnotation( UnwrapValidatedValue.class ); - return unwrapMode( typeArgumentAnnotated, indexable, unwrapValidatedValue ); + return unwrapMode( typeArgumentAnnotated, isCollection, unwrapValidatedValue ); } private UnwrapMode unwrapMode(ExecutableElement executable, boolean typeArgumentAnnotated) { - boolean indexable = ReflectionHelper.isIndexable( ReflectionHelper.typeOf( executable.getMember() ) ); + boolean isCollection = ReflectionHelper.isCollection( ReflectionHelper.typeOf( executable.getMember() ) ); UnwrapValidatedValue unwrapValidatedValue = executable.getAccessibleObject().getAnnotation( UnwrapValidatedValue.class ); - return unwrapMode( typeArgumentAnnotated, indexable, unwrapValidatedValue ); + return unwrapMode( typeArgumentAnnotated, isCollection, unwrapValidatedValue ); } private Set> convertToMetaConstraints(List> constraintDescriptors, Field field) { @@ -278,8 +278,8 @@ private Set> convertToMetaConstraints(List exampleValue */ @@ -497,8 +497,8 @@ else if ( parameterAnnotation.annotationType().equals( UnwrapValidatedValue.clas typeArgumentsConstraints = findTypeAnnotationConstraintsForExecutableParameter( executable.getMember(), i ); boolean typeArgumentAnnotated = !typeArgumentsConstraints.isEmpty(); - boolean indexable = ReflectionHelper.isIndexable( ReflectionHelper.typeOf( executable, i ) ); - UnwrapMode unwrapMode = unwrapMode( typeArgumentAnnotated, indexable, unwrapValidatedValue ); + boolean isCollection = ReflectionHelper.isCollection( ReflectionHelper.typeOf( executable, i ) ); + UnwrapMode unwrapMode = unwrapMode( typeArgumentAnnotated, isCollection, unwrapValidatedValue ); metaData.add( new ConstrainedParameter( diff --git a/engine/src/main/java/org/hibernate/validator/internal/util/ReflectionHelper.java b/engine/src/main/java/org/hibernate/validator/internal/util/ReflectionHelper.java index 1a69f01a83..77e2d2cc72 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/util/ReflectionHelper.java +++ b/engine/src/main/java/org/hibernate/validator/internal/util/ReflectionHelper.java @@ -34,6 +34,7 @@ * @author Hardy Ferentschik * @author Gunnar Morling * @author Kevin Pollet <kevin.pollet@serli.com> (C) 2011 SERLI + * @author Guillaume Smet */ public final class ReflectionHelper { @@ -253,36 +254,19 @@ public static Object getValue(Method method, Object object) { } /** - * Indicates if the type is considered indexable (ie is an {@code Iterable}, an array or a {@code Map}). - * - * @param type the type to inspect. - * - * @return Returns true if the type is indexable. + * Indicates whether the given type represents a collection of elements or not (i.e. whether it is an + * {@code Iterable}, {@code Map} or array type). */ - public static boolean isIndexable(Type type) { - boolean isIndexable = false; - if ( ReflectionHelper.isList( type ) ) { - isIndexable = true; - } - else if ( ReflectionHelper.isMap( type ) ) { - isIndexable = true; - } - else if ( TypeHelper.isArray( type ) ) { - isIndexable = true; - } - return isIndexable; + public static boolean isCollection(Type type) { + return isIterable( type ) || + isMap( type ) || + TypeHelper.isArray( type ); } - /** - * Determines the type of elements of an Iterable, array or the value of a Map. - * - * @param type the type to inspect - * - * @return Returns the type of elements of an Iterable, array or the value of a Map. - * null is returned in case the type is not indexable (in the context of JSR 303). + * Determines the type of the elements of an {@code Iterable}, array or the value of a {@code Map}. */ - public static Type getIndexedType(Type type) { + public static Type getCollectionElementType(Type type) { Type indexedType = null; if ( isIterable( type ) && type instanceof ParameterizedType ) { ParameterizedType paramType = (ParameterizedType) type; @@ -298,6 +282,21 @@ else if ( TypeHelper.isArray( type ) ) { return indexedType; } + /** + * Indicates if the type is considered indexable (ie is a {@code List}, an array or a {@code Map}). + *

+ * Note that it does not include {@code Set}s as they are not indexable. + * + * @param type the type to inspect. + * + * @return Returns true if the type is indexable. + */ + public static boolean isIndexable(Type type) { + return isList( type ) || + isMap( type ) || + TypeHelper.isArray( type ); + } + /** * Converts the given Type to a Class. * diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/util/ReflectionHelperTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/util/ReflectionHelperTest.java index 636c682e91..6ee58c2f97 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/util/ReflectionHelperTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/util/ReflectionHelperTest.java @@ -6,6 +6,12 @@ */ package org.hibernate.validator.test.internal.util; +import static org.fest.assertions.Assertions.assertThat; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNull; +import static org.testng.Assert.assertTrue; + import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.ArrayList; @@ -14,23 +20,19 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.SortedMap; import java.util.TreeSet; -import org.testng.annotations.Test; - import org.hibernate.validator.internal.util.ReflectionHelper; import org.hibernate.validator.testutil.TestForIssue; - -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertNull; -import static org.testng.Assert.assertTrue; +import org.testng.annotations.Test; /** * Tests for the {@code ReflectionHelper}. * * @author Hardy Ferentschik + * @author Guillaume Smet */ public class ReflectionHelperTest { @@ -51,27 +53,63 @@ public void testIsIterable() throws Exception { } @Test - public void testIsMap() throws Exception { - assertTrue( ReflectionHelper.isMap( Map.class ) ); - assertTrue( ReflectionHelper.isMap( SortedMap.class ) ); + public void testIsCollection() throws Exception { + assertTrue( ReflectionHelper.isCollection( Iterable.class ) ); + assertTrue( ReflectionHelper.isCollection( Collection.class ) ); - Type type = TestTypes.class.getField( "objectMap" ).getGenericType(); - assertTrue( ReflectionHelper.isMap( type ) ); + assertTrue( ReflectionHelper.isCollection( List.class ) ); + Type type = TestTypes.class.getField( "stringList" ).getGenericType(); + assertTrue( ReflectionHelper.isCollection( type ) ); - assertFalse( ReflectionHelper.isMap( null ) ); - assertFalse( ReflectionHelper.isMap( Object.class ) ); + assertTrue( ReflectionHelper.isCollection( TreeSet.class ) ); + assertTrue( ReflectionHelper.isCollection( HashSet.class ) ); + type = TestTypes.class.getField( "floatSet" ).getGenericType(); + assertTrue( ReflectionHelper.isCollection( type ) ); + + assertTrue( ReflectionHelper.isCollection( Map.class ) ); + assertTrue( ReflectionHelper.isCollection( SortedMap.class ) ); + type = TestTypes.class.getField( "objectMap" ).getGenericType(); + assertTrue( ReflectionHelper.isCollection( type ) ); + + assertTrue( ReflectionHelper.isCollection( int[].class ) ); + assertTrue( ReflectionHelper.isCollection( String[].class ) ); + type = TestTypes.class.getField( "stringArray" ).getGenericType(); + assertTrue( ReflectionHelper.isCollection( type ) ); + type = TestTypes.class.getField( "intArray" ).getGenericType(); + assertTrue( ReflectionHelper.isCollection( type ) ); + + assertFalse( ReflectionHelper.isCollection( null ) ); + assertFalse( ReflectionHelper.isCollection( Object.class ) ); } @Test - public void testGetIndexedType() throws Exception { + public void testGetCollectionElementType() throws Exception { Type type = TestTypes.class.getField( "stringList" ).getGenericType(); - assertEquals( String.class, ReflectionHelper.getIndexedType( type ) ); + assertThat( ReflectionHelper.getCollectionElementType( type ) ).isEqualTo( String.class ); - type = TestTypes.class.getField( "objectMap" ).getGenericType(); - assertEquals( Object.class, ReflectionHelper.getIndexedType( type ) ); + type = TestTypes.class.getField( "floatSet" ).getGenericType(); + assertThat( ReflectionHelper.getCollectionElementType( type ) ).isEqualTo( Float.class ); type = TestTypes.class.getField( "stringArray" ).getGenericType(); - assertEquals( String.class, ReflectionHelper.getIndexedType( type ) ); + assertThat( ReflectionHelper.getCollectionElementType( type ) ).isEqualTo( String.class ); + + type = TestTypes.class.getField( "objectMap" ).getGenericType(); + assertThat( ReflectionHelper.getCollectionElementType( type ) ).isEqualTo( Object.class ); + + type = TestTypes.class.getField( "intArray" ).getGenericType(); + assertThat( ReflectionHelper.getCollectionElementType( type ) ).isEqualTo( int.class ); + } + + @Test + public void testIsMap() throws Exception { + assertTrue( ReflectionHelper.isMap( Map.class ) ); + assertTrue( ReflectionHelper.isMap( SortedMap.class ) ); + + Type type = TestTypes.class.getField( "objectMap" ).getGenericType(); + assertTrue( ReflectionHelper.isMap( type ) ); + + assertFalse( ReflectionHelper.isMap( null ) ); + assertFalse( ReflectionHelper.isMap( Object.class ) ); } @Test @@ -123,8 +161,10 @@ public void testIsGetterMethod() throws Exception { @SuppressWarnings("unused") private static class TestTypes { public List stringList; + public Set floatSet; public Map objectMap; public String[] stringArray; + public int[] intArray; } @SuppressWarnings("unused") From bcfd0359998d5c35bb7e24aea03764e54e754b61 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Mon, 5 Dec 2016 11:12:32 +0100 Subject: [PATCH 085/124] HV-1176 Fix type argument constraints detection. They could be ignored if they were the only constraints of a method's parameters or return value. This issue was detected by separating the tests of List and Optional: the presence of an @Valid annotation for the List made the test work. --- .../TypeAnnotationConstraintTest.java | 80 +++++++++++++++++++ .../metadata/raw/ConstrainedExecutable.java | 25 +++--- .../metadata/raw/ConstrainedField.java | 8 +- .../metadata/raw/ConstrainedParameter.java | 8 +- 4 files changed, 106 insertions(+), 15 deletions(-) diff --git a/engine-jdk8-tests/src/test/java/org/hibernate/validator/test/internal/engine/typeannotationconstraint/TypeAnnotationConstraintTest.java b/engine-jdk8-tests/src/test/java/org/hibernate/validator/test/internal/engine/typeannotationconstraint/TypeAnnotationConstraintTest.java index 5da294edce..735a80309e 100644 --- a/engine-jdk8-tests/src/test/java/org/hibernate/validator/test/internal/engine/typeannotationconstraint/TypeAnnotationConstraintTest.java +++ b/engine-jdk8-tests/src/test/java/org/hibernate/validator/test/internal/engine/typeannotationconstraint/TypeAnnotationConstraintTest.java @@ -624,6 +624,68 @@ public void getter_constraint_provided_on_type_parameter_of_an_optional_gets_val ); } + @Test + public void return_value_constraint_provided_on_type_parameter_of_an_optional_gets_validated() throws Exception { + Method method = TypeWithOptional6.class.getDeclaredMethod( "returnStringOptional" ); + Set> constraintViolations = validator.forExecutables().validateReturnValue( + new TypeWithOptional6(), + method, + Optional.of( "" ) + ); + assertNumberOfViolations( constraintViolations, 1 ); + assertCorrectPropertyPaths( + constraintViolations, + "returnStringOptional." + ); + assertCorrectConstraintTypes( + constraintViolations, + NotBlankTypeUse.class + ); + } + + @Test + public void method_parameter_constraint_provided_as_type_parameter_of_an_optional_gets_validated() + throws Exception { + Method method = TypeWithOptional7.class.getDeclaredMethod( "setValues", Optional.class ); + Object[] values = new Object[] { Optional.of( "" ) }; + + Set> constraintViolations = validator.forExecutables().validateParameters( + new TypeWithOptional7(), + method, + values + ); + assertNumberOfViolations( constraintViolations, 1 ); + assertCorrectPropertyPaths( + constraintViolations, + "setValues.arg0" + ); + assertCorrectConstraintTypes( + constraintViolations, + NotBlankTypeUse.class + ); + } + + @Test + public void constructor_parameter_constraint_provided_on_type_parameter_of_an_optional_gets_validated() + throws Exception { + Constructor constructor = TypeWithOptional8.class.getDeclaredConstructor( Optional.class ); + Object[] values = new Object[] { Optional.of( "" ) }; + + Set> constraintViolations = validator.forExecutables().validateConstructorParameters( + constructor, + values + ); + assertNumberOfViolations( constraintViolations, 1 ); + assertCorrectPropertyPaths( + constraintViolations, + "TypeWithOptional8.arg0" + ); + assertCorrectConstraintTypes( + constraintViolations, + NotBlankTypeUse.class + ); + } + // No unwrapper available @Test(expectedExceptions = ValidationException.class, expectedExceptionsMessageRegExp = "HV000182.*") @@ -822,6 +884,24 @@ static class TypeWithOptional5 { } } + static class TypeWithOptional6 { + Optional stringOptional; + + public Optional<@NotNullTypeUse @NotBlankTypeUse String> returnStringOptional() { + return stringOptional; + } + } + + static class TypeWithOptional7 { + public void setValues(Optional<@NotBlankTypeUse String> optionalParameter) { + } + } + + static class TypeWithOptional8 { + public TypeWithOptional8(Optional<@NotBlankTypeUse String> optionalParameter) { + } + } + // No wrapper available static class Bar { diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedExecutable.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedExecutable.java index 6439749761..0ed61f27b9 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedExecutable.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedExecutable.java @@ -27,9 +27,10 @@ /** * Represents a method or constructor of a Java type and all its associated * meta-data relevant in the context of bean validation, for instance the - * constraints at it's parameters or return value. + * constraints at its parameters or return value. * * @author Gunnar Morling + * @author Guillaume Smet */ public class ConstrainedExecutable extends AbstractConstrainedElement { @@ -85,18 +86,16 @@ public ConstrainedExecutable( * * @param source The source of meta data. * @param location The location of the represented executable. - * @param parameterMetaData A list with parameter meta data. The length must correspond - * with the number of parameters of the represented executable. So - * this list may be empty (in case of a parameterless executable), - * but never {@code null}. + * @param parameterMetaData A list with parameter meta data. The length must correspond with the number of + * parameters of the represented executable. So this list may be empty (in case of a parameterless executable), but + * never {@code null}. * @param crossParameterConstraints the cross parameter constraints - * @param returnValueConstraints The return value constraints of the represented executable, if - * any. - * @param typeArgumentsConstraints The return value constraints of the represented executable, if - * any. + * @param returnValueConstraints The return value constraints of the represented executable, if any. + * @param typeArgumentsConstraints The type argument constraints on the return value of the represented executable, + * if any. * @param groupConversions The group conversions of the represented executable, if any. - * @param isCascading Whether a cascaded validation of the represented executable's - * return value shall be performed or not. + * @param isCascading Whether a cascaded validation of the represented executable's return value shall be performed + * or not. * @param unwrapMode Determines how the value of the executable's return value must be handled in regards to * unwrapping prior to validation. */ @@ -190,7 +189,7 @@ public Set> getCrossParameterConstraints() { */ @Override public boolean isConstrained() { - return super.isConstrained() || hasParameterConstraints; + return super.isConstrained() || !typeArgumentsConstraints.isEmpty() || hasParameterConstraints; } /** @@ -219,7 +218,7 @@ public ExecutableElement getExecutable() { } public Set> getTypeArgumentsConstraints() { - return this.typeArgumentsConstraints; + return typeArgumentsConstraints; } @Override diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedField.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedField.java index b2abe05895..c391b180de 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedField.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedField.java @@ -19,6 +19,7 @@ * in the context of bean validation, for instance its constraints. * * @author Gunnar Morling + * @author Guillaume Smet */ public class ConstrainedField extends AbstractConstrainedElement { @@ -53,7 +54,12 @@ public ConstrainedField(ConfigurationSource source, } public Set> getTypeArgumentsConstraints() { - return this.typeArgumentsConstraints; + return typeArgumentsConstraints; + } + + @Override + public boolean isConstrained() { + return super.isConstrained() || !typeArgumentsConstraints.isEmpty(); } @Override diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedParameter.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedParameter.java index 253a553cea..e85cdca682 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedParameter.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/raw/ConstrainedParameter.java @@ -22,6 +22,7 @@ * Contains constraint-related meta-data for one method parameter. * * @author Gunnar Morling + * @author Guillaume Smet */ public class ConstrainedParameter extends AbstractConstrainedElement { @@ -107,7 +108,12 @@ public int getIndex() { } public Set> getTypeArgumentsConstraints() { - return this.typeArgumentsConstraints; + return typeArgumentsConstraints; + } + + @Override + public boolean isConstrained() { + return super.isConstrained() || !typeArgumentsConstraints.isEmpty(); } /** From 84314d9952e0ca8805cf9dfa75954c5168cf5256 Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Thu, 8 Dec 2016 10:09:41 +0100 Subject: [PATCH 086/124] HV-1183 Upgrading to JodaTime 2.9.5; adding integration test for JodaTime/JSoup constraints/validators --- .../wildfly/OptionalConstraintsIT.java | 83 +++++++++++++++++++ ...loyment-structure-optional-constraints.xml | 17 ++++ pom.xml | 2 +- 3 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 integration/src/test/java/org/hibernate/validator/integration/wildfly/OptionalConstraintsIT.java create mode 100644 integration/src/test/resources/jboss-deployment-structure-optional-constraints.xml diff --git a/integration/src/test/java/org/hibernate/validator/integration/wildfly/OptionalConstraintsIT.java b/integration/src/test/java/org/hibernate/validator/integration/wildfly/OptionalConstraintsIT.java new file mode 100644 index 0000000000..ac45d166d8 --- /dev/null +++ b/integration/src/test/java/org/hibernate/validator/integration/wildfly/OptionalConstraintsIT.java @@ -0,0 +1,83 @@ +/* + * Hibernate Validator, declare and validate application constraints + * + * License: Apache License, Version 2.0 + * See the license.txt file in the root directory or . + */ +package org.hibernate.validator.integration.wildfly; + +import static org.junit.Assert.assertEquals; + +import java.util.Set; + +import javax.inject.Inject; +import javax.validation.ConstraintViolation; +import javax.validation.Validator; +import javax.validation.constraints.Future; + +import org.hibernate.validator.constraints.SafeHtml; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.junit.Arquillian; +import org.jboss.shrinkwrap.api.Archive; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.asset.EmptyAsset; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.joda.time.DateTime; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * Asserts that the constraints based on the JodaTime and JSoup server modules can be used. + * + * @author Gunnar Morling + */ +@RunWith(Arquillian.class) +public class OptionalConstraintsIT { + + private static final String WAR_FILE_NAME = OptionalConstraintsIT.class + .getSimpleName() + ".war"; + + public static class Shipment { + + @Future + public DateTime deliveryDate = new DateTime( 2014, 10, 21, 0, 0, 0, 0 ); + } + + public static class Item { + + @SafeHtml + public String descriptionHtml = " + + + + jdk9 + + 9 + + + + --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED + + + diff --git a/integration/src/test/resources/arquillian.xml b/integration/src/test/resources/arquillian.xml index 019be85654..d6389164db 100644 --- a/integration/src/test/resources/arquillian.xml +++ b/integration/src/test/resources/arquillian.xml @@ -20,8 +20,14 @@ ${basedir}/target/wildfly-${wildfly.version} - + + ${arquillian.javaVmArguments.add-opens} + + - \ No newline at end of file + diff --git a/pom.xml b/pom.xml index c047f0846d..2239246432 100644 --- a/pom.xml +++ b/pom.xml @@ -126,18 +126,28 @@ 7.1 + 2.4.8-SNAPSHOT + - 2.18.1 + 2.18.1 - - + + + - - java.xml.bind + + java.xml.bind + java.xml.bind + + + @@ -245,7 +255,7 @@ org.codehaus.groovy groovy-jsr223 - 2.4.7 + ${groovy.version} org.easymock @@ -484,19 +494,19 @@ maven-surefire-plugin - ${maven.surefire.version} + ${maven-surefire-plugin.version} once true **/*Test.java - ${surefire.argLine} ${surefire.argLine.extension} + ${maven-surefire-plugin.argLine} ${maven-surefire-plugin.argLine.add-modules} ${maven-surefire-plugin.argLine.add-opens} maven-surefire-report-plugin - ${maven.surefire.version} + ${maven-surefire-plugin.version} generate-test-report @@ -513,7 +523,7 @@ maven-failsafe-plugin - ${maven.surefire.version} + ${maven-surefire-plugin.version} integration-test @@ -521,6 +531,9 @@ integration-test verify + + ${maven-surefire-plugin.argLine} ${maven-surefire-plugin.argLine.add-modules} ${maven-surefire-plugin.argLine.add-opens} + @@ -653,9 +666,16 @@ ${org.codehaus.mojo.chronos.version} - org.codehaus.gmaven - gmaven-plugin + org.codehaus.gmavenplus + gmavenplus-plugin 1.5 + + + org.codehaus.groovy + groovy-all + ${groovy.version} + + org.apache.servicemix.tooling @@ -749,13 +769,13 @@ - org.codehaus.gmaven + org.codehaus.gmavenplus - gmaven-plugin + gmavenplus-plugin - [1.4,) + [1.5,) execute @@ -879,7 +899,23 @@ 9 - --add-modules ${jigsaw.modules} + --add-modules=${maven-surefire-plugin.jigsaw.modules} + + --add-opens=java.base/java.lang=ALL-UNNAMED + --add-opens=java.base/java.lang.reflect=ALL-UNNAMED + --add-opens=java.base/java.security=ALL-UNNAMED + --add-opens=java.base/java.math=ALL-UNNAMED + --add-opens=java.base/java.io=ALL-UNNAMED + --add-opens=java.base/java.net=ALL-UNNAMED + --add-opens=java.base/java.util=ALL-UNNAMED + --add-opens=java.base/java.util.concurrent=ALL-UNNAMED + --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED + --add-opens=java.base/java.util.concurrent.locks=ALL-UNNAMED + --add-opens=java.base/jdk.internal.reflect=ALL-UNNAMED + --add-opens=java.management/javax.management=ALL-UNNAMED + --add-opens=java.management/javax.management.openmbean=ALL-UNNAMED + --add-opens=java.naming/javax.naming=ALL-UNNAMED + diff --git a/settings-example.xml b/settings-example.xml index e96f41de72..7a1c8e0c4b 100644 --- a/settings-example.xml +++ b/settings-example.xml @@ -31,6 +31,18 @@ never + + jfrog-snapshots + JFrog snapshots repository for Groovy + https://oss.jfrog.org/oss-snapshot-local/ + + false + + + true + never + + @@ -57,6 +69,18 @@ never + + jfrog-snapshots + JFrog snapshots repository for Groovy + https://oss.jfrog.org/oss-snapshot-local/ + + false + + + true + never + + diff --git a/tck-runner/pom.xml b/tck-runner/pom.xml index 14583fd31c..742b837456 100644 --- a/tck-runner/pom.xml +++ b/tck-runner/pom.xml @@ -184,8 +184,8 @@ - org.codehaus.gmaven - gmaven-plugin + org.codehaus.gmavenplus + gmavenplus-plugin configure-properties @@ -194,11 +194,13 @@ execute - - + + + @@ -241,6 +243,7 @@ + --add-opens java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED Servlet 3.0 @@ -315,8 +318,8 @@ - org.codehaus.gmaven - gmaven-plugin + org.codehaus.gmavenplus + gmavenplus-plugin update-modules @@ -325,7 +328,9 @@ execute - ${pom.basedir}/src/script/setupModules.groovy + + + @@ -334,7 +339,7 @@ org.apache.maven.plugins maven-surefire-plugin - -Xmx1024m -Djava.util.logging.manager=org.jboss.logmanager.LogManager ${surefire.argLine.extension} + -Xmx1024m -Djava.util.logging.manager=org.jboss.logmanager.LogManager ${maven-surefire-plugin.argLine.add-modules} ${maven-surefire-plugin.argLine.add-opens} once incontainer diff --git a/tck-runner/src/test/resources/arquillian.xml b/tck-runner/src/test/resources/arquillian.xml index a3e6420779..0370cd97e0 100644 --- a/tck-runner/src/test/resources/arquillian.xml +++ b/tck-runner/src/test/resources/arquillian.xml @@ -20,7 +20,8 @@ ${wildflyTargetDir} - -Xmx1024m -XX:MaxPermSize=512m ${remote.debug} + ${arquillian.javaVmArguments.add-opens} + -Xmx1024m -XX:MaxPermSize=512m ${remote.debug} -Dvalidation.provider=${validation.provider} true From af909082976a3c05b367773dc5b67c90db6e1fad Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Thu, 15 Dec 2016 14:01:03 +0100 Subject: [PATCH 092/124] HV-1187 Update README.md with current JDK9 support --- README.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 1033f9135c..5f5e2256d9 100644 --- a/README.md +++ b/README.md @@ -84,15 +84,19 @@ There are more build options available as well. For more information refer to [C To build Hibernate Validator with JDK 9, export the following environment variable: - export MAVEN_OPTS="--add-modules java.annotations.common,java.xml.bind --add-opens=java.base/java.security=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED" + export MAVEN_OPTS="--add-modules java.annotations.common,java.xml.bind --add-opens=java.base/java.security=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED" Then the build can be started like this: - mvn -s settings-example.xml clean install -DdisableDocumentationBuild=true -DdisableDistributionBuild + mvn -s settings-example.xml clean install + +Also the OSGi integration tests will fail on Java 9 currently, hence the "osgi" module is excluded automatically when building on JDK 9. We are waiting for the release of Karaf 4.1.0. -The documentation and distribution modules are known to not work on Java 9 for the time being, hence they need to be excluded. -Also the integration tests on WildFly will fail on Java 9 currently, hence this "integration" module is excluded automatically when building on JDK 9. +Here are the reasons why we added the various --add-opens options: + * java.security: required by wildfly-maven-plugin:execute-commands (for the WildFly integration tests and the TCK runner running in container mode) + * java.lang: required by JRuby for Asciidoc processing + * java.util: required by the gmavenplus script used to start WildFly ## Continuous Integration From 2679011ed01b2c1e4e2a299f282a636a2b65c266 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Sat, 17 Dec 2016 08:24:37 +0100 Subject: [PATCH 093/124] HV-1187 Only use Groovy 2.4.8-SNAPSHOT for JDK 9 --- pom.xml | 89 +++++++++++++++++++++++++++++++++++++++++++- settings-example.xml | 24 ------------ 2 files changed, 88 insertions(+), 25 deletions(-) diff --git a/pom.xml b/pom.xml index 2239246432..2d601fd8b7 100644 --- a/pom.xml +++ b/pom.xml @@ -126,7 +126,8 @@ 7.1 - 2.4.8-SNAPSHOT + + 2.4.7 --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED @@ -916,7 +921,89 @@ --add-opens=java.management/javax.management.openmbean=ALL-UNNAMED --add-opens=java.naming/javax.naming=ALL-UNNAMED + + 2.4.8-SNAPSHOT + + + + + central + Maven Central + http://repo.maven.apache.org/maven2/ + + false + never + + + + jboss-public-repository-group + JBoss Public Maven Repository Group + https://repository.jboss.org/nexus/content/groups/public-jboss/ + default + + true + never + + + true + never + + + + jfrog-snapshots + JFrog snapshots repository for Groovy + https://oss.jfrog.org/oss-snapshot-local/ + + false + + + true + never + + + + + + + central + Maven Central + http://repo.maven.apache.org/maven2/ + + false + never + + + + jboss-public-repository-group + JBoss Public Maven Repository Group + https://repository.jboss.org/nexus/content/groups/public-jboss/ + default + + true + never + + + true + never + + + + jfrog-snapshots + JFrog snapshots repository for Groovy + https://oss.jfrog.org/oss-snapshot-local/ + + false + + + true + never + + + diff --git a/settings-example.xml b/settings-example.xml index 7a1c8e0c4b..e96f41de72 100644 --- a/settings-example.xml +++ b/settings-example.xml @@ -31,18 +31,6 @@ never - - jfrog-snapshots - JFrog snapshots repository for Groovy - https://oss.jfrog.org/oss-snapshot-local/ - - false - - - true - never - - @@ -69,18 +57,6 @@ never - - jfrog-snapshots - JFrog snapshots repository for Groovy - https://oss.jfrog.org/oss-snapshot-local/ - - false - - - true - never - - From 243d71fe6a1f883b79679d952c6c518903dbc072 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Mon, 19 Dec 2016 10:40:27 +0100 Subject: [PATCH 094/124] HV-1187 Fix incontainer build which was broken by latest changes --- pom.xml | 15 ++++++++++++++- tck-runner/pom.xml | 4 ++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 2d601fd8b7..a7dccbe28e 100644 --- a/pom.xml +++ b/pom.xml @@ -502,7 +502,7 @@ **/*Test.java - ${maven-surefire-plugin.argLine} ${maven-surefire-plugin.argLine.add-modules} ${maven-surefire-plugin.argLine.add-opens} + ${maven-surefire-plugin.argLine} @@ -924,6 +924,19 @@ 2.4.8-SNAPSHOT + + + + + maven-surefire-plugin + ${maven-surefire-plugin.version} + + ${maven-surefire-plugin.argLine} ${maven-surefire-plugin.argLine.add-modules} ${maven-surefire-plugin.argLine.add-opens} + + + + + - 2.4.7 + 2.4.8 - 2.4.8-SNAPSHOT @@ -937,86 +934,6 @@ - - - - - central - Maven Central - http://repo.maven.apache.org/maven2/ - - false - never - - - - jboss-public-repository-group - JBoss Public Maven Repository Group - https://repository.jboss.org/nexus/content/groups/public-jboss/ - default - - true - never - - - true - never - - - - jfrog-snapshots - JFrog snapshots repository for Groovy - https://oss.jfrog.org/oss-snapshot-local/ - - false - - - true - never - - - - - - - central - Maven Central - http://repo.maven.apache.org/maven2/ - - false - never - - - - jboss-public-repository-group - JBoss Public Maven Repository Group - https://repository.jboss.org/nexus/content/groups/public-jboss/ - default - - true - never - - - true - never - - - - jfrog-snapshots - JFrog snapshots repository for Groovy - https://oss.jfrog.org/oss-snapshot-local/ - - false - - - true - never - - - From 5e442207924b6ed1a6de3270769bf93d92bba795 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Fri, 20 Jan 2017 13:36:55 +0100 Subject: [PATCH 096/124] Add .checkstyle to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f90abb3a7c..af68ba4e0b 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,7 @@ atlassian-ide-plugin.xml .project .settings .factorypath +.checkstyle .externalToolBuilders maven-eclipse.xml From 8b8904704a4b5e3fb54237d18d3eec0e6a1db891 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Fri, 20 Jan 2017 10:02:06 +0100 Subject: [PATCH 097/124] Fix minor typo in a comment --- .../engine/constraintvalidation/ConstraintValidatorManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/constraintvalidation/ConstraintValidatorManager.java b/engine/src/main/java/org/hibernate/validator/internal/engine/constraintvalidation/ConstraintValidatorManager.java index 6bd0faac84..cd8d671461 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/constraintvalidation/ConstraintValidatorManager.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/constraintvalidation/ConstraintValidatorManager.java @@ -80,7 +80,7 @@ public ConstraintValidatorManager(ConstraintValidatorFactory constraintValidator /** * @param validatedValueType the type of the value to be validated. Cannot be {@code null}. - * @param descriptor the constraint descriptor for which to get an initalized constraint validator. Cannot be {@code null} + * @param descriptor the constraint descriptor for which to get an initialized constraint validator. Cannot be {@code null} * @param constraintFactory constraint factory used to instantiate the constraint validator. Cannot be {@code null}. * @param the type of the value to be validated * @param the annotation type From 8e717e48a1842f5707b06df7ec02999394beffeb Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Fri, 20 Jan 2017 10:02:23 +0100 Subject: [PATCH 098/124] HV-1220 Make programmatically defined cross parameter constraints on the parameters of a method returning void work as expected The location used was the one of a return value so it kinda worked if the method had parameters as the return value type was Object which is supported for cross parameter constraints but it failed as long as the return value type was void. --- .../cfg/context/ConfiguredConstraint.java | 8 +++- ...ParameterConstraintMappingContextImpl.java | 2 +- .../PropertyConstraintMappingContextImpl.java | 2 +- ...turnValueConstraintMappingContextImpl.java | 2 +- .../test/cfg/MethodConstraintMappingTest.java | 39 +++++++++++++++++++ 5 files changed, 49 insertions(+), 4 deletions(-) diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConfiguredConstraint.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConfiguredConstraint.java index 03b1967148..b063ef492e 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConfiguredConstraint.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ConfiguredConstraint.java @@ -59,12 +59,18 @@ public static ConfiguredConstraint forParameter(Constr ); } - public static ConfiguredConstraint forExecutable(ConstraintDef constraint, ExecutableElement executable) { + public static ConfiguredConstraint forReturnValue(ConstraintDef constraint, ExecutableElement executable) { return new ConfiguredConstraint( constraint, ConstraintLocation.forReturnValue( executable ), executable.getElementType() ); } + public static ConfiguredConstraint forCrossParameter(ConstraintDef constraint, ExecutableElement executable) { + return new ConfiguredConstraint( + constraint, ConstraintLocation.forCrossParameter( executable ), executable.getElementType() + ); + } + public ConstraintDef getConstraint() { return constraint; } diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/CrossParameterConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/CrossParameterConstraintMappingContextImpl.java index 1151df70c2..8f1c8d340a 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/CrossParameterConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/CrossParameterConstraintMappingContextImpl.java @@ -32,7 +32,7 @@ final class CrossParameterConstraintMappingContextImpl @Override public CrossParameterConstraintMappingContext constraint(ConstraintDef definition) { - super.addConstraint( ConfiguredConstraint.forExecutable( definition, executableContext.getExecutable() ) ); + super.addConstraint( ConfiguredConstraint.forCrossParameter( definition, executableContext.getExecutable() ) ); return this; } diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/PropertyConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/PropertyConstraintMappingContextImpl.java index 52d4acc88d..36c50acfb2 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/PropertyConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/PropertyConstraintMappingContextImpl.java @@ -62,7 +62,7 @@ public PropertyConstraintMappingContext constraint(ConstraintDef definitio } else { super.addConstraint( - ConfiguredConstraint.forExecutable( + ConfiguredConstraint.forReturnValue( definition, ExecutableElement.forMethod( (Method) member ) ) ); diff --git a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ReturnValueConstraintMappingContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ReturnValueConstraintMappingContextImpl.java index e903c2d30c..f71d85babb 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ReturnValueConstraintMappingContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/cfg/context/ReturnValueConstraintMappingContextImpl.java @@ -39,7 +39,7 @@ protected ReturnValueConstraintMappingContext getThis() { @Override public ReturnValueConstraintMappingContext constraint(ConstraintDef definition) { - super.addConstraint( ConfiguredConstraint.forExecutable( definition, executableContext.getExecutable() ) ); + super.addConstraint( ConfiguredConstraint.forReturnValue( definition, executableContext.getExecutable() ) ); return this; } diff --git a/engine/src/test/java/org/hibernate/validator/test/cfg/MethodConstraintMappingTest.java b/engine/src/test/java/org/hibernate/validator/test/cfg/MethodConstraintMappingTest.java index ce6fb88428..f62d73d4e2 100644 --- a/engine/src/test/java/org/hibernate/validator/test/cfg/MethodConstraintMappingTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/cfg/MethodConstraintMappingTest.java @@ -666,6 +666,38 @@ public void crossParameterConstraint() { } } + @Test + @TestForIssue(jiraKey = "HV-1220") + public void crossParameterConstraintOnMethodReturningVoid() { + ConstraintMapping mapping = config.createConstraintMapping(); + mapping.type( GreetingService.class ) + .method( "sayNothing", String.class ) + .crossParameter() + .constraint( + new GenericConstraintDef( + GenericAndCrossParameterConstraint.class + ) + ); + config.addMapping( mapping ); + + try { + GreetingService service = getValidatingProxy( + wrappedObject, + config.buildValidatorFactory().getValidator() + ); + service.sayNothing( "" ); + + fail( "Expected exception wasn't thrown." ); + } + catch (ConstraintViolationException e) { + + assertCorrectConstraintViolationMessages( + e, "default message" + ); + assertCorrectPropertyPaths( e, "sayNothing." ); + } + } + private interface TestGroup { } @@ -708,6 +740,8 @@ public interface GreetingService { User getUser(); + void sayNothing(String string1); + } public class GreetingServiceImpl implements GreetingService { @@ -747,5 +781,10 @@ public Message getHello() { public User getUser() { return new User( null ); } + + @Override + public void sayNothing(String string1) { + // Nothing to do + } } } From a8db9cdf54769a62d684bb5e9a51938299e58bc2 Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Wed, 1 Mar 2017 12:05:25 +0100 Subject: [PATCH 099/124] HV-1266 Updating build instructions to reflect relocation of @Generated --- README.md | 4 ++-- pom.xml | 11 ++++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5f5e2256d9..5008c2f0e1 100644 --- a/README.md +++ b/README.md @@ -84,13 +84,13 @@ There are more build options available as well. For more information refer to [C To build Hibernate Validator with JDK 9, export the following environment variable: - export MAVEN_OPTS="--add-modules java.annotations.common,java.xml.bind --add-opens=java.base/java.security=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED" + export MAVEN_OPTS="--add-opens=java.base/java.security=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED" Then the build can be started like this: mvn -s settings-example.xml clean install -Also the OSGi integration tests will fail on Java 9 currently, hence the "osgi" module is excluded automatically when building on JDK 9. We are waiting for the release of Karaf 4.1.0. +Also the OSGi integration tests will fail on Java 9 currently, hence the "osgi" module is excluded automatically when building on JDK 9. We are waiting for the release of a Karaf version supporting the latest Java 9 builds. Here are the reasons why we added the various --add-opens options: diff --git a/pom.xml b/pom.xml index 0473850a45..85fe3cf066 100644 --- a/pom.xml +++ b/pom.xml @@ -392,7 +392,7 @@ maven-compiler-plugin - 3.5.1 + 3.6.1 -parameters @@ -924,6 +924,15 @@ + + maven-compiler-plugin + + true + + -J--add-modules=java.xml.ws.annotation + + + maven-surefire-plugin ${maven-surefire-plugin.version} From 27370d3215e96d3be720a30813e45c461d0af325 Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Tue, 14 Mar 2017 11:57:04 +0100 Subject: [PATCH 100/124] HV-1280 Setting context class loader to HV's defining CL before calling into JAXB/JAXP; This makes sure we don't get in touch with a JAXP implementation provided as part of the deployed application when running on WF. --- .../internal/xml/ValidationXmlParser.java | 5 + .../internal/xml/XmlMappingParser.java | 31 ++-- .../integration/wildfly/xml/Camera.java | 15 ++ .../xml/JaxpContainedInDeploymentIT.java | 142 ++++++++++++++++++ 4 files changed, 184 insertions(+), 9 deletions(-) create mode 100644 integration/src/test/java/org/hibernate/validator/integration/wildfly/xml/Camera.java create mode 100644 integration/src/test/java/org/hibernate/validator/integration/wildfly/xml/JaxpContainedInDeploymentIT.java diff --git a/engine/src/main/java/org/hibernate/validator/internal/xml/ValidationXmlParser.java b/engine/src/main/java/org/hibernate/validator/internal/xml/ValidationXmlParser.java index c93371e9c0..35cf241e3f 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/xml/ValidationXmlParser.java +++ b/engine/src/main/java/org/hibernate/validator/internal/xml/ValidationXmlParser.java @@ -69,7 +69,11 @@ public final BootstrapConfiguration parseValidationXml() { return BootstrapConfigurationImpl.getDefaultBootstrapConfiguration(); } + ClassLoader previousTccl = Thread.currentThread().getContextClassLoader(); + try { + Thread.currentThread().setContextClassLoader( ValidationXmlParser.class.getClassLoader() ); + // HV-970 The parser helper is only loaded if there actually is a validation.xml file; // this avoids accessing javax.xml.stream.* (which does not exist on Android) when not actually // working with the XML configuration @@ -83,6 +87,7 @@ public final BootstrapConfiguration parseValidationXml() { return createBootstrapConfiguration( validationConfig ); } finally { + Thread.currentThread().setContextClassLoader( previousTccl ); closeStream( inputStream ); } } diff --git a/engine/src/main/java/org/hibernate/validator/internal/xml/XmlMappingParser.java b/engine/src/main/java/org/hibernate/validator/internal/xml/XmlMappingParser.java index 0ed463ab50..dd753eda7c 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/xml/XmlMappingParser.java +++ b/engine/src/main/java/org/hibernate/validator/internal/xml/XmlMappingParser.java @@ -137,15 +137,7 @@ public final void parse(Set mappingStreams) { in.mark( Integer.MAX_VALUE ); } - XMLEventReader xmlEventReader = xmlParserHelper.createXmlEventReader( "constraint mapping file", new CloseIgnoringInputStream( in ) ); - String schemaVersion = xmlParserHelper.getSchemaVersion( "constraint mapping file", xmlEventReader ); - String schemaResourceName = getSchemaResourceName( schemaVersion ); - Schema schema = xmlParserHelper.getSchema( schemaResourceName ); - - Unmarshaller unmarshaller = jc.createUnmarshaller(); - unmarshaller.setSchema( schema ); - - ConstraintMappingsType mapping = getValidationConfig( xmlEventReader, unmarshaller ); + ConstraintMappingsType mapping = unmarshal( jc, in ); String defaultPackage = mapping.getDefaultPackage(); parseConstraintDefinitions( @@ -180,6 +172,27 @@ public final void parse(Set mappingStreams) { } } + private ConstraintMappingsType unmarshal(JAXBContext jc, InputStream in) throws JAXBException { + ClassLoader previousTccl = Thread.currentThread().getContextClassLoader(); + + try { + Thread.currentThread().setContextClassLoader( ValidationXmlParser.class.getClassLoader() ); + + XMLEventReader xmlEventReader = xmlParserHelper.createXmlEventReader( "constraint mapping file", new CloseIgnoringInputStream( in ) ); + String schemaVersion = xmlParserHelper.getSchemaVersion( "constraint mapping file", xmlEventReader ); + String schemaResourceName = getSchemaResourceName( schemaVersion ); + Schema schema = xmlParserHelper.getSchema( schemaResourceName ); + + Unmarshaller unmarshaller = jc.createUnmarshaller(); + unmarshaller.setSchema( schema ); + + return getValidationConfig( xmlEventReader, unmarshaller ); + } + finally { + Thread.currentThread().setContextClassLoader( previousTccl ); + } + } + public final Set> getXmlConfiguredClasses() { return processedClasses; } diff --git a/integration/src/test/java/org/hibernate/validator/integration/wildfly/xml/Camera.java b/integration/src/test/java/org/hibernate/validator/integration/wildfly/xml/Camera.java new file mode 100644 index 0000000000..6ffdb34fca --- /dev/null +++ b/integration/src/test/java/org/hibernate/validator/integration/wildfly/xml/Camera.java @@ -0,0 +1,15 @@ +/* + * Hibernate Validator, declare and validate application constraints + * + * License: Apache License, Version 2.0 + * See the license.txt file in the root directory or . + */ +package org.hibernate.validator.integration.wildfly.xml; + +/** + * @author Gunnar Morling + */ +public class Camera { + + public String brand = null; +} diff --git a/integration/src/test/java/org/hibernate/validator/integration/wildfly/xml/JaxpContainedInDeploymentIT.java b/integration/src/test/java/org/hibernate/validator/integration/wildfly/xml/JaxpContainedInDeploymentIT.java new file mode 100644 index 0000000000..deb21cbd6b --- /dev/null +++ b/integration/src/test/java/org/hibernate/validator/integration/wildfly/xml/JaxpContainedInDeploymentIT.java @@ -0,0 +1,142 @@ +/* + * Hibernate Validator, declare and validate application constraints + * + * License: Apache License, Version 2.0 + * See the license.txt file in the root directory or . + */ +package org.hibernate.validator.integration.wildfly.xml; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; + +import java.util.Set; + +import javax.inject.Inject; +import javax.validation.ConstraintViolation; +import javax.validation.Validator; +import javax.validation.constraints.NotNull; + +import org.jboss.arquillian.container.test.api.Deployer; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.container.test.api.RunAsClient; +import org.jboss.arquillian.junit.Arquillian; +import org.jboss.arquillian.junit.InSequence; +import org.jboss.arquillian.test.api.ArquillianResource; +import org.jboss.shrinkwrap.api.Archive; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.asset.Asset; +import org.jboss.shrinkwrap.api.asset.EmptyAsset; +import org.jboss.shrinkwrap.api.asset.StringAsset; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.jboss.shrinkwrap.descriptor.api.Descriptors; +import org.jboss.shrinkwrap.descriptor.api.validationConfiguration11.ValidationConfigurationDescriptor; +import org.jboss.shrinkwrap.descriptor.api.validationMapping11.ValidationMappingDescriptor; +import org.jboss.shrinkwrap.resolver.api.maven.Maven; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * Test for https://hibernate.atlassian.net/browse/HV-1280. To reproduce the issue, the deployment must be done twice + * (it will only show up during the 2nd deploy), which is why the test is managing the deployment itself via client-side + * test methods. + * + * @author Gunnar Morling + */ +@RunWith(Arquillian.class) +public class JaxpContainedInDeploymentIT { + + private static final String WAR_FILE_NAME = JaxpContainedInDeploymentIT.class.getSimpleName() + ".war"; + + @ArquillianResource + private Deployer deployer; + + @Inject + private Validator validator; + + @Deployment(name = "jaxpit", managed = false) + public static Archive createTestArchive() { + return ShrinkWrap + .create( WebArchive.class, WAR_FILE_NAME ) + .addClass( Camera.class ) + .addAsResource( validationXml(), "META-INF/validation.xml" ) + .addAsResource( mappingXml(), "META-INF/my-mapping.xml" ) + .addAsLibrary( Maven.resolver().resolve( "xerces:xercesImpl:2.9.1" ).withoutTransitivity().asSingleFile() ) + .addAsResource( "log4j.properties" ) + .addAsWebInfResource( EmptyAsset.INSTANCE, "beans.xml" ); + } + + private static Asset validationXml() { + String validationXml = Descriptors.create( ValidationConfigurationDescriptor.class ) + .version( "1.1" ) + .constraintMapping( "META-INF/my-mapping.xml" ) + .exportAsString(); + return new StringAsset( validationXml ); + } + + private static Asset mappingXml() { + String mappingXml = Descriptors.create( ValidationMappingDescriptor.class ) + .version( "1.1" ) + .createBean() + .clazz( Camera.class.getName() ) + .createField() + .name( "brand" ) + .createConstraint() + .annotation( "javax.validation.constraints.NotNull" ) + .up() + .up() + .up() + .exportAsString(); + return new StringAsset( mappingXml ); + } + + @Test + @RunAsClient + @InSequence(0) + public void deploy1() throws Exception { + deployer.deploy( "jaxpit" ); + } + + @Test + @InSequence(1) + public void test1() throws Exception { + doTest(); + } + + @Test + @RunAsClient + @InSequence(2) + public void undeploy1() throws Exception { + deployer.undeploy( "jaxpit" ); + } + + @Test + @RunAsClient + @InSequence(3) + public void deploy2() throws Exception { + deployer.deploy( "jaxpit" ); + } + + @Test + @InSequence(4) + public void test2() throws Exception { + doTest(); + } + + @Test + @RunAsClient + @InSequence(5) + public void undeploy2() throws Exception { + deployer.undeploy( "jaxpit" ); + } + + private void doTest() { + Set> violations = validator.validate( new Camera() ); + + assertEquals( 1, violations.size() ); + assertSame( NotNull.class, violations.iterator() + .next() + .getConstraintDescriptor() + .getAnnotation() + .annotationType() ); + } +} From 72c638d78b499e4478c29a85b57b688465c7a218 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Wed, 15 Mar 2017 09:50:35 +0100 Subject: [PATCH 101/124] HV-1280 Use privileged actions to manipulate the class loader --- .../internal/xml/ValidationXmlParser.java | 19 ++++++++++++++++--- .../internal/xml/XmlMappingParser.java | 19 ++++++++++++++++--- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/engine/src/main/java/org/hibernate/validator/internal/xml/ValidationXmlParser.java b/engine/src/main/java/org/hibernate/validator/internal/xml/ValidationXmlParser.java index 35cf241e3f..3779b3b457 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/xml/ValidationXmlParser.java +++ b/engine/src/main/java/org/hibernate/validator/internal/xml/ValidationXmlParser.java @@ -9,6 +9,7 @@ import java.io.IOException; import java.io.InputStream; import java.security.AccessController; +import java.security.PrivilegedAction; import java.security.PrivilegedExceptionAction; import java.util.EnumSet; import java.util.HashMap; @@ -27,7 +28,9 @@ import org.hibernate.validator.internal.util.logging.Log; import org.hibernate.validator.internal.util.logging.LoggerFactory; +import org.hibernate.validator.internal.util.privilegedactions.GetClassLoader; import org.hibernate.validator.internal.util.privilegedactions.NewJaxbContext; +import org.hibernate.validator.internal.util.privilegedactions.SetContextClassLoader; import org.hibernate.validator.internal.util.privilegedactions.Unmarshal; /** @@ -69,10 +72,10 @@ public final BootstrapConfiguration parseValidationXml() { return BootstrapConfigurationImpl.getDefaultBootstrapConfiguration(); } - ClassLoader previousTccl = Thread.currentThread().getContextClassLoader(); + ClassLoader previousTccl = run( GetClassLoader.fromContext() ); try { - Thread.currentThread().setContextClassLoader( ValidationXmlParser.class.getClassLoader() ); + run( SetContextClassLoader.action( ValidationXmlParser.class.getClassLoader() ) ); // HV-970 The parser helper is only loaded if there actually is a validation.xml file; // this avoids accessing javax.xml.stream.* (which does not exist on Android) when not actually @@ -87,7 +90,7 @@ public final BootstrapConfiguration parseValidationXml() { return createBootstrapConfiguration( validationConfig ); } finally { - Thread.currentThread().setContextClassLoader( previousTccl ); + run( SetContextClassLoader.action( previousTccl ) ); closeStream( inputStream ); } } @@ -196,6 +199,16 @@ private EnumSet getValidatedExecutableTypes(DefaultValidatedExec return executableTypes; } + /** + * Runs the given privileged action, using a privileged block if required. + *

+ * NOTE: This must never be changed into a publicly available method to avoid execution of arbitrary + * privileged actions within HV's protection domain. + */ + private static T run(PrivilegedAction action) { + return System.getSecurityManager() != null ? AccessController.doPrivileged( action ) : action.run(); + } + /** * Runs the given privileged action, using a privileged block if required. *

diff --git a/engine/src/main/java/org/hibernate/validator/internal/xml/XmlMappingParser.java b/engine/src/main/java/org/hibernate/validator/internal/xml/XmlMappingParser.java index dd753eda7c..927325843a 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/xml/XmlMappingParser.java +++ b/engine/src/main/java/org/hibernate/validator/internal/xml/XmlMappingParser.java @@ -11,6 +11,7 @@ import java.io.InputStream; import java.lang.annotation.Annotation; import java.security.AccessController; +import java.security.PrivilegedAction; import java.security.PrivilegedExceptionAction; import java.util.Collections; import java.util.List; @@ -37,7 +38,9 @@ import org.hibernate.validator.internal.metadata.raw.ConstrainedType; import org.hibernate.validator.internal.util.logging.Log; import org.hibernate.validator.internal.util.logging.LoggerFactory; +import org.hibernate.validator.internal.util.privilegedactions.GetClassLoader; import org.hibernate.validator.internal.util.privilegedactions.NewJaxbContext; +import org.hibernate.validator.internal.util.privilegedactions.SetContextClassLoader; import org.hibernate.validator.internal.util.privilegedactions.Unmarshal; import static org.hibernate.validator.internal.util.CollectionHelper.newArrayList; @@ -173,10 +176,10 @@ public final void parse(Set mappingStreams) { } private ConstraintMappingsType unmarshal(JAXBContext jc, InputStream in) throws JAXBException { - ClassLoader previousTccl = Thread.currentThread().getContextClassLoader(); + ClassLoader previousTccl = run( GetClassLoader.fromContext() ); try { - Thread.currentThread().setContextClassLoader( ValidationXmlParser.class.getClassLoader() ); + run( SetContextClassLoader.action( XmlMappingParser.class.getClassLoader() ) ); XMLEventReader xmlEventReader = xmlParserHelper.createXmlEventReader( "constraint mapping file", new CloseIgnoringInputStream( in ) ); String schemaVersion = xmlParserHelper.getSchemaVersion( "constraint mapping file", xmlEventReader ); @@ -189,7 +192,7 @@ private ConstraintMappingsType unmarshal(JAXBContext jc, InputStream in) throws return getValidationConfig( xmlEventReader, unmarshaller ); } finally { - Thread.currentThread().setContextClassLoader( previousTccl ); + run( SetContextClassLoader.action( previousTccl ) ); } } @@ -382,6 +385,16 @@ private String getSchemaResourceName(String schemaVersion) { return schemaResource; } + /** + * Runs the given privileged action, using a privileged block if required. + *

+ * NOTE: This must never be changed into a publicly available method to avoid execution of arbitrary + * privileged actions within HV's protection domain. + */ + private static T run(PrivilegedAction action) { + return System.getSecurityManager() != null ? AccessController.doPrivileged( action ) : action.run(); + } + /** * Runs the given privileged action, using a privileged block if required. *

From 534c75ecc1dafe78dbc0561f63018cc5b3e02873 Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Wed, 15 Mar 2017 10:59:01 +0100 Subject: [PATCH 102/124] HV-1284 Re-enable security manager for local TCK execution --- documentation/src/main/asciidoc/ch01.asciidoc | 2 +- tck-runner/pom.xml | 28 +++---------------- tck-runner/src/test/resources/test.policy | 2 ++ 3 files changed, 7 insertions(+), 25 deletions(-) diff --git a/documentation/src/main/asciidoc/ch01.asciidoc b/documentation/src/main/asciidoc/ch01.asciidoc index 59b5ef3ae8..6d90241344 100644 --- a/documentation/src/main/asciidoc/ch01.asciidoc +++ b/documentation/src/main/asciidoc/ch01.asciidoc @@ -104,6 +104,7 @@ The following shows how to do this via a http://docs.oracle.com/javase/8/docs/te grant codeBase "file:path/to/hibernate-validator-{hvVersion}.jar" { permission java.lang.reflect.ReflectPermission "suppressAccessChecks"; permission java.lang.RuntimePermission "accessDeclaredMembers"; + permission java.lang.RuntimePermission "setContextClassLoader"; // Only needed when working with XML descriptors (validation.xml or XML constraint mappings) permission java.util.PropertyPermission "mapAnyUriToUri", "read"; @@ -321,4 +322,3 @@ To learn more about the validation of beans and properties, just continue readin <>. If you are interested in using Bean Validation for the validation of method pre- and postcondition refer to <>. In case your application has specific validation requirements have a look at <>. - diff --git a/tck-runner/pom.xml b/tck-runner/pom.xml index b3a3357a02..92ba7310f9 100644 --- a/tck-runner/pom.xml +++ b/tck-runner/pom.xml @@ -171,8 +171,10 @@ - - true + + LocalSecurityManagerTesting + + -Djava.security.manager -Djava.security.policy=${project.build.directory}/test-classes/test.policy -Djava.security.debug=access @@ -183,28 +185,6 @@ - - org.codehaus.gmavenplus - gmavenplus-plugin - - - configure-properties - validate - - execute - - - - - - - - - org.apache.maven.plugins maven-surefire-plugin diff --git a/tck-runner/src/test/resources/test.policy b/tck-runner/src/test/resources/test.policy index ab976dd95e..b2a4fbd1c6 100644 --- a/tck-runner/src/test/resources/test.policy +++ b/tck-runner/src/test/resources/test.policy @@ -26,6 +26,7 @@ grant codeBase "file:${localRepository}/org/hibernate/hibernate-validator/${project.version}/hibernate-validator-${project.version}.jar" { permission java.lang.reflect.ReflectPermission "suppressAccessChecks"; permission java.lang.RuntimePermission "accessDeclaredMembers"; + permission java.lang.RuntimePermission "setContextClassLoader"; // JAXB permission java.util.PropertyPermission "mapAnyUriToUri", "read"; @@ -36,6 +37,7 @@ grant codeBase "file:${localRepository}/org/hibernate/hibernate-validator/${proj grant codeBase "file:${basedir}/../engine/target/hibernate-validator-${project.version}.jar" { permission java.lang.reflect.ReflectPermission "suppressAccessChecks"; permission java.lang.RuntimePermission "accessDeclaredMembers"; + permission java.lang.RuntimePermission "setContextClassLoader"; // JAXB permission java.util.PropertyPermission "mapAnyUriToUri", "read"; From 162a9faf85970c0ef04a6c394e06e36321b6be81 Mon Sep 17 00:00:00 2001 From: Jenkins Date: Wed, 15 Mar 2017 13:13:42 +0000 Subject: [PATCH 103/124] [Jenkins release job] README.md updated by release build 5.3.5.Final --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5008c2f0e1..becbcf2dad 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Hibernate Validator -*Version: 5.3.4.Final - 08-12-2016* +*Version: 5.3.5.Final - 15-03-2017* ## What is it? @@ -35,7 +35,7 @@ Logging will delegate any log requests to that provider. org.hibernate hibernate-validator - 5.3.4.Final + 5.3.5.Final You also need an API and implementation of the Unified Expression Language. These dependencies must be explicitly added in an SE environment. @@ -59,7 +59,7 @@ extension by adding the following dependency: org.hibernate hibernate-validator-cdi - 5.3.4.Final + 5.3.5.Final * _hibernate-validator-annotation-processor-<version>.jar_ is an optional jar which can be integrated with your build From 66a6e9a66b9bd555a2201b273cb92c13039b295b Mon Sep 17 00:00:00 2001 From: Jenkins Date: Wed, 15 Mar 2017 13:13:43 +0000 Subject: [PATCH 104/124] [Jenkins release job] changelog.txt updated by release build 5.3.5.Final --- changelog.txt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/changelog.txt b/changelog.txt index 12661ef8b6..b0f5dba317 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,6 +1,23 @@ Hibernate Validator Changelog ============================= +5.3.5.Final (15-03-2017) +------------------------- + +** Bug + * HV-1284 - build - Reenable testing under the security manager + * HV-1220 - engine - Programmatically defined cross parameter method constraints don't work on method returning void + +** Improvement + * HV-1187 - build, engine - Support JDK9 ea+148 + +** New Feature + * HV-1280 - - Class loading conflict when custom Xerces is part of a deployment + +** Task + * HV-1266 - build - Update build instructions as per latest Java 9 releases + * HV-1210 - build - Upgrade to Groovy 2.4.8 + 5.3.4.Final (08-12-2016) ------------------------- From 080d475cd02a045e07538a64675b2baa26e79cac Mon Sep 17 00:00:00 2001 From: Jenkins Date: Wed, 15 Mar 2017 13:14:04 +0000 Subject: [PATCH 105/124] [Jenkins release job] Preparing release 5.3.5.Final --- annotation-processor/pom.xml | 2 +- build-config/pom.xml | 2 +- cdi/pom.xml | 2 +- distribution/pom.xml | 2 +- documentation/pom.xml | 2 +- engine-jdk8-tests/pom.xml | 2 +- engine/pom.xml | 2 +- integration/pom.xml | 2 +- osgi/integrationtest/pom.xml | 2 +- osgi/karaf-features/pom.xml | 2 +- osgi/pom.xml | 2 +- performance/pom.xml | 2 +- pom.xml | 2 +- tck-runner/pom.xml | 2 +- test-utils/pom.xml | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/annotation-processor/pom.xml b/annotation-processor/pom.xml index d773cf4813..aa1e17afd7 100644 --- a/annotation-processor/pom.xml +++ b/annotation-processor/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.5-SNAPSHOT + 5.3.5.Final ../pom.xml diff --git a/build-config/pom.xml b/build-config/pom.xml index 9414f4af4b..dc4093c0d7 100644 --- a/build-config/pom.xml +++ b/build-config/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.5-SNAPSHOT + 5.3.5.Final ../pom.xml diff --git a/cdi/pom.xml b/cdi/pom.xml index 9786a80f4b..13ec93e522 100644 --- a/cdi/pom.xml +++ b/cdi/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.5-SNAPSHOT + 5.3.5.Final ../pom.xml diff --git a/distribution/pom.xml b/distribution/pom.xml index 825d6dd5df..3cb135d988 100644 --- a/distribution/pom.xml +++ b/distribution/pom.xml @@ -10,7 +10,7 @@ hibernate-validator-parent org.hibernate - 5.3.5-SNAPSHOT + 5.3.5.Final ../pom.xml diff --git a/documentation/pom.xml b/documentation/pom.xml index e9b7660f5f..6a73b4acbf 100644 --- a/documentation/pom.xml +++ b/documentation/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.5-SNAPSHOT + 5.3.5.Final ../pom.xml diff --git a/engine-jdk8-tests/pom.xml b/engine-jdk8-tests/pom.xml index f899d69a3f..d1d8ada032 100644 --- a/engine-jdk8-tests/pom.xml +++ b/engine-jdk8-tests/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.5-SNAPSHOT + 5.3.5.Final hibernate-validator-engine-jdk8-tests diff --git a/engine/pom.xml b/engine/pom.xml index 2b553bcd44..3e6b4a2eae 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.5-SNAPSHOT + 5.3.5.Final ../pom.xml diff --git a/integration/pom.xml b/integration/pom.xml index 3f2b782d0a..af5f453e8e 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.5-SNAPSHOT + 5.3.5.Final ../pom.xml diff --git a/osgi/integrationtest/pom.xml b/osgi/integrationtest/pom.xml index ad1577a393..607f85e76f 100644 --- a/osgi/integrationtest/pom.xml +++ b/osgi/integrationtest/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-osgi org.hibernate - 5.3.5-SNAPSHOT + 5.3.5.Final ../pom.xml diff --git a/osgi/karaf-features/pom.xml b/osgi/karaf-features/pom.xml index ab4cbc505a..6a5e677972 100644 --- a/osgi/karaf-features/pom.xml +++ b/osgi/karaf-features/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-osgi org.hibernate - 5.3.5-SNAPSHOT + 5.3.5.Final ../pom.xml diff --git a/osgi/pom.xml b/osgi/pom.xml index 0d7e156709..73943cb2bd 100644 --- a/osgi/pom.xml +++ b/osgi/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.5-SNAPSHOT + 5.3.5.Final ../pom.xml diff --git a/performance/pom.xml b/performance/pom.xml index 2812b798bf..7d62e74f1b 100644 --- a/performance/pom.xml +++ b/performance/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.5-SNAPSHOT + 5.3.5.Final ../pom.xml diff --git a/pom.xml b/pom.xml index 85fe3cf066..593900aa36 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.5-SNAPSHOT + 5.3.5.Final pom Hibernate Validator Aggregator diff --git a/tck-runner/pom.xml b/tck-runner/pom.xml index 92ba7310f9..44c3febe85 100644 --- a/tck-runner/pom.xml +++ b/tck-runner/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.5-SNAPSHOT + 5.3.5.Final ../pom.xml diff --git a/test-utils/pom.xml b/test-utils/pom.xml index 31bd9cb94f..e5bcba0d37 100644 --- a/test-utils/pom.xml +++ b/test-utils/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.5-SNAPSHOT + 5.3.5.Final hibernate-validator-test-utils From 932875b8869d9e130e362f36a72117d0ec7fb778 Mon Sep 17 00:00:00 2001 From: Jenkins Date: Wed, 15 Mar 2017 13:19:20 +0000 Subject: [PATCH 106/124] [Jenkins release job] Preparing next development iteration --- annotation-processor/pom.xml | 2 +- build-config/pom.xml | 2 +- cdi/pom.xml | 2 +- distribution/pom.xml | 2 +- documentation/pom.xml | 2 +- engine-jdk8-tests/pom.xml | 2 +- engine/pom.xml | 2 +- integration/pom.xml | 2 +- osgi/integrationtest/pom.xml | 2 +- osgi/karaf-features/pom.xml | 2 +- osgi/pom.xml | 2 +- performance/pom.xml | 2 +- pom.xml | 2 +- tck-runner/pom.xml | 2 +- test-utils/pom.xml | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/annotation-processor/pom.xml b/annotation-processor/pom.xml index aa1e17afd7..332d3c6039 100644 --- a/annotation-processor/pom.xml +++ b/annotation-processor/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.5.Final + 5.3.6-SNAPSHOT ../pom.xml diff --git a/build-config/pom.xml b/build-config/pom.xml index dc4093c0d7..ac303cfc91 100644 --- a/build-config/pom.xml +++ b/build-config/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.5.Final + 5.3.6-SNAPSHOT ../pom.xml diff --git a/cdi/pom.xml b/cdi/pom.xml index 13ec93e522..b7d8c62cf9 100644 --- a/cdi/pom.xml +++ b/cdi/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.5.Final + 5.3.6-SNAPSHOT ../pom.xml diff --git a/distribution/pom.xml b/distribution/pom.xml index 3cb135d988..4b7c6b82fc 100644 --- a/distribution/pom.xml +++ b/distribution/pom.xml @@ -10,7 +10,7 @@ hibernate-validator-parent org.hibernate - 5.3.5.Final + 5.3.6-SNAPSHOT ../pom.xml diff --git a/documentation/pom.xml b/documentation/pom.xml index 6a73b4acbf..856495e40d 100644 --- a/documentation/pom.xml +++ b/documentation/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.5.Final + 5.3.6-SNAPSHOT ../pom.xml diff --git a/engine-jdk8-tests/pom.xml b/engine-jdk8-tests/pom.xml index d1d8ada032..e1ac3d5d5d 100644 --- a/engine-jdk8-tests/pom.xml +++ b/engine-jdk8-tests/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.5.Final + 5.3.6-SNAPSHOT hibernate-validator-engine-jdk8-tests diff --git a/engine/pom.xml b/engine/pom.xml index 3e6b4a2eae..4bc9e59e2f 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.5.Final + 5.3.6-SNAPSHOT ../pom.xml diff --git a/integration/pom.xml b/integration/pom.xml index af5f453e8e..8230dbb3d7 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.5.Final + 5.3.6-SNAPSHOT ../pom.xml diff --git a/osgi/integrationtest/pom.xml b/osgi/integrationtest/pom.xml index 607f85e76f..194e13cda9 100644 --- a/osgi/integrationtest/pom.xml +++ b/osgi/integrationtest/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-osgi org.hibernate - 5.3.5.Final + 5.3.6-SNAPSHOT ../pom.xml diff --git a/osgi/karaf-features/pom.xml b/osgi/karaf-features/pom.xml index 6a5e677972..f1a218b944 100644 --- a/osgi/karaf-features/pom.xml +++ b/osgi/karaf-features/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-osgi org.hibernate - 5.3.5.Final + 5.3.6-SNAPSHOT ../pom.xml diff --git a/osgi/pom.xml b/osgi/pom.xml index 73943cb2bd..aa384d7a58 100644 --- a/osgi/pom.xml +++ b/osgi/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.5.Final + 5.3.6-SNAPSHOT ../pom.xml diff --git a/performance/pom.xml b/performance/pom.xml index 7d62e74f1b..52d0bf16d1 100644 --- a/performance/pom.xml +++ b/performance/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.5.Final + 5.3.6-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index 593900aa36..4a53c93f22 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.5.Final + 5.3.6-SNAPSHOT pom Hibernate Validator Aggregator diff --git a/tck-runner/pom.xml b/tck-runner/pom.xml index 44c3febe85..dbca8ff988 100644 --- a/tck-runner/pom.xml +++ b/tck-runner/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.5.Final + 5.3.6-SNAPSHOT ../pom.xml diff --git a/test-utils/pom.xml b/test-utils/pom.xml index e5bcba0d37..bbf0d2a6c9 100644 --- a/test-utils/pom.xml +++ b/test-utils/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.5.Final + 5.3.6-SNAPSHOT hibernate-validator-test-utils From c15772e8412fd38a0087f473385ea71925ee7120 Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Wed, 26 Jul 2017 15:21:21 +0200 Subject: [PATCH 107/124] Giving license name in pom.xml in spdx format --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4a53c93f22..3e31e75ae8 100644 --- a/pom.xml +++ b/pom.xml @@ -834,7 +834,7 @@ - Apache License, Version 2.0 + Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0.txt From 2b895289915d6646cad1ade1d594d576f2ef0593 Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Wed, 18 Oct 2017 14:28:06 +0200 Subject: [PATCH 108/124] HV-1494 Adding SupportedValidationTarget to HV composite constraints --- .../validator/constraints/NotEmpty.java | 3 + .../validator/constraints/Range.java | 3 + .../constraints/br/TituloEleitoral.java | 3 + ...CompositeConstraintsOnReturnValueTest.java | 149 ++++++++++++++++++ 4 files changed, 158 insertions(+) create mode 100644 engine/src/test/java/org/hibernate/validator/test/internal/engine/methodvalidation/PureCompositeConstraintsOnReturnValueTest.java diff --git a/engine/src/main/java/org/hibernate/validator/constraints/NotEmpty.java b/engine/src/main/java/org/hibernate/validator/constraints/NotEmpty.java index a4112b38d6..7115622572 100644 --- a/engine/src/main/java/org/hibernate/validator/constraints/NotEmpty.java +++ b/engine/src/main/java/org/hibernate/validator/constraints/NotEmpty.java @@ -14,6 +14,8 @@ import javax.validation.ReportAsSingleViolation; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; +import javax.validation.constraintvalidation.SupportedValidationTarget; +import javax.validation.constraintvalidation.ValidationTarget; import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.ElementType.CONSTRUCTOR; @@ -30,6 +32,7 @@ */ @Documented @Constraint(validatedBy = { }) +@SupportedValidationTarget(ValidationTarget.ANNOTATED_ELEMENT) @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER }) @Retention(RUNTIME) @ReportAsSingleViolation diff --git a/engine/src/main/java/org/hibernate/validator/constraints/Range.java b/engine/src/main/java/org/hibernate/validator/constraints/Range.java index 1ec6abab73..676c03fb0c 100644 --- a/engine/src/main/java/org/hibernate/validator/constraints/Range.java +++ b/engine/src/main/java/org/hibernate/validator/constraints/Range.java @@ -15,6 +15,8 @@ import javax.validation.ReportAsSingleViolation; import javax.validation.constraints.Max; import javax.validation.constraints.Min; +import javax.validation.constraintvalidation.SupportedValidationTarget; +import javax.validation.constraintvalidation.ValidationTarget; import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.ElementType.CONSTRUCTOR; @@ -31,6 +33,7 @@ */ @Documented @Constraint(validatedBy = { }) +@SupportedValidationTarget(ValidationTarget.ANNOTATED_ELEMENT) @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER }) @Retention(RUNTIME) @Min(0) diff --git a/engine/src/main/java/org/hibernate/validator/constraints/br/TituloEleitoral.java b/engine/src/main/java/org/hibernate/validator/constraints/br/TituloEleitoral.java index 435ca54372..2c21049af1 100644 --- a/engine/src/main/java/org/hibernate/validator/constraints/br/TituloEleitoral.java +++ b/engine/src/main/java/org/hibernate/validator/constraints/br/TituloEleitoral.java @@ -13,6 +13,8 @@ import javax.validation.Payload; import javax.validation.ReportAsSingleViolation; import javax.validation.constraints.Pattern; +import javax.validation.constraintvalidation.SupportedValidationTarget; +import javax.validation.constraintvalidation.ValidationTarget; import org.hibernate.validator.constraints.Mod11Check; import org.hibernate.validator.constraints.Mod11Check.List; @@ -42,6 +44,7 @@ @ReportAsSingleViolation @Documented @Constraint(validatedBy = { }) +@SupportedValidationTarget(ValidationTarget.ANNOTATED_ELEMENT) @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER }) @Retention(RUNTIME) public @interface TituloEleitoral { diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/engine/methodvalidation/PureCompositeConstraintsOnReturnValueTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/engine/methodvalidation/PureCompositeConstraintsOnReturnValueTest.java new file mode 100644 index 0000000000..935c0735d3 --- /dev/null +++ b/engine/src/test/java/org/hibernate/validator/test/internal/engine/methodvalidation/PureCompositeConstraintsOnReturnValueTest.java @@ -0,0 +1,149 @@ +/* + * Hibernate Validator, declare and validate application constraints + * + * License: Apache License, Version 2.0 + * See the license.txt file in the root directory or . + */ +package org.hibernate.validator.test.internal.engine.methodvalidation; + +import static java.lang.annotation.ElementType.ANNOTATION_TYPE; +import static java.lang.annotation.ElementType.CONSTRUCTOR; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.ElementType.TYPE_USE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertCorrectConstraintTypes; +import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertNumberOfViolations; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import java.util.Set; + +import javax.validation.Constraint; +import javax.validation.ConstraintViolation; +import javax.validation.Payload; +import javax.validation.ReportAsSingleViolation; +import javax.validation.Validator; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; +import javax.validation.constraints.Size; +import javax.validation.constraintvalidation.SupportedValidationTarget; +import javax.validation.constraintvalidation.ValidationTarget; + +import org.hibernate.validator.constraints.NotEmpty; +import org.hibernate.validator.testutil.TestForIssue; +import org.hibernate.validator.testutils.ValidatorUtil; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +/** + * @author Marko Bekhta + */ +public class PureCompositeConstraintsOnReturnValueTest { + private Validator validator; + private Foo foo; + + @BeforeMethod + public void setUp() throws Exception { + validator = ValidatorUtil.getValidator(); + foo = new Foo( "" ); + } + + @Test + @TestForIssue( jiraKey = "HV-1494") + public void testHVSpecificNotEmpty() throws Exception { + Set> violations = validator.forExecutables() + .validateReturnValue( + foo, + Foo.class.getDeclaredMethod( "createBarString", String.class ), + "" + ); + assertCorrectConstraintTypes( violations, NotEmpty.class ); + + violations = validator.forExecutables() + .validateReturnValue( + foo, + Foo.class.getDeclaredMethod( "createBarString", String.class ), + " " + ); + assertNumberOfViolations( violations, 0 ); + } + + @Test + @TestForIssue( jiraKey = "HV-1494") + public void testCustomComposingConstraintOnReturnValue() throws Exception { + Set> violations = validator.forExecutables() + .validateReturnValue( + foo, + Foo.class.getDeclaredMethod( "createCustomBarString", String.class ), + "a" + ); + assertCorrectConstraintTypes( violations, CustomCompositeConstraint.class ); + + violations = validator.forExecutables() + .validateReturnValue( + foo, + Foo.class.getDeclaredMethod( "createCustomBarString", String.class ), + "1" + ); + assertNumberOfViolations( violations, 0 ); + } + + @Test + @TestForIssue( jiraKey = "HV-1494") + public void testCustomComposingConstraintOnParameters() throws Exception { + Set> violations = validator.forExecutables() + .validateParameters( + foo, + Foo.class.getDeclaredMethod( "createCustomBarString", String.class ), + new String[] { "abc" } + ); + assertCorrectConstraintTypes( violations, CustomCompositeConstraint.class ); + + violations = validator.forExecutables() + .validateParameters( + foo, + Foo.class.getDeclaredMethod( "createCustomBarString", String.class ), + new String[] { "1" } + ); + assertNumberOfViolations( violations, 0 ); + } + + private static class Foo { + + private String bar; + + public Foo(String bar) { + this.bar = bar; + } + + @NotEmpty + public String createBarString(String a) { + return bar; + } + + @CustomCompositeConstraint + public String createCustomBarString(@CustomCompositeConstraint String a) { + return bar; + } + } + + @Documented + @Constraint(validatedBy = { }) + @SupportedValidationTarget(ValidationTarget.ANNOTATED_ELEMENT) + @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE }) + @Retention(RUNTIME) + @ReportAsSingleViolation + @NotNull + @Size(min = 1) + @Pattern(regexp = "\\d*") + public @interface CustomCompositeConstraint { + String message() default "no message"; + + Class[] groups() default { }; + + Class[] payload() default { }; + } +} From 0886e89900d343ea20fde5137c9a3086e6da9ac9 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Thu, 19 Oct 2017 15:38:27 +0200 Subject: [PATCH 109/124] HV-1498 Fix privilege escalation when running under the security manager --- documentation/src/main/asciidoc/ch01.asciidoc | 2 ++ .../HibernateValidatorPermission.java | 29 +++++++++++++++++++ .../internal/engine/ValidatorImpl.java | 6 ++++ .../metadata/aggregated/PropertyMetaData.java | 6 ++++ .../privilegedactions/GetDeclaredField.java | 1 - tck-runner/src/test/resources/test.policy | 5 ++++ 6 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 engine/src/main/java/org/hibernate/validator/HibernateValidatorPermission.java diff --git a/documentation/src/main/asciidoc/ch01.asciidoc b/documentation/src/main/asciidoc/ch01.asciidoc index 6d90241344..ce9a244061 100644 --- a/documentation/src/main/asciidoc/ch01.asciidoc +++ b/documentation/src/main/asciidoc/ch01.asciidoc @@ -106,6 +106,8 @@ grant codeBase "file:path/to/hibernate-validator-{hvVersion}.jar" { permission java.lang.RuntimePermission "accessDeclaredMembers"; permission java.lang.RuntimePermission "setContextClassLoader"; + permission org.hibernate.validator.HibernateValidatorPermission "accessPrivateMembers"; + // Only needed when working with XML descriptors (validation.xml or XML constraint mappings) permission java.util.PropertyPermission "mapAnyUriToUri", "read"; }; diff --git a/engine/src/main/java/org/hibernate/validator/HibernateValidatorPermission.java b/engine/src/main/java/org/hibernate/validator/HibernateValidatorPermission.java new file mode 100644 index 0000000000..71b33b75fb --- /dev/null +++ b/engine/src/main/java/org/hibernate/validator/HibernateValidatorPermission.java @@ -0,0 +1,29 @@ +/* + * Hibernate Validator, declare and validate application constraints + * + * License: Apache License, Version 2.0 + * See the license.txt file in the root directory or . + */ +package org.hibernate.validator; + +import java.security.BasicPermission; + +/** + * Our specific implementation of {@link BasicPermission} as we cannot define additional {@link RuntimePermission}. + *

+ * {@code HibernateValidatorPermission} is thread-safe and immutable. + * + * @author Guillaume Smet + */ +public class HibernateValidatorPermission extends BasicPermission { + + public static final HibernateValidatorPermission ACCESS_PRIVATE_MEMBERS = new HibernateValidatorPermission( "accessPrivateMembers" ); + + public HibernateValidatorPermission(String name) { + super( name ); + } + + public HibernateValidatorPermission(String name, String actions) { + super( name, actions ); + } +} diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java index 8b67f64beb..9ac7a1f8f0 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java @@ -40,6 +40,7 @@ import javax.validation.groups.Default; import javax.validation.metadata.BeanDescriptor; +import org.hibernate.validator.HibernateValidatorPermission; import org.hibernate.validator.internal.engine.ValidationContext.ValidationContextBuilder; import org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManager; import org.hibernate.validator.internal.engine.groups.Group; @@ -1771,6 +1772,11 @@ private Member getAccessible(Member original) { return member; } + SecurityManager sm = System.getSecurityManager(); + if ( sm != null ) { + sm.checkPermission( HibernateValidatorPermission.ACCESS_PRIVATE_MEMBERS ); + } + Class clazz = original.getDeclaringClass(); if ( original instanceof Field ) { diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java index 911eb3f323..95ea78779e 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/aggregated/PropertyMetaData.java @@ -25,6 +25,7 @@ import javax.validation.ElementKind; import javax.validation.metadata.GroupConversionDescriptor; +import org.hibernate.validator.HibernateValidatorPermission; import org.hibernate.validator.internal.engine.valuehandling.UnwrapMode; import org.hibernate.validator.internal.metadata.core.ConstraintHelper; import org.hibernate.validator.internal.metadata.core.MetaConstraint; @@ -119,6 +120,11 @@ private static Member getAccessible(Member original) { return original; } + SecurityManager sm = System.getSecurityManager(); + if ( sm != null ) { + sm.checkPermission( HibernateValidatorPermission.ACCESS_PRIVATE_MEMBERS ); + } + Class clazz = original.getDeclaringClass(); Member member; diff --git a/engine/src/main/java/org/hibernate/validator/internal/util/privilegedactions/GetDeclaredField.java b/engine/src/main/java/org/hibernate/validator/internal/util/privilegedactions/GetDeclaredField.java index e996f7fd8c..2a4392e368 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/util/privilegedactions/GetDeclaredField.java +++ b/engine/src/main/java/org/hibernate/validator/internal/util/privilegedactions/GetDeclaredField.java @@ -31,7 +31,6 @@ private GetDeclaredField(Class clazz, String fieldName) { public Field run() { try { final Field field = clazz.getDeclaredField( fieldName ); - field.setAccessible( true ); return field; } catch (NoSuchFieldException e) { diff --git a/tck-runner/src/test/resources/test.policy b/tck-runner/src/test/resources/test.policy index b2a4fbd1c6..fedfaede4e 100644 --- a/tck-runner/src/test/resources/test.policy +++ b/tck-runner/src/test/resources/test.policy @@ -28,6 +28,8 @@ grant codeBase "file:${localRepository}/org/hibernate/hibernate-validator/${proj permission java.lang.RuntimePermission "accessDeclaredMembers"; permission java.lang.RuntimePermission "setContextClassLoader"; + permission org.hibernate.validator.HibernateValidatorPermission "accessPrivateMembers"; + // JAXB permission java.util.PropertyPermission "mapAnyUriToUri", "read"; }; @@ -39,6 +41,8 @@ grant codeBase "file:${basedir}/../engine/target/hibernate-validator-${project.v permission java.lang.RuntimePermission "accessDeclaredMembers"; permission java.lang.RuntimePermission "setContextClassLoader"; + permission org.hibernate.validator.HibernateValidatorPermission "accessPrivateMembers"; + // JAXB permission java.util.PropertyPermission "mapAnyUriToUri", "read"; }; @@ -81,6 +85,7 @@ grant codeBase "file:${project.build.directory}/classes" { permission java.util.PropertyPermission "validation.provider", "read"; permission java.io.FilePermission "${localRepository}/org/hibernate/beanvalidation/tck/beanvalidation-tck-tests/${tck.version}/beanvalidation-tck-tests-${tck.version}.jar", "read"; permission java.util.PropertyPermission "user.language", "write"; + permission org.hibernate.validator.HibernateValidatorPermission "accessPrivateMembers"; }; grant codeBase "file:${project.build.directory}/test-classes" { From 02098c1d0db3669ba863b24216dc1f9c39a0e3e2 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Mon, 31 Jul 2017 20:18:21 +0200 Subject: [PATCH 110/124] HV-1454 Support JDK 9 build 180 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 3e31e75ae8..150b11388e 100644 --- a/pom.xml +++ b/pom.xml @@ -344,7 +344,7 @@ maven-enforcer-plugin - 1.4.1 + 3.0.0-M1 enforce-java @@ -635,7 +635,7 @@ maven-javadoc-plugin - 2.10.4 + 3.0.0-M1 true ${project.basedir}/../src/main/javadoc From 60ca6c55c457b0a6b142e4b6e870033800334ba8 Mon Sep 17 00:00:00 2001 From: Jenkins Date: Thu, 19 Oct 2017 15:58:09 +0000 Subject: [PATCH 111/124] [Jenkins release job] README.md updated by release build 5.3.6.Final --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index becbcf2dad..83fbc1145f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Hibernate Validator -*Version: 5.3.5.Final - 15-03-2017* +*Version: 5.3.6.Final - 19-10-2017* ## What is it? @@ -35,7 +35,7 @@ Logging will delegate any log requests to that provider. org.hibernate hibernate-validator - 5.3.5.Final + 5.3.6.Final You also need an API and implementation of the Unified Expression Language. These dependencies must be explicitly added in an SE environment. @@ -59,7 +59,7 @@ extension by adding the following dependency: org.hibernate hibernate-validator-cdi - 5.3.5.Final + 5.3.6.Final * _hibernate-validator-annotation-processor-<version>.jar_ is an optional jar which can be integrated with your build From faf949376d8dd1325abc06cabf1cc606351d965c Mon Sep 17 00:00:00 2001 From: Jenkins Date: Thu, 19 Oct 2017 15:58:09 +0000 Subject: [PATCH 112/124] [Jenkins release job] changelog.txt updated by release build 5.3.6.Final --- changelog.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/changelog.txt b/changelog.txt index b0f5dba317..957c43b00e 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,6 +1,16 @@ Hibernate Validator Changelog ============================= +5.3.6.Final (19-10-2017) +------------------------- + +** Bug + * HV-1498 - engine - Privilege escalation when running under the security manager + * HV-1494 - validators - Hibernate Validator specific @NotEmpty used on return type throws an exception + +** Improvement + * HV-1454 - build - Support JDK 9 build 180 + 5.3.5.Final (15-03-2017) ------------------------- From be5f102e7c9eba64e58b93763befde4284ce9e67 Mon Sep 17 00:00:00 2001 From: Jenkins Date: Thu, 19 Oct 2017 15:58:18 +0000 Subject: [PATCH 113/124] [Jenkins release job] Preparing release 5.3.6.Final --- annotation-processor/pom.xml | 2 +- build-config/pom.xml | 2 +- cdi/pom.xml | 2 +- distribution/pom.xml | 2 +- documentation/pom.xml | 2 +- engine-jdk8-tests/pom.xml | 2 +- engine/pom.xml | 2 +- integration/pom.xml | 2 +- osgi/integrationtest/pom.xml | 2 +- osgi/karaf-features/pom.xml | 2 +- osgi/pom.xml | 2 +- performance/pom.xml | 2 +- pom.xml | 2 +- tck-runner/pom.xml | 2 +- test-utils/pom.xml | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/annotation-processor/pom.xml b/annotation-processor/pom.xml index 332d3c6039..d4f48c4499 100644 --- a/annotation-processor/pom.xml +++ b/annotation-processor/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6-SNAPSHOT + 5.3.6.Final ../pom.xml diff --git a/build-config/pom.xml b/build-config/pom.xml index ac303cfc91..7a2fbb0e16 100644 --- a/build-config/pom.xml +++ b/build-config/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6-SNAPSHOT + 5.3.6.Final ../pom.xml diff --git a/cdi/pom.xml b/cdi/pom.xml index b7d8c62cf9..36ec025f93 100644 --- a/cdi/pom.xml +++ b/cdi/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6-SNAPSHOT + 5.3.6.Final ../pom.xml diff --git a/distribution/pom.xml b/distribution/pom.xml index 4b7c6b82fc..ff8b26b8f8 100644 --- a/distribution/pom.xml +++ b/distribution/pom.xml @@ -10,7 +10,7 @@ hibernate-validator-parent org.hibernate - 5.3.6-SNAPSHOT + 5.3.6.Final ../pom.xml diff --git a/documentation/pom.xml b/documentation/pom.xml index 856495e40d..2d63c9260c 100644 --- a/documentation/pom.xml +++ b/documentation/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6-SNAPSHOT + 5.3.6.Final ../pom.xml diff --git a/engine-jdk8-tests/pom.xml b/engine-jdk8-tests/pom.xml index e1ac3d5d5d..0b1d172090 100644 --- a/engine-jdk8-tests/pom.xml +++ b/engine-jdk8-tests/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.6-SNAPSHOT + 5.3.6.Final hibernate-validator-engine-jdk8-tests diff --git a/engine/pom.xml b/engine/pom.xml index 4bc9e59e2f..621154282e 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6-SNAPSHOT + 5.3.6.Final ../pom.xml diff --git a/integration/pom.xml b/integration/pom.xml index 8230dbb3d7..7492b5d10c 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6-SNAPSHOT + 5.3.6.Final ../pom.xml diff --git a/osgi/integrationtest/pom.xml b/osgi/integrationtest/pom.xml index 194e13cda9..a52a4ae6e1 100644 --- a/osgi/integrationtest/pom.xml +++ b/osgi/integrationtest/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-osgi org.hibernate - 5.3.6-SNAPSHOT + 5.3.6.Final ../pom.xml diff --git a/osgi/karaf-features/pom.xml b/osgi/karaf-features/pom.xml index f1a218b944..e827d31a8b 100644 --- a/osgi/karaf-features/pom.xml +++ b/osgi/karaf-features/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-osgi org.hibernate - 5.3.6-SNAPSHOT + 5.3.6.Final ../pom.xml diff --git a/osgi/pom.xml b/osgi/pom.xml index aa384d7a58..ae5aa4a56d 100644 --- a/osgi/pom.xml +++ b/osgi/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6-SNAPSHOT + 5.3.6.Final ../pom.xml diff --git a/performance/pom.xml b/performance/pom.xml index 52d0bf16d1..080c31e52e 100644 --- a/performance/pom.xml +++ b/performance/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6-SNAPSHOT + 5.3.6.Final ../pom.xml diff --git a/pom.xml b/pom.xml index 150b11388e..59d2243b0f 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.6-SNAPSHOT + 5.3.6.Final pom Hibernate Validator Aggregator diff --git a/tck-runner/pom.xml b/tck-runner/pom.xml index dbca8ff988..4d5c0ba7da 100644 --- a/tck-runner/pom.xml +++ b/tck-runner/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6-SNAPSHOT + 5.3.6.Final ../pom.xml diff --git a/test-utils/pom.xml b/test-utils/pom.xml index bbf0d2a6c9..f99775646e 100644 --- a/test-utils/pom.xml +++ b/test-utils/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.6-SNAPSHOT + 5.3.6.Final hibernate-validator-test-utils From b812eb99a8f0fa225207c0836eaedbb794b98cd5 Mon Sep 17 00:00:00 2001 From: Jenkins Date: Thu, 19 Oct 2017 16:02:31 +0000 Subject: [PATCH 114/124] [Jenkins release job] Preparing next development iteration --- annotation-processor/pom.xml | 2 +- build-config/pom.xml | 2 +- cdi/pom.xml | 2 +- distribution/pom.xml | 2 +- documentation/pom.xml | 2 +- engine-jdk8-tests/pom.xml | 2 +- engine/pom.xml | 2 +- integration/pom.xml | 2 +- osgi/integrationtest/pom.xml | 2 +- osgi/karaf-features/pom.xml | 2 +- osgi/pom.xml | 2 +- performance/pom.xml | 2 +- pom.xml | 2 +- tck-runner/pom.xml | 2 +- test-utils/pom.xml | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/annotation-processor/pom.xml b/annotation-processor/pom.xml index d4f48c4499..791cd5ac46 100644 --- a/annotation-processor/pom.xml +++ b/annotation-processor/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6.Final + 5.3.7-SNAPSHOT ../pom.xml diff --git a/build-config/pom.xml b/build-config/pom.xml index 7a2fbb0e16..6f11f32cc1 100644 --- a/build-config/pom.xml +++ b/build-config/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6.Final + 5.3.7-SNAPSHOT ../pom.xml diff --git a/cdi/pom.xml b/cdi/pom.xml index 36ec025f93..0cd4e788b2 100644 --- a/cdi/pom.xml +++ b/cdi/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6.Final + 5.3.7-SNAPSHOT ../pom.xml diff --git a/distribution/pom.xml b/distribution/pom.xml index ff8b26b8f8..4a104019ef 100644 --- a/distribution/pom.xml +++ b/distribution/pom.xml @@ -10,7 +10,7 @@ hibernate-validator-parent org.hibernate - 5.3.6.Final + 5.3.7-SNAPSHOT ../pom.xml diff --git a/documentation/pom.xml b/documentation/pom.xml index 2d63c9260c..cb6127e744 100644 --- a/documentation/pom.xml +++ b/documentation/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6.Final + 5.3.7-SNAPSHOT ../pom.xml diff --git a/engine-jdk8-tests/pom.xml b/engine-jdk8-tests/pom.xml index 0b1d172090..23abffb0dd 100644 --- a/engine-jdk8-tests/pom.xml +++ b/engine-jdk8-tests/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.6.Final + 5.3.7-SNAPSHOT hibernate-validator-engine-jdk8-tests diff --git a/engine/pom.xml b/engine/pom.xml index 621154282e..4de45a5dd6 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6.Final + 5.3.7-SNAPSHOT ../pom.xml diff --git a/integration/pom.xml b/integration/pom.xml index 7492b5d10c..d9cdbef729 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6.Final + 5.3.7-SNAPSHOT ../pom.xml diff --git a/osgi/integrationtest/pom.xml b/osgi/integrationtest/pom.xml index a52a4ae6e1..2570f60d0e 100644 --- a/osgi/integrationtest/pom.xml +++ b/osgi/integrationtest/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-osgi org.hibernate - 5.3.6.Final + 5.3.7-SNAPSHOT ../pom.xml diff --git a/osgi/karaf-features/pom.xml b/osgi/karaf-features/pom.xml index e827d31a8b..5040d1bdf4 100644 --- a/osgi/karaf-features/pom.xml +++ b/osgi/karaf-features/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-osgi org.hibernate - 5.3.6.Final + 5.3.7-SNAPSHOT ../pom.xml diff --git a/osgi/pom.xml b/osgi/pom.xml index ae5aa4a56d..b591ac397b 100644 --- a/osgi/pom.xml +++ b/osgi/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6.Final + 5.3.7-SNAPSHOT ../pom.xml diff --git a/performance/pom.xml b/performance/pom.xml index 080c31e52e..30de798913 100644 --- a/performance/pom.xml +++ b/performance/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6.Final + 5.3.7-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index 59d2243b0f..d57c368017 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.6.Final + 5.3.7-SNAPSHOT pom Hibernate Validator Aggregator diff --git a/tck-runner/pom.xml b/tck-runner/pom.xml index 4d5c0ba7da..ce4cffbded 100644 --- a/tck-runner/pom.xml +++ b/tck-runner/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6.Final + 5.3.7-SNAPSHOT ../pom.xml diff --git a/test-utils/pom.xml b/test-utils/pom.xml index f99775646e..4568fc87d8 100644 --- a/test-utils/pom.xml +++ b/test-utils/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.6.Final + 5.3.7-SNAPSHOT hibernate-validator-test-utils From d8d60ff4ff1e4e20ba4b68e075f4fd90200db679 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Wed, 7 Mar 2018 15:44:06 +0100 Subject: [PATCH 115/124] Add the Maven wrapper files to .gitignore --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index af68ba4e0b..3ae74e4d13 100644 --- a/.gitignore +++ b/.gitignore @@ -47,3 +47,7 @@ maven-eclipse.xml *.log .clover .DS_Store + +# Maven wrapper files +.mvn +mvnw* From dfc6d7f3bb56cdd575981521f565b3c1a5132d11 Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Thu, 12 Jun 2025 17:46:55 +0200 Subject: [PATCH 116/124] [Jenkins release job] Preparing next development iteration --- annotation-processor/pom.xml | 2 +- build-config/pom.xml | 2 +- cdi/pom.xml | 2 +- distribution/pom.xml | 2 +- documentation/pom.xml | 2 +- engine-jdk8-tests/pom.xml | 2 +- engine/pom.xml | 2 +- integration/pom.xml | 2 +- osgi/integrationtest/pom.xml | 2 +- osgi/karaf-features/pom.xml | 2 +- osgi/pom.xml | 2 +- performance/pom.xml | 2 +- pom.xml | 2 +- tck-runner/pom.xml | 2 +- test-utils/pom.xml | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/annotation-processor/pom.xml b/annotation-processor/pom.xml index 791cd5ac46..4acc0cffbd 100644 --- a/annotation-processor/pom.xml +++ b/annotation-processor/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.7-SNAPSHOT + 5.3.6.SP1-SNAPSHOT ../pom.xml diff --git a/build-config/pom.xml b/build-config/pom.xml index 6f11f32cc1..9218a02442 100644 --- a/build-config/pom.xml +++ b/build-config/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.7-SNAPSHOT + 5.3.6.SP1-SNAPSHOT ../pom.xml diff --git a/cdi/pom.xml b/cdi/pom.xml index 0cd4e788b2..a0ca1770e0 100644 --- a/cdi/pom.xml +++ b/cdi/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.7-SNAPSHOT + 5.3.6.SP1-SNAPSHOT ../pom.xml diff --git a/distribution/pom.xml b/distribution/pom.xml index 4a104019ef..b086b60c99 100644 --- a/distribution/pom.xml +++ b/distribution/pom.xml @@ -10,7 +10,7 @@ hibernate-validator-parent org.hibernate - 5.3.7-SNAPSHOT + 5.3.6.SP1-SNAPSHOT ../pom.xml diff --git a/documentation/pom.xml b/documentation/pom.xml index cb6127e744..ff4d806451 100644 --- a/documentation/pom.xml +++ b/documentation/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.7-SNAPSHOT + 5.3.6.SP1-SNAPSHOT ../pom.xml diff --git a/engine-jdk8-tests/pom.xml b/engine-jdk8-tests/pom.xml index 23abffb0dd..3ed0ba522f 100644 --- a/engine-jdk8-tests/pom.xml +++ b/engine-jdk8-tests/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.7-SNAPSHOT + 5.3.6.SP1-SNAPSHOT hibernate-validator-engine-jdk8-tests diff --git a/engine/pom.xml b/engine/pom.xml index 4de45a5dd6..637d1e248c 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.7-SNAPSHOT + 5.3.6.SP1-SNAPSHOT ../pom.xml diff --git a/integration/pom.xml b/integration/pom.xml index d9cdbef729..11d5e22f8f 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.7-SNAPSHOT + 5.3.6.SP1-SNAPSHOT ../pom.xml diff --git a/osgi/integrationtest/pom.xml b/osgi/integrationtest/pom.xml index 2570f60d0e..07f683410c 100644 --- a/osgi/integrationtest/pom.xml +++ b/osgi/integrationtest/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-osgi org.hibernate - 5.3.7-SNAPSHOT + 5.3.6.SP1-SNAPSHOT ../pom.xml diff --git a/osgi/karaf-features/pom.xml b/osgi/karaf-features/pom.xml index 5040d1bdf4..7c8a8274cf 100644 --- a/osgi/karaf-features/pom.xml +++ b/osgi/karaf-features/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-osgi org.hibernate - 5.3.7-SNAPSHOT + 5.3.6.SP1-SNAPSHOT ../pom.xml diff --git a/osgi/pom.xml b/osgi/pom.xml index b591ac397b..48403b8406 100644 --- a/osgi/pom.xml +++ b/osgi/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.7-SNAPSHOT + 5.3.6.SP1-SNAPSHOT ../pom.xml diff --git a/performance/pom.xml b/performance/pom.xml index 30de798913..43af392d04 100644 --- a/performance/pom.xml +++ b/performance/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.7-SNAPSHOT + 5.3.6.SP1-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index d57c368017..0abf6e258b 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.7-SNAPSHOT + 5.3.6.SP1-SNAPSHOT pom Hibernate Validator Aggregator diff --git a/tck-runner/pom.xml b/tck-runner/pom.xml index ce4cffbded..6e22cc472a 100644 --- a/tck-runner/pom.xml +++ b/tck-runner/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.7-SNAPSHOT + 5.3.6.SP1-SNAPSHOT ../pom.xml diff --git a/test-utils/pom.xml b/test-utils/pom.xml index 4568fc87d8..43d83a1b76 100644 --- a/test-utils/pom.xml +++ b/test-utils/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.7-SNAPSHOT + 5.3.6.SP1-SNAPSHOT hibernate-validator-test-utils From 84193f7c0fb859ea0e77b4063bfcf173f4440495 Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Thu, 12 Jun 2025 18:56:06 +0200 Subject: [PATCH 117/124] Add a Jenkinsfile for the build so that this branch can be tested on a CI --- Jenkinsfile | 639 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 639 insertions(+) create mode 100644 Jenkinsfile diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000000..8b1a32b718 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,639 @@ +/* + * Hibernate Validator, declare and validate application constraints + * + * License: Apache License, Version 2.0 + * See the license.txt file in the root directory or . + */ + +import groovy.transform.Field + +/* + * See https://github.com/hibernate/hibernate-jenkins-pipeline-helpers + */ +@Library('hibernate-jenkins-pipeline-helpers') _ + +import org.hibernate.jenkins.pipeline.helpers.job.JobHelper +import org.hibernate.jenkins.pipeline.helpers.alternative.AlternativeMultiMap + +/* + * WARNING: DO NOT IMPORT LOCAL LIBRARIES HERE. + * + * By local, I mean libraries whose files are in the same Git repository. + * + * The Jenkinsfile is protected and will not be executed if modified in pull requests from external users, + * but other local library files are not protected. + * A user could potentially craft a malicious PR by modifying a local library. + * + * See https://blog.grdryn.me/blog/jenkins-pipeline-trust.html for a full explanation, + * and a potential solution if we really need local libraries. + * Alternatively we might be able to host libraries in a separate GitHub repo and configure + * them in the GUI: see https://ci.hibernate.org/job/hibernate-validator/configure, "Pipeline Libraries". + */ + +/* + * See https://github.com/hibernate/hibernate-jenkins-pipeline-helpers for the documentation + * of the helpers library used in this Jenkinsfile, + * and for help writing Jenkinsfiles. + * + * ### Jenkins configuration + * + * #### Jenkins plugins + * + * This file requires the following plugins in particular: + * + * - everything required by the helpers library (see the org.hibernate.(...) imports for a link to its documentation) + * - https://plugins.jenkins.io/pipeline-github for the trigger on pull request comments + * + * #### Script approval + * + * If not already done, you will need to allow the following calls in /scriptApproval/: + * + * - everything required by the helpers library (see the org.hibernate.(...) imports for a link to its documentation) + * + * ### Integrations + * + * ### Job configuration + * + * This Jenkinsfile gets its configuration from four sources: + * branch name, environment variables, a configuration file, and credentials. + * All configuration is optional for the default build (and it should stay that way), + * but some features require some configuration. + * + * #### Branch name + * + * See the org.hibernate.(...) imports for a link to the helpers library documentation, + * which explains the basics. + * + * #### Environment variables + * + * No particular environment variables is necessary. + * + * #### Job configuration file + * + * See the org.hibernate.(...) imports for a link to the helpers library documentation, + * which explains the basic structure of this file and how to set it up. + * + * Below is the additional structure specific to this Jenkinsfile: + * + */ + +@Field final String DEFAULT_JDK_TOOL = 'OpenJDK 8 Latest' +@Field final String MAVEN_TOOL = 'Apache Maven 3.9' + +// Default node pattern, to be used for resource-intensive stages. +// Should not include the controller node. +@Field final String NODE_PATTERN_BASE = 'Worker&&Containers' +// Quick-use node pattern, to be used for very light, quick, and environment-independent stages, +// such as sending a notification. May include the controller node in particular. +@Field final String QUICK_USE_NODE_PATTERN = 'Controller||Worker' + +@Field AlternativeMultiMap environments +@Field JobHelper helper + +@Field boolean enableDefaultBuild = false +@Field boolean enableDefaultBuildIT = false + +this.helper = new JobHelper(this) + +helper.runWithNotification { + + stage('Configure') { + // We want to make sure that if we are building a PR that the branch name will not require any escaping of symbols in it. + // Otherwise, it may lead to cryptic build errors. + if (helper.scmSource.branch.name && !(helper.scmSource.branch.name ==~ /^[\w\d\/\\_\-\.]+$/)) { + throw new IllegalArgumentException(""" + Branch name ${helper.scmSource.branch.name} contains unexpected symbols. + Only characters, digits and -_.\\/ symbols are allowed in the branch name. + Change the branch name and open a new Pull Request. + """) + } + + requireApprovalForPullRequest 'hibernate' + + this.environments = AlternativeMultiMap.create([ + jdk: [ + new JdkBuildEnvironment(testJavaVersion: '8', testCompilerTool: 'OpenJDK 8 Latest', + condition: TestCondition.BEFORE_MERGE, + isDefault: true), + + // We want to enable preview features when testing newer builds of OpenJDK: + // even if we don't use these features, just enabling them can cause side effects + // and it's useful to test that. + new JdkBuildEnvironment(testJavaVersion: '9', testCompilerTool: 'OpenJDK 9 Latest', + testLauncherArgs: '--enable-preview', + condition: TestCondition.AFTER_MERGE) + ], + wildflyTck: [ + new WildFlyTckBuildEnvironment(testJavaVersion: '8', testCompilerTool: 'OpenJDK 8 Latest', + condition: TestCondition.ON_DEMAND) + ], + sigtest: [ + new SigTestBuildEnvironment(testJavaVersion: '8', jdkTool: 'OpenJDK 8 Latest', + condition: TestCondition.BEFORE_MERGE) + ] + ]) + + helper.configure { + configurationNodePattern QUICK_USE_NODE_PATTERN + file 'job-configuration.yaml' + jdk { + defaultTool DEFAULT_JDK_TOOL + } + maven { + defaultTool MAVEN_TOOL + producedArtifactPattern "org/hibernate/validator/*" + } + } + + properties([ + buildDiscarder( + logRotator(daysToKeepStr: '30', numToKeepStr: '10') + ), + disableConcurrentBuilds(abortPrevious: true), + pipelineTriggers( + // HSEARCH-3417: do not add snapshotDependencies() here, this was known to cause problems. + [ + issueCommentTrigger('.*test this please.*') + ] + + helper.generateUpstreamTriggers() + ), + helper.generateNotificationProperty(), + parameters([ + choice( + name: 'ENVIRONMENT_SET', + choices: """AUTOMATIC +DEFAULT +SUPPORTED +ALL""", + description: """A set of environments that must be checked. +'AUTOMATIC' picks a different set of environments based on the branch name. +'DEFAULT' means a single build with the default environment expected by the Maven configuration, +while other options will trigger multiple Maven executions in different environments.""" + ), + string( + name: 'ENVIRONMENT_FILTER', + defaultValue: '', + trim: true, + description: """A regex filter to apply to the environments that must be checked. +If this parameter is non-empty, ENVIRONMENT_SET will be ignored and environments whose tag matches the given regex will be checked. +Some useful filters: 'default', 'jdk', 'jdk-10', 'eclipse'. +""" + ) + ]) + ]) + + if (params.ENVIRONMENT_FILTER) { + keepOnlyEnvironmentsMatchingFilter(params.ENVIRONMENT_FILTER) + } + else { + keepOnlyEnvironmentsFromSet(params.ENVIRONMENT_SET) + } + + // Determine whether ITs need to be run in the default build + enableDefaultBuildIT = environments.content.any { key, envSet -> + return envSet.enabled.contains(envSet.default) + } + // No need to re-test default environments separately, they will be tested as part of the default build if needed + environments.content.each { key, envSet -> + envSet.enabled.remove(envSet.default) + } + + if ( enableDefaultBuildIT && params.LEGACY_IT ) { + echo "Enabling legacy integration tests in default environment due to explicit request" + enableDefaultBuildLegacyIT = true + } + + enableDefaultBuild = + enableDefaultBuildIT || + environments.content.any { key, envSet -> envSet.enabled.any { buildEnv -> buildEnv.requiresDefaultBuildArtifacts() } } + + echo """Branch: ${helper.scmSource.branch.name} +PR: ${helper.scmSource.pullRequest?.id} +params.ENVIRONMENT_SET: ${params.ENVIRONMENT_SET} +params.ENVIRONMENT_FILTER: ${params.ENVIRONMENT_FILTER} + +Resulting execution plan: + enableDefaultBuild=$enableDefaultBuild + enableDefaultBuildIT=$enableDefaultBuildIT + environments=${environments.enabledAsString} +""" + } + + stage('Default build') { + if (!enableDefaultBuild) { + echo 'Skipping default build and integration tests in the default environment' + helper.markStageSkipped() + return + } + runBuildOnNode { + withMavenWorkspace { + mvn """ \ + clean install \ + --fail-at-end \ + -Pdist \ + -Pcoverage \ + -Pjqassistant -Pci-build \ + ${enableDefaultBuildIT ? '' : '-DskipITs'} \ + ${toTestJdkArg(environments.content.jdk.default)} \ + """ + + dir(helper.configuration.maven.localRepositoryPath) { + stash name:'default-build-result', includes:"org/hibernate/validator/**" + } + stash name:'default-build-jacoco-reports', includes:"**/jacoco.exec" + } + } + } + + stage('Non-default environments') { + Map parameters = [:] + + // Test with multiple JDKs + environments.content.jdk.enabled.each { JdkBuildEnvironment buildEnv -> + parameters.put(buildEnv.tag, { + runBuildOnNode { + withMavenWorkspace { + mavenNonDefaultBuild buildEnv, """ \ + clean install \ + """ + } + } + }) + } + + // Run the TCK with WildFly in multiple environments + environments.content.wildflyTck.enabled.each { WildFlyTckBuildEnvironment buildEnv -> + parameters.put(buildEnv.tag, { + runBuildOnNode { + withMavenWorkspace { + mavenNonDefaultBuild buildEnv, """ \ + clean install \ + -pl tck-runner \ + -Dincontainer -Dincontainer-prepared \ + """ + } + } + }) + } + + // Run the TCK signature test + environments.content.sigtest.enabled.each { SigTestBuildEnvironment buildEnv -> + parameters.put(buildEnv.tag, { + runBuildOnNode { + withMavenWorkspace(jdk: buildEnv.jdkTool) { + mavenNonDefaultBuild buildEnv, """ \ + clean install \ + -pl tck-runner \ + -Psigtest \ + -Denforcer.skip=true \ + -DskipTests=true -Dcheckstyle.skip=true \ + -DdisableDistributionBuild=true -DdisableDocumentationBuild=true \ + -Dscan=false -Dno-build-cache \ + """ + } + } + }) + } + + if (parameters.isEmpty()) { + echo 'Skipping builds in non-default environments' + helper.markStageSkipped() + } + else { + parameters.put('failFast', false) + parallel(parameters) + } + } + + stage('Sonar analysis') { + def sonarCredentialsId = helper.configuration.file?.sonar?.credentials + if (sonarCredentialsId) { + runBuildOnNode { + withMavenWorkspace { + if (enableDefaultBuild && enableDefaultBuildIT) { + unstash name: "default-build-jacoco-reports" + } + environments.content.jdk.enabled.each { JdkBuildEnvironment buildEnv -> + unstash name: "${buildEnv.tag}-build-jacoco-reports" + } + environments.content.wildflyTck.enabled.each { JdkBuildEnvironment buildEnv -> + unstash name: "${buildEnv.tag}-build-jacoco-reports" + } + + // we don't clean to keep the unstashed jacoco reports: + sh "mvn package -Pskip-checks -Pci-build -DskipTests -Pcoverage-report ${toTestJdkArg(environments.content.jdk.default)}" + + + // WARNING: Make sure credentials are evaluated by sh, not Groovy. + // To that end, escape the '$' when referencing the variables. + // See https://www.jenkins.io/doc/book/pipeline/jenkinsfile/#string-interpolation + withCredentials([usernamePassword( + credentialsId: sonarCredentialsId, + usernameVariable: 'SONARCLOUD_ORGANIZATION', + // https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/scanners/sonarscanner-for-maven/#analyzing + passwordVariable: 'SONAR_TOKEN' + )]) { + // We don't want to use the build cache or build scans for this execution + def miscMavenArgs = '-Dscan=false -Dno-build-cache' + sh """ \ + mvn sonar:sonar \ + ${miscMavenArgs} \ + -Dsonar.organization=\${SONARCLOUD_ORGANIZATION} \ + -Dsonar.host.url=https://sonarcloud.io \ + -Dsonar.projectKey=hibernate_hibernate-validator \ + -Dsonar.projectName="Hibernate Validator" \ + -Dsonar.projectDescription="Hibernate Validator, declare and validate application constraints" \ + ${helper.scmSource.pullRequest ? """ \ + -Dsonar.pullrequest.branch=${helper.scmSource.branch.name} \ + -Dsonar.pullrequest.key=${helper.scmSource.pullRequest.id} \ + -Dsonar.pullrequest.base=${helper.scmSource.pullRequest.target.name} \ + ${helper.scmSource.gitHubRepoId ? """ \ + -Dsonar.pullrequest.provider=GitHub \ + -Dsonar.pullrequest.github.repository=${helper.scmSource.gitHubRepoId} \ + """ : ''} \ + """ : """ \ + -Dsonar.branch.name=${helper.scmSource.branch.name} \ + """} \ + """ + } + } + } + } else { + echo "Skipping Sonar report: no credentials." + } + } + +} // End of helper.runWithNotification + +// Job-specific helpers + +enum TestCondition { + // For environments that are expected to work correctly + // before merging into main or maintenance branches. + // Tested on main and maintenance branches, on feature branches, and for PRs. + BEFORE_MERGE, + // For environments that are expected to work correctly, + // but are considered too resource-intensive to test them on pull requests. + // Tested on main and maintenance branches only. + // Not tested on feature branches or PRs. + AFTER_MERGE, + // For environments that may not work correctly. + // Only tested when explicitly requested through job parameters. + ON_DEMAND; + + // Work around JENKINS-33023 + // See https://issues.jenkins-ci.org/browse/JENKINS-33023?focusedCommentId=325738&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-325738 + public TestCondition() {} +} + +abstract class BuildEnvironment { + boolean isDefault = false + TestCondition condition + String testJavaVersion + String testCompilerTool + String testLauncherTool + String testLauncherArgs + String toString() { getTag() } + abstract String getTag() + boolean isDefault() { isDefault } + boolean requiresDefaultBuildArtifacts() { true } + boolean generatesCoverage() { true } +} + +class JdkBuildEnvironment extends BuildEnvironment { + @Override + String getTag() { "jdk-$testJavaVersion" } + @Override + boolean requiresDefaultBuildArtifacts() { false } +} + +class WildFlyTckBuildEnvironment extends BuildEnvironment { + @Override + String getTag() { "wildfly-tck-jdk$testJavaVersion" } + @Override + boolean requiresDefaultBuildArtifacts() { true } +} + +class SigTestBuildEnvironment extends BuildEnvironment { + String jdkTool + @Override + String getTag() { "sigtest-jdk$testJavaVersion" } + @Override + boolean requiresDefaultBuildArtifacts() { true } + boolean generatesCoverage() { false } +} + +void keepOnlyEnvironmentsMatchingFilter(String regex) { + def pattern = /$regex/ + + boolean enableDefault = ('default' =~ pattern) + + environments.content.each { key, envSet -> + envSet.enabled.removeAll { buildEnv -> + !(buildEnv.tag =~ pattern) && !(envSet.default == buildEnv && enableDefault) + } + } +} + +void keepOnlyEnvironmentsFromSet(String environmentSetName) { + boolean enableDefaultEnv = false + boolean enableBeforeMergeEnvs = false + boolean enableAfterMergeEnvs = false + boolean enableOnDemandEnvs = false + switch (environmentSetName) { + case 'DEFAULT': + enableDefaultEnv = true + break + case 'SUPPORTED': + enableDefaultEnv = true + enableBeforeMergeEnvs = true + enableAfterMergeEnvs = true + break + case 'ALL': + enableDefaultEnv = true + enableBeforeMergeEnvs = true + enableAfterMergeEnvs = true + enableOnDemandEnvs = true + break + case 'AUTOMATIC': + if (helper.scmSource.pullRequest) { + echo "Building pull request '$helper.scmSource.pullRequest.id'" + enableDefaultEnv = true + enableBeforeMergeEnvs = true + } else if (helper.scmSource.branch.primary) { + echo "Building primary branch '$helper.scmSource.branch.name'" + enableDefaultEnv = true + enableBeforeMergeEnvs = true + enableAfterMergeEnvs = true + echo "Legacy integration tests are enabled for the default build environment." + enableDefaultBuildLegacyIT = true + } else { + echo "Building feature branch '$helper.scmSource.branch.name'" + enableDefaultEnv = true + enableBeforeMergeEnvs = true + } + break + default: + throw new IllegalArgumentException( + "Unknown value for param 'ENVIRONMENT_SET': '$environmentSetName'." + ) + } + + // Filter environments + + environments.content.each { key, envSet -> + envSet.enabled.removeAll { buildEnv -> ! ( + enableDefaultEnv && buildEnv.isDefault || + enableBeforeMergeEnvs && buildEnv.condition == TestCondition.BEFORE_MERGE || + enableAfterMergeEnvs && buildEnv.condition == TestCondition.AFTER_MERGE || + enableOnDemandEnvs && buildEnv.condition == TestCondition.ON_DEMAND ) } + } +} + +void runBuildOnNode(Closure body) { + runBuildOnNode( NODE_PATTERN_BASE, body ) +} + +void runBuildOnNode(String label, Closure body) { + node( label ) { + timeout( [time: 1, unit: 'HOURS'], body ) + } +} + +void mavenNonDefaultBuild(BuildEnvironment buildEnv, String args, String projectPath = '.') { + if ( buildEnv.requiresDefaultBuildArtifacts() ) { + dir(helper.configuration.maven.localRepositoryPath) { + unstash name:'default-build-result' + } + } + + // Add a suffix to tests to distinguish between different executions + // of the same test in different environments in reports + def testSuffix = buildEnv.tag.replaceAll('[^a-zA-Z0-9_\\-+]+', '_') + + dir(projectPath) { + mvn """ \ + -Dsurefire.environment=$testSuffix \ + ${toTestJdkArg(buildEnv)} \ + --fail-at-end \ + $args \ + """ + } + + if ( buildEnv.generatesCoverage() ) { + // We allow an empty stash here since it can happen that a PR build is triggered + // but because of incremental build there will be no tests executed and no jacoco files generated: + stash name: "${buildEnv.tag}-build-jacoco-reports", includes:"**/jacoco.exec", allowEmpty: true + } +} + +String toTestJdkArg(BuildEnvironment buildEnv) { + String args = '' + + String testCompilerTool = buildEnv.testCompilerTool + if ( testCompilerTool && DEFAULT_JDK_TOOL != testCompilerTool ) { + def testCompilerToolPath = tool(name: testCompilerTool, type: 'jdk') + args += " -Djava-version.test.compiler.java_home=$testCompilerToolPath" + } + // Note: the POM uses the java_home of the test compiler for the test launcher by default. + String testLauncherTool = buildEnv.testLauncherTool + if ( testLauncherTool && DEFAULT_JDK_TOOL != testLauncherTool ) { + def testLauncherToolPath = tool(name: testLauncherTool, type: 'jdk') + args += " -Djava-version.test.launcher.java_home=$testLauncherToolPath" + } + String defaultVersion = environments.content.jdk.default.testJavaVersion + String version = buildEnv.testJavaVersion + if ( defaultVersion != version ) { + args += " -Djava-version.test.release=$version" + } + + if ( buildEnv.testLauncherArgs ) { + args += " -Dsurefire.jvm.args.commandline=${buildEnv.testLauncherArgs}" + } + + return args +} + +void withMavenWorkspace(Closure body) { + withMavenWorkspace([:], body) +} + +void withMavenWorkspace(Map args, Closure body) { + args.put("options", [ + // Artifacts are not needed and take up disk space + artifactsPublisher(disabled: true), + // stdout/stderr for successful tests is not needed and takes up disk space + // we archive test results and stdout/stderr as part of the build scan anyway, + // see https://develocity.commonhaus.dev/scans?search.rootProjectNames=Hibernate%20Validator + junitPublisher(disabled: true) + ]) + helper.withMavenWorkspace(args, body) +} + +void mvn(String args) { + def develocityMainCredentialsId = helper.configuration.file?.develocity?.credentials?.main + def develocityPrCredentialsId = helper.configuration.file?.develocity?.credentials?.pr + def develocityBaseUrl = helper.configuration.file?.develocity?.url + if ( !helper.scmSource.pullRequest && develocityMainCredentialsId ) { + // Not a PR: we can pass credentials to the build, allowing it to populate the build cache + // and to publish build scans directly. + withEnv(["DEVELOCITY_BASE_URL=${develocityBaseUrl}"]) { + withCredentials([string(credentialsId: develocityMainCredentialsId, + variable: 'DEVELOCITY_ACCESS_KEY')]) { + withGradle { // withDevelocity, actually: https://plugins.jenkins.io/gradle/#plugin-content-capturing-build-scans-from-jenkins-pipeline + sh "mvn $args" + } + } + } + } + else if ( helper.scmSource.pullRequest && develocityPrCredentialsId ) { + // Pull request: we can't pass credentials to the build, since we'd be exposing secrets to e.g. tests. + // We do the build first, then publish the build scan separately. + tryFinally({ + sh "mvn $args" + }, { // Finally + withEnv(["DEVELOCITY_BASE_URL=${develocityBaseUrl}"]) { + withCredentials([string(credentialsId: develocityPrCredentialsId, + variable: 'DEVELOCITY_ACCESS_KEY')]) { + withGradle { // withDevelocity, actually: https://plugins.jenkins.io/gradle/#plugin-content-capturing-build-scans-from-jenkins-pipeline + sh 'mvn develocity:build-scan-publish-previous || true' + } + } + } + }) + } + else { + // No Develocity credentials. + sh "mvn $args" + } +} + +// try-finally construct that properly suppresses exceptions thrown in the finally block. +def tryFinally(Closure main, Closure ... finallies) { + def mainFailure = null + try { + main() + } + catch (Throwable t) { + mainFailure = t + throw t + } + finally { + finallies.each {it -> + try { + it() + } + catch (Throwable t) { + if ( mainFailure ) { + mainFailure.addSuppressed( t ) + } + else { + mainFailure = t + } + } + } + } + if ( mainFailure ) { // We may reach here if only the "finally" failed + throw mainFailure + } +} From 1a10c3e32fe5f25e83ba72607a0819e4a7861cbc Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Thu, 12 Jun 2025 18:56:06 +0200 Subject: [PATCH 118/124] Use Oracle JDK for builds so that there are no complaints about javafx --- Jenkinsfile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 8b1a32b718..5daa73b2c8 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -77,7 +77,7 @@ import org.hibernate.jenkins.pipeline.helpers.alternative.AlternativeMultiMap * */ -@Field final String DEFAULT_JDK_TOOL = 'OpenJDK 8 Latest' +@Field final String DEFAULT_JDK_TOOL = 'OracleJDK8 Latest' @Field final String MAVEN_TOOL = 'Apache Maven 3.9' // Default node pattern, to be used for resource-intensive stages. @@ -112,23 +112,23 @@ helper.runWithNotification { this.environments = AlternativeMultiMap.create([ jdk: [ - new JdkBuildEnvironment(testJavaVersion: '8', testCompilerTool: 'OpenJDK 8 Latest', + new JdkBuildEnvironment(testJavaVersion: '8', testCompilerTool: 'OracleJDK8 Latest', condition: TestCondition.BEFORE_MERGE, isDefault: true), // We want to enable preview features when testing newer builds of OpenJDK: // even if we don't use these features, just enabling them can cause side effects // and it's useful to test that. - new JdkBuildEnvironment(testJavaVersion: '9', testCompilerTool: 'OpenJDK 9 Latest', + new JdkBuildEnvironment(testJavaVersion: '9', testCompilerTool: 'OracleJDK 9 Latest', testLauncherArgs: '--enable-preview', condition: TestCondition.AFTER_MERGE) ], wildflyTck: [ - new WildFlyTckBuildEnvironment(testJavaVersion: '8', testCompilerTool: 'OpenJDK 8 Latest', + new WildFlyTckBuildEnvironment(testJavaVersion: '8', testCompilerTool: 'OracleJDK8 Latest', condition: TestCondition.ON_DEMAND) ], sigtest: [ - new SigTestBuildEnvironment(testJavaVersion: '8', jdkTool: 'OpenJDK 8 Latest', + new SigTestBuildEnvironment(testJavaVersion: '8', jdkTool: 'OracleJDK8 Latest', condition: TestCondition.BEFORE_MERGE) ] ]) From 324eb220766277ed0d5452adfe0ebf0094a007f2 Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Thu, 12 Jun 2025 09:39:36 +0200 Subject: [PATCH 119/124] HV-1816 Partial backport of internal changes only config option applied through the env/system property --- .../engine/MessageInterpolatorContext.java | 11 +++- .../internal/engine/ValidationContext.java | 31 +++++++++-- .../internal/engine/ValidatorContextImpl.java | 3 ++ .../internal/engine/ValidatorFactoryImpl.java | 52 +++++++++++++++---- .../internal/engine/ValidatorImpl.java | 14 +++-- .../constraintvalidation/ConstraintTree.java | 3 +- .../ConstraintValidatorContextImpl.java | 45 ++++++++++------ .../ConstraintViolationCreationContext.java | 11 +++- .../validator/internal/util/logging/Log.java | 10 ++++ .../GetEnvOrSystemVariableValue.java | 36 +++++++++++++ .../AbstractMessageInterpolator.java | 35 ++++++++----- .../ConstraintValidatorContextImplTest.java | 2 +- ...bernateConstraintValidatorContextTest.java | 12 +++++ ...ssionLanguageMessageInterpolationTest.java | 15 ++++-- .../MessageInterpolatorContextTest.java | 10 ++-- ...ResourceBundleMessageInterpolatorTest.java | 3 +- .../validator/testutils/ValidatorUtil.java | 2 +- tck-runner/src/test/resources/test.policy | 6 ++- 18 files changed, 233 insertions(+), 68 deletions(-) create mode 100644 engine/src/main/java/org/hibernate/validator/internal/util/privilegedactions/GetEnvOrSystemVariableValue.java diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/MessageInterpolatorContext.java b/engine/src/main/java/org/hibernate/validator/internal/engine/MessageInterpolatorContext.java index 949d3d2133..0f9a6b0703 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/MessageInterpolatorContext.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/MessageInterpolatorContext.java @@ -28,15 +28,18 @@ public class MessageInterpolatorContext implements HibernateMessageInterpolatorC private final Object validatedValue; private final Class rootBeanType; private final Map messageParameters; + private final boolean expressionLanguageEnabled; public MessageInterpolatorContext(ConstraintDescriptor constraintDescriptor, Object validatedValue, Class rootBeanType, - Map messageParameters) { + Map messageParameters, + boolean expressionLanguageEnabled) { this.constraintDescriptor = constraintDescriptor; this.validatedValue = validatedValue; this.rootBeanType = rootBeanType; this.messageParameters = messageParameters; + this.expressionLanguageEnabled = expressionLanguageEnabled; } @Override @@ -58,6 +61,11 @@ public Map getMessageParameters() { return messageParameters; } + + public boolean isExpressionLanguageEnabled() { + return expressionLanguageEnabled; + } + @Override public T unwrap(Class type) { //allow unwrapping into public super types @@ -105,6 +113,7 @@ public String toString() { sb.append( "MessageInterpolatorContext" ); sb.append( "{constraintDescriptor=" ).append( constraintDescriptor ); sb.append( ", validatedValue=" ).append( validatedValue ); + sb.append( ", expressionLanguageEnabled=" ).append( expressionLanguageEnabled ); sb.append( '}' ); return sb.toString(); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidationContext.java b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidationContext.java index 28455f6a65..e26bd0b265 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidationContext.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidationContext.java @@ -149,6 +149,8 @@ public class ValidationContext { private final TimeProvider timeProvider; + private final boolean expressionLanguageEnabled; + private ValidationContext(ConstraintValidatorManager constraintValidatorManager, MessageInterpolator messageInterpolator, ConstraintValidatorFactory constraintValidatorFactory, @@ -158,6 +160,7 @@ private ValidationContext(ConstraintValidatorManager constraintValidatorManager, List> validatedValueUnwrappers, TypeResolutionHelper typeResolutionHelper, boolean failFast, + boolean expressionLanguageEnabled, T rootBean, Class rootBeanClass, ExecutableElement executable, @@ -172,6 +175,7 @@ private ValidationContext(ConstraintValidatorManager constraintValidatorManager, this.validatedValueUnwrappers = validatedValueUnwrappers; this.typeResolutionHelper = typeResolutionHelper; this.failFast = failFast; + this.expressionLanguageEnabled = expressionLanguageEnabled; this.rootBean = rootBean; this.rootBeanClass = rootBeanClass; @@ -193,8 +197,9 @@ public static ValidationContextBuilder getValidationContext( TimeProvider timeProvider, List> validatedValueUnwrappers, TypeResolutionHelper typeResolutionHelper, - boolean failFast) { - + boolean failFast, + boolean expressionLanguageEnabled + ) { return new ValidationContextBuilder( constraintValidatorManager, messageInterpolator, @@ -203,7 +208,8 @@ public static ValidationContextBuilder getValidationContext( timeProvider, validatedValueUnwrappers, typeResolutionHelper, - failFast + failFast, + expressionLanguageEnabled ); } @@ -299,6 +305,7 @@ public ConstraintViolation createConstraintViolation(ValueContext local String messageTemplate = constraintViolationCreationContext.getMessage(); String interpolatedMessage = interpolate( messageTemplate, + constraintViolationCreationContext.isExpressionLanguageEnabled(), localContext.getCurrentValidatedValue(), descriptor, constraintViolationCreationContext.getExpressionVariables() @@ -402,6 +409,10 @@ public ValidatedValueUnwrapper getValidatedValueUnwrapper(Type type) { return null; } + public boolean isExpressionLanguageEnabled() { + return expressionLanguageEnabled; + } + @Override public String toString() { final StringBuilder sb = new StringBuilder(); @@ -412,6 +423,7 @@ public String toString() { } private String interpolate(String messageTemplate, + boolean expressionLanguageEnabled, Object validatedValue, ConstraintDescriptor descriptor, Map messageParameters) { @@ -419,7 +431,8 @@ private String interpolate(String messageTemplate, descriptor, validatedValue, getRootBeanClass(), - messageParameters + messageParameters, + expressionLanguageEnabled ); try { @@ -511,6 +524,7 @@ public static class ValidationContextBuilder { private final List> validatedValueUnwrappers; private final TypeResolutionHelper typeResolutionHelper; private final boolean failFast; + private final boolean expressionLanguageEnabled; private ValidationContextBuilder( ConstraintValidatorManager constraintValidatorManager, @@ -520,7 +534,8 @@ private ValidationContextBuilder( TimeProvider timeProvider, List> validatedValueUnwrappers, TypeResolutionHelper typeResolutionHelper, - boolean failFast) { + boolean failFast, + boolean expressionLanguageEnabled) { this.constraintValidatorManager = constraintValidatorManager; this.messageInterpolator = messageInterpolator; this.constraintValidatorFactory = constraintValidatorFactory; @@ -529,6 +544,7 @@ private ValidationContextBuilder( this.validatedValueUnwrappers = validatedValueUnwrappers; this.typeResolutionHelper = typeResolutionHelper; this.failFast = failFast; + this.expressionLanguageEnabled = expressionLanguageEnabled; } public ValidationContext forValidate(T rootBean) { @@ -544,6 +560,7 @@ public ValidationContext forValidate(T rootBean) { validatedValueUnwrappers, typeResolutionHelper, failFast, + expressionLanguageEnabled, rootBean, rootBeanClass, null, //executable @@ -565,6 +582,7 @@ public ValidationContext forValidateProperty(T rootBean) { validatedValueUnwrappers, typeResolutionHelper, failFast, + expressionLanguageEnabled, rootBean, rootBeanClass, null, //executable @@ -584,6 +602,7 @@ public ValidationContext forValidateValue(Class rootBeanClass) { validatedValueUnwrappers, typeResolutionHelper, failFast, + expressionLanguageEnabled, null, //root bean rootBeanClass, null, //executable @@ -610,6 +629,7 @@ public ValidationContext forValidateParameters( validatedValueUnwrappers, typeResolutionHelper, failFast, + expressionLanguageEnabled, rootBean, rootBeanClass, executable, @@ -635,6 +655,7 @@ public ValidationContext forValidateReturnValue( validatedValueUnwrappers, typeResolutionHelper, failFast, + expressionLanguageEnabled, rootBean, rootBeanClass, executable, diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorContextImpl.java index 93dba04526..f46a665331 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorContextImpl.java @@ -35,6 +35,7 @@ public class ValidatorContextImpl implements HibernateValidatorContext { private ConstraintValidatorFactory constraintValidatorFactory; private ParameterNameProvider parameterNameProvider; private boolean failFast; + private final boolean expressionLanguageEnabled; private final List> validatedValueHandlers; private TimeProvider timeProvider; private final MethodValidationConfiguration methodValidationConfiguration = new MethodValidationConfiguration(); @@ -47,6 +48,7 @@ public ValidatorContextImpl(ValidatorFactoryImpl validatorFactory) { this.constraintValidatorFactory = validatorFactory.getConstraintValidatorFactory(); this.parameterNameProvider = validatorFactory.getParameterNameProvider(); this.failFast = validatorFactory.isFailFast(); + this.expressionLanguageEnabled = validatorFactory.isExpressionLanguageEnabled(); this.validatedValueHandlers = new ArrayList>( validatorFactory.getValidatedValueHandlers() ); @@ -146,6 +148,7 @@ public Validator getValidator() { traversableResolver, parameterNameProvider, failFast, + expressionLanguageEnabled, validatedValueHandlers, timeProvider, methodValidationConfiguration diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorFactoryImpl.java b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorFactoryImpl.java index bd1b1dd6a5..237d83b184 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorFactoryImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorFactoryImpl.java @@ -17,7 +17,6 @@ import java.util.List; import java.util.Map; import java.util.Set; - import javax.validation.ConstraintValidatorFactory; import javax.validation.MessageInterpolator; import javax.validation.ParameterNameProvider; @@ -43,6 +42,7 @@ import org.hibernate.validator.internal.util.TypeResolutionHelper; import org.hibernate.validator.internal.util.logging.Log; import org.hibernate.validator.internal.util.logging.LoggerFactory; +import org.hibernate.validator.internal.util.privilegedactions.GetEnvOrSystemVariableValue; import org.hibernate.validator.internal.util.privilegedactions.LoadClass; import org.hibernate.validator.internal.util.privilegedactions.NewInstance; import org.hibernate.validator.spi.cfg.ConstraintMappingContributor; @@ -63,6 +63,9 @@ public class ValidatorFactoryImpl implements HibernateValidatorFactory { private static final Log log = LoggerFactory.make(); + private static final String EXPRESSION_LANGUAGE_ENABLED_ENV = "ORG_HIBERNATE_VALIDATOR_EXPRESSION_LANGUAGE_ENABLED"; + private static final String EXPRESSION_LANGUAGE_ENABLED_SYSTEM = "org.hibernate.validator.expressionLanguageEnabled"; + /** * The default message interpolator for this factory. */ @@ -114,6 +117,11 @@ public class ValidatorFactoryImpl implements HibernateValidatorFactory { */ private final boolean failFast; + /** + * Hibernate Validator specific flag to enable Expression Language message interpolation. + */ + private final boolean expressionLanguageEnabled; + /** * Hibernate validator specific flags to relax constraints on parameters. */ @@ -208,6 +216,7 @@ public ValidatorFactoryImpl(ConfigurationState configurationState) { tmpFailFast = checkPropertiesForBoolean( properties, HibernateValidatorConfiguration.FAIL_FAST, tmpFailFast ); this.failFast = tmpFailFast; + this.expressionLanguageEnabled = getExpressionLanguageEnabled(); this.methodValidationConfiguration = new MethodValidationConfiguration(); @@ -265,8 +274,10 @@ private static Set getConstraintMappings(Configuration } // XML-defined constraint mapping contributors - List contributors = getPropertyConfiguredConstraintMappingContributors( configurationState.getProperties(), - externalClassLoader ); + List contributors = getPropertyConfiguredConstraintMappingContributors( + configurationState.getProperties(), + externalClassLoader + ); for ( ConstraintMappingContributor contributor : contributors ) { DefaultConstraintMappingBuilder builder = new DefaultConstraintMappingBuilder( constraintMappings ); @@ -303,6 +314,15 @@ private static TimeProvider getTimeProvider(ConfigurationState configurationStat return timeProvider != null ? timeProvider : DefaultTimeProvider.getInstance(); } + private static boolean getExpressionLanguageEnabled() { + String enable = run( GetEnvOrSystemVariableValue.action( EXPRESSION_LANGUAGE_ENABLED_ENV, EXPRESSION_LANGUAGE_ENABLED_SYSTEM ) ); + if ( enable == null ) { + log.expressionLanguageFeaturesNoExplicitSetting( EXPRESSION_LANGUAGE_ENABLED_ENV, EXPRESSION_LANGUAGE_ENABLED_SYSTEM ); + enable = "false"; + } + return "true".equalsIgnoreCase( enable ); + } + @Override public Validator getValidator() { return createValidator( @@ -311,6 +331,7 @@ public Validator getValidator() { traversableResolver, parameterNameProvider, failFast, + expressionLanguageEnabled, validatedValueHandlers, timeProvider, methodValidationConfiguration @@ -341,6 +362,10 @@ public boolean isFailFast() { return failFast; } + public boolean isExpressionLanguageEnabled() { + return expressionLanguageEnabled; + } + public List> getValidatedValueHandlers() { return validatedValueHandlers; } @@ -374,14 +399,17 @@ public void close() { xmlMetaDataProvider = null; } - Validator createValidator(ConstraintValidatorFactory constraintValidatorFactory, + Validator createValidator( + ConstraintValidatorFactory constraintValidatorFactory, MessageInterpolator messageInterpolator, TraversableResolver traversableResolver, ParameterNameProvider parameterNameProvider, boolean failFast, + boolean expressionLanguageEnabled, List> validatedValueHandlers, TimeProvider timeProvider, - MethodValidationConfiguration methodValidationConfiguration) { + MethodValidationConfiguration methodValidationConfiguration + ) { BeanMetaDataManager beanMetaDataManager; if ( !beanMetaDataManagerMap.containsKey( parameterNameProvider ) ) { @@ -408,7 +436,8 @@ Validator createValidator(ConstraintValidatorFactory constraintValidatorFactory, typeResolutionHelper, validatedValueHandlers, constraintValidatorManager, - failFast + failFast, + expressionLanguageEnabled ); } @@ -449,7 +478,6 @@ private boolean checkPropertiesForBoolean(Map properties, String * {@link HibernateValidatorConfiguration#VALIDATED_VALUE_HANDLERS} property. * * @param properties the properties used to bootstrap the factory - * * @return a list with property-configured {@link ValidatedValueUnwrapper}s; May be empty but never {@code null} */ private static List> getPropertyConfiguredValidatedValueHandlers( @@ -481,7 +509,6 @@ private static List> getPropertyConfiguredValidatedVa * property. * * @param properties the properties used to bootstrap the factory - * * @return a list with property-configured {@link ContraintMappingContributor}s; May be empty but never {@code null} */ private static List getPropertyConfiguredConstraintMappingContributors( @@ -517,8 +544,10 @@ private static List getPropertyConfiguredConstrain return contributors; } - private static void registerCustomConstraintValidators(Set constraintMappings, - ConstraintHelper constraintHelper) { + private static void registerCustomConstraintValidators( + Set constraintMappings, + ConstraintHelper constraintHelper + ) { Set> definedConstraints = newHashSet(); for ( DefaultConstraintMapping constraintMapping : constraintMappings ) { for ( ConstraintDefinitionContribution contribution : constraintMapping.getConstraintDefinitionContributions() ) { @@ -529,7 +558,8 @@ private static void registerCustomConstraintValidators(Set void processConstraintDefinitionContribution( ConstraintDefinitionContribution constraintDefinitionContribution, ConstraintHelper constraintHelper, - Set> definedConstraints) { + Set> definedConstraints + ) { Class constraintType = constraintDefinitionContribution.getConstraintType(); if ( definedConstraints.contains( constraintType ) ) { throw log.getConstraintHasAlreadyBeenConfiguredViaProgrammaticApiException( constraintType.getName() ); diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java index 9ac7a1f8f0..427bd59814 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java @@ -143,6 +143,11 @@ public class ValidatorImpl implements Validator, ExecutableValidator { */ private final boolean failFast; + /** + * Hibernate Validator specific flag to enable Expression Language message interpolation. + */ + private final boolean expressionLanguageEnabled; + /** * Used for resolving generic type information. */ @@ -167,7 +172,8 @@ public ValidatorImpl(ConstraintValidatorFactory constraintValidatorFactory, TypeResolutionHelper typeResolutionHelper, List> validatedValueHandlers, ConstraintValidatorManager constraintValidatorManager, - boolean failFast) { + boolean failFast, + boolean expressionLanguageEnabled) { this.constraintValidatorFactory = constraintValidatorFactory; this.messageInterpolator = messageInterpolator; this.traversableResolver = traversableResolver; @@ -178,6 +184,7 @@ public ValidatorImpl(ConstraintValidatorFactory constraintValidatorFactory, this.validatedValueHandlers = validatedValueHandlers; this.constraintValidatorManager = constraintValidatorManager; this.failFast = failFast; + this.expressionLanguageEnabled = expressionLanguageEnabled; validationOrderGenerator = new ValidationOrderGenerator(); @@ -353,7 +360,8 @@ private ValidationContextBuilder getValidationContext() { timeProvider, validatedValueHandlers, typeResolutionHelper, - failFast + failFast, + expressionLanguageEnabled ); } @@ -1565,8 +1573,8 @@ private ValueContext collectMetaConstraintsForPathWithoutValue(Validat PathImpl propertyPath, List> metaConstraints, List> typeArgumentConstraints) { - Class clazz = validationContext.getRootBeanClass(); PropertyMetaData propertyMetaData = null; + Class clazz = validationContext.getRootBeanClass(); Iterator propertyPathIter = propertyPath.iterator(); diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/constraintvalidation/ConstraintTree.java b/engine/src/main/java/org/hibernate/validator/internal/engine/constraintvalidation/ConstraintTree.java index 653920f826..da7b7cb5a4 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/constraintvalidation/ConstraintTree.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/constraintvalidation/ConstraintTree.java @@ -120,7 +120,8 @@ private void validateConstraints(ValidationContext validationContext, validationContext.getParameterNames(), validationContext.getTimeProvider(), valueContext.getPropertyPath(), - descriptor + descriptor, + validationContext.isExpressionLanguageEnabled() ); // validate diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/constraintvalidation/ConstraintValidatorContextImpl.java b/engine/src/main/java/org/hibernate/validator/internal/engine/constraintvalidation/ConstraintValidatorContextImpl.java index 7346f7357a..9fbf798a98 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/constraintvalidation/ConstraintValidatorContextImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/constraintvalidation/ConstraintValidatorContextImpl.java @@ -9,6 +9,7 @@ import static org.hibernate.validator.internal.util.CollectionHelper.newArrayList; import static org.hibernate.validator.internal.util.CollectionHelper.newHashMap; +import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -37,6 +38,7 @@ public class ConstraintValidatorContextImpl implements HibernateConstraintValida private static final Log log = LoggerFactory.make(); + private final boolean expressionLanguageEnabled; private final Map expressionVariables = newHashMap(); private final List methodParameterNames; private final TimeProvider timeProvider; @@ -47,7 +49,8 @@ public class ConstraintValidatorContextImpl implements HibernateConstraintValida private Object dynamicPayload; public ConstraintValidatorContextImpl(List methodParameterNames, TimeProvider timeProvider, PathImpl propertyPath, - ConstraintDescriptor constraintDescriptor) { + ConstraintDescriptor constraintDescriptor, boolean expressionLanguageEnabled) { + this.expressionLanguageEnabled = expressionLanguageEnabled; this.methodParameterNames = methodParameterNames; this.timeProvider = timeProvider; this.basePath = propertyPath; @@ -118,6 +121,7 @@ public final List getConstraintViolationCrea returnedConstraintViolationCreationContexts.add( new ConstraintViolationCreationContext( getDefaultConstraintMessageTemplate(), + true, // EL is enabled for the default constraint violation basePath, parameterMapCopy, dynamicPayload @@ -134,18 +138,25 @@ public List getMethodParameterNames() { private abstract class NodeBuilderBase { protected final String messageTemplate; protected PathImpl propertyPath; + protected final boolean expressionLanguageEnabled; - protected NodeBuilderBase(String template, PathImpl path) { + protected NodeBuilderBase(String template, PathImpl path, boolean expressionLanguageEnabled) { this.messageTemplate = template; this.propertyPath = path; + this.expressionLanguageEnabled = expressionLanguageEnabled; } public ConstraintValidatorContext addConstraintViolation() { + if ( !(expressionVariables == null || expressionVariables.isEmpty()) && !expressionLanguageEnabled ) { + log.expressionVariablesDefinedWithExpressionLanguageNotEnabled( + constraintDescriptor.getAnnotation() != null ? constraintDescriptor.getAnnotation().annotationType() : Annotation.class ); + } Map parameterMapCopy = newHashMap(); parameterMapCopy.putAll( expressionVariables ); constraintViolationCreationContexts.add( new ConstraintViolationCreationContext( messageTemplate, + expressionLanguageEnabled, propertyPath, parameterMapCopy, dynamicPayload @@ -160,7 +171,7 @@ private class ConstraintViolationBuilderImpl extends NodeBuilderBase implements private final List methodParameterNames; private ConstraintViolationBuilderImpl(List methodParameterNames, String template, PathImpl path) { - super( template, path ); + super( template, path, ConstraintValidatorContextImpl.this.expressionLanguageEnabled ); this.methodParameterNames = methodParameterNames; } @@ -169,19 +180,19 @@ public NodeBuilderDefinedContext addNode(String name) { dropLeafNodeIfRequired(); propertyPath.addPropertyNode( name ); - return new NodeBuilder( messageTemplate, propertyPath ); + return new NodeBuilder( messageTemplate, propertyPath, expressionLanguageEnabled ); } @Override public NodeBuilderCustomizableContext addPropertyNode(String name) { dropLeafNodeIfRequired(); - return new DeferredNodeBuilder( messageTemplate, propertyPath, name ); + return new DeferredNodeBuilder( messageTemplate, propertyPath, expressionLanguageEnabled,name ); } @Override public LeafNodeBuilderCustomizableContext addBeanNode() { - return new DeferredNodeBuilder( messageTemplate, propertyPath, null ); + return new DeferredNodeBuilder( messageTemplate, propertyPath, expressionLanguageEnabled, null ); } @Override @@ -193,7 +204,7 @@ public NodeBuilderDefinedContext addParameterNode(int index) { dropLeafNodeIfRequired(); propertyPath.addParameterNode( methodParameterNames.get( index ), index ); - return new NodeBuilder( messageTemplate, propertyPath ); + return new NodeBuilder( messageTemplate, propertyPath, expressionLanguageEnabled ); } /** @@ -212,8 +223,8 @@ private void dropLeafNodeIfRequired() { private class NodeBuilder extends NodeBuilderBase implements NodeBuilderDefinedContext, LeafNodeBuilderDefinedContext { - private NodeBuilder(String template, PathImpl path) { - super( template, path ); + private NodeBuilder(String template, PathImpl path, boolean expressionLanguageEnabled) { + super( template, path, expressionLanguageEnabled ); } @Override @@ -224,12 +235,12 @@ public ConstraintViolationBuilder.NodeBuilderCustomizableContext addNode(String @Override public NodeBuilderCustomizableContext addPropertyNode(String name) { - return new DeferredNodeBuilder( messageTemplate, propertyPath, name ); + return new DeferredNodeBuilder( messageTemplate, propertyPath, expressionLanguageEnabled, name ); } @Override public LeafNodeBuilderCustomizableContext addBeanNode() { - return new DeferredNodeBuilder( messageTemplate, propertyPath, null ); + return new DeferredNodeBuilder( messageTemplate, propertyPath, expressionLanguageEnabled, null ); } } @@ -238,8 +249,8 @@ private class DeferredNodeBuilder extends NodeBuilderBase private final String leafNodeName; - private DeferredNodeBuilder(String template, PathImpl path, String nodeName) { - super( template, path ); + private DeferredNodeBuilder(String template, PathImpl path, boolean expressionLanguageEnabled, String nodeName) { + super( template, path, expressionLanguageEnabled ); this.leafNodeName = nodeName; } @@ -253,14 +264,14 @@ public DeferredNodeBuilder inIterable() { public NodeBuilder atKey(Object key) { propertyPath.setLeafNodeMapKey( key ); addLeafNode(); - return new NodeBuilder( messageTemplate, propertyPath ); + return new NodeBuilder( messageTemplate, propertyPath, expressionLanguageEnabled ); } @Override public NodeBuilder atIndex(Integer index) { propertyPath.setLeafNodeIndex( index ); addLeafNode(); - return new NodeBuilder( messageTemplate, propertyPath ); + return new NodeBuilder( messageTemplate, propertyPath, expressionLanguageEnabled ); } @Override @@ -272,13 +283,13 @@ public NodeBuilderCustomizableContext addNode(String name) { @Override public NodeBuilderCustomizableContext addPropertyNode(String name) { addLeafNode(); - return new DeferredNodeBuilder( messageTemplate, propertyPath, name ); + return new DeferredNodeBuilder( messageTemplate, propertyPath, expressionLanguageEnabled, name ); } @Override public LeafNodeBuilderCustomizableContext addBeanNode() { addLeafNode(); - return new DeferredNodeBuilder( messageTemplate, propertyPath, null ); + return new DeferredNodeBuilder( messageTemplate, propertyPath, expressionLanguageEnabled, null ); } @Override diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/constraintvalidation/ConstraintViolationCreationContext.java b/engine/src/main/java/org/hibernate/validator/internal/engine/constraintvalidation/ConstraintViolationCreationContext.java index fc4283a50e..68a810f630 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/constraintvalidation/ConstraintViolationCreationContext.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/constraintvalidation/ConstraintViolationCreationContext.java @@ -18,16 +18,18 @@ */ public class ConstraintViolationCreationContext { private final String message; + private final boolean expressionLanguageEnabled; private final PathImpl propertyPath; private final Map expressionVariables; private final Object dynamicPayload; public ConstraintViolationCreationContext(String message, PathImpl property) { - this( message, property, Collections.emptyMap(), null ); + this( message, true, property, Collections.emptyMap(), null ); } - public ConstraintViolationCreationContext(String message, PathImpl property, Map expressionVariables, Object dynamicPayload) { + public ConstraintViolationCreationContext(String message, boolean expressionLanguageEnabled, PathImpl property, Map expressionVariables, Object dynamicPayload) { this.message = message; + this.expressionLanguageEnabled = expressionLanguageEnabled; this.propertyPath = property; this.expressionVariables = expressionVariables; this.dynamicPayload = dynamicPayload; @@ -37,6 +39,10 @@ public final String getMessage() { return message; } + public boolean isExpressionLanguageEnabled() { + return expressionLanguageEnabled; + } + public final PathImpl getPath() { return propertyPath; } @@ -53,6 +59,7 @@ public Object getDynamicPayload() { public String toString() { final StringBuilder sb = new StringBuilder( "ConstraintViolationCreationContext{" ); sb.append( "message='" ).append( message ).append( '\'' ); + sb.append( ", expressionLanguageEnabled=" ).append( expressionLanguageEnabled ); sb.append( ", propertyPath=" ).append( propertyPath ); sb.append( ", messageParameters=" ).append( expressionVariables ); sb.append( ", dynamicPayload=" ).append( dynamicPayload ); diff --git a/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java b/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java index aff3df834f..f5640fda0a 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java +++ b/engine/src/main/java/org/hibernate/validator/internal/util/logging/Log.java @@ -9,6 +9,7 @@ import static org.jboss.logging.Logger.Level.INFO; import static org.jboss.logging.Logger.Level.WARN; +import java.lang.annotation.Annotation; import java.lang.annotation.ElementType; import java.lang.reflect.Member; import java.lang.reflect.Method; @@ -652,4 +653,13 @@ UnexpectedTypeException getNoValidatorFoundForTypeException(String constraintTyp @Message(id = 196, value = "Unable to convert the Type %s to a Class.") ValidationException getUnableToConvertTypeToClassException(Type type); + + // Message ID is to match the one from the "future" versions of HV from which this change is cherry-picked + @LogMessage(level = WARN) + @Message(id = 257, value = "Expression variables have been defined for constraint %1$s while Expression Language is not enabled.") + void expressionVariablesDefinedWithExpressionLanguageNotEnabled(Class constraintAnnotation); + + @LogMessage(level = WARN) + @Message(id = 258, value = "Expression Language interpolation features are not explicitly enabled/disabled. Use '%1$s' environment variable, or '%2$s' system property to define the behavior. Defaulting to expression language features being disabled.") + void expressionLanguageFeaturesNoExplicitSetting(String expressionLanguageEnabledEnv, String expressionLanguageEnabledSystem); } diff --git a/engine/src/main/java/org/hibernate/validator/internal/util/privilegedactions/GetEnvOrSystemVariableValue.java b/engine/src/main/java/org/hibernate/validator/internal/util/privilegedactions/GetEnvOrSystemVariableValue.java new file mode 100644 index 0000000000..41e45bf91a --- /dev/null +++ b/engine/src/main/java/org/hibernate/validator/internal/util/privilegedactions/GetEnvOrSystemVariableValue.java @@ -0,0 +1,36 @@ +/* + * Hibernate Validator, declare and validate application constraints + * + * License: Apache License, Version 2.0 + * See the license.txt file in the root directory or . + */ +package org.hibernate.validator.internal.util.privilegedactions; + +import java.security.PrivilegedAction; + +/** + * Get an environment variable {@code System.getenv(..)} or if unavailable -- system property {@code System.getProperty(..)}. + */ +public final class GetEnvOrSystemVariableValue implements PrivilegedAction { + + private final String environmentVariableName; + private final String systemPropertyName; + + public static GetEnvOrSystemVariableValue action(String environmentVariableName, String systemPropertyName) { + return new GetEnvOrSystemVariableValue( environmentVariableName, systemPropertyName ); + } + + private GetEnvOrSystemVariableValue(String environmentVariableName, String systemPropertyName) { + this.environmentVariableName = environmentVariableName; + this.systemPropertyName = systemPropertyName; + } + + @Override + public String run() { + String value = System.getenv( environmentVariableName ); + if ( value == null ) { + value = System.getProperty( systemPropertyName ); + } + return value; + } +} diff --git a/engine/src/main/java/org/hibernate/validator/messageinterpolation/AbstractMessageInterpolator.java b/engine/src/main/java/org/hibernate/validator/messageinterpolation/AbstractMessageInterpolator.java index 5ae55bc8d5..790b0cfbca 100644 --- a/engine/src/main/java/org/hibernate/validator/messageinterpolation/AbstractMessageInterpolator.java +++ b/engine/src/main/java/org/hibernate/validator/messageinterpolation/AbstractMessageInterpolator.java @@ -17,6 +17,7 @@ import javax.validation.MessageInterpolator; import javax.validation.ValidationException; +import org.hibernate.validator.internal.engine.MessageInterpolatorContext; import org.hibernate.validator.internal.engine.messageinterpolation.InterpolationTermType; import org.hibernate.validator.internal.engine.messageinterpolation.LocalizedMessage; import org.hibernate.validator.internal.engine.messageinterpolation.parser.MessageDescriptorFormatException; @@ -329,23 +330,29 @@ private String interpolateMessage(String message, Context context, Locale locale ); // resolve EL expressions (step 5) - tokens = null; - if ( cachingEnabled ) { - tokens = tokenizedELMessages.get( resolvedMessage ); - } - if ( tokens == null ) { - TokenCollector tokenCollector = new TokenCollector( resolvedMessage, InterpolationTermType.EL ); - tokens = tokenCollector.getTokenList(); - + // in the standard Hibernate Validator execution flow, the context is always an instance of + // HibernateMessageInterpolatorContext + // but it can be a spec Context in the Jakarta Bean Validation TCK. + if ( !( context instanceof HibernateMessageInterpolatorContext ) + || ( (MessageInterpolatorContext) context ).isExpressionLanguageEnabled() ) { + tokens = null; if ( cachingEnabled ) { - tokenizedELMessages.putIfAbsent( resolvedMessage, tokens ); + tokens = tokenizedELMessages.get( resolvedMessage ); + } + if ( tokens == null ) { + TokenCollector tokenCollector = new TokenCollector( resolvedMessage, InterpolationTermType.EL ); + tokens = tokenCollector.getTokenList(); + + if ( cachingEnabled ) { + tokenizedELMessages.putIfAbsent( resolvedMessage, tokens ); + } } + resolvedMessage = interpolateExpression( + new TokenIterator( tokens ), + context, + locale + ); } - resolvedMessage = interpolateExpression( - new TokenIterator( tokens ), - context, - locale - ); // last but not least we have to take care of escaped literals resolvedMessage = replaceEscapedLiterals( resolvedMessage ); diff --git a/engine/src/test/java/org/hibernate/validator/test/constraints/ConstraintValidatorContextImplTest.java b/engine/src/test/java/org/hibernate/validator/test/constraints/ConstraintValidatorContextImplTest.java index ce0e55c5f8..4691b5a6d0 100644 --- a/engine/src/test/java/org/hibernate/validator/test/constraints/ConstraintValidatorContextImplTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/constraints/ConstraintValidatorContextImplTest.java @@ -162,7 +162,7 @@ private ConstraintValidatorContextImpl createEmptyConstraintValidatorContextImpl PathImpl path = PathImpl.createRootPath(); path.addBeanNode(); - ConstraintValidatorContextImpl context = new ConstraintValidatorContextImpl( null, null, path, null ); + ConstraintValidatorContextImpl context = new ConstraintValidatorContextImpl( null, null, path, null, true ); context.disableDefaultConstraintViolation(); return context; } diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/engine/constraintvalidation/HibernateConstraintValidatorContextTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/engine/constraintvalidation/HibernateConstraintValidatorContextTest.java index 82fa64ec03..bba100c802 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/engine/constraintvalidation/HibernateConstraintValidatorContextTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/engine/constraintvalidation/HibernateConstraintValidatorContextTest.java @@ -31,6 +31,8 @@ import org.hibernate.validator.internal.engine.ConstraintViolationImpl; import org.hibernate.validator.testutil.TestForIssue; import org.testng.Assert; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; import org.testng.collections.Lists; @@ -46,6 +48,16 @@ public class HibernateConstraintValidatorContextTest { private static final List INVALID_KEYWORDS = Lists.newArrayList( "foo", "bar", "baz" ); + @BeforeTest + public void before() { + System.setProperty( "org.hibernate.validator.expressionLanguageEnabled", "true" ); + } + + @AfterTest + public void after() { + System.clearProperty( "org.hibernate.validator.expressionLanguageEnabled" ); + } + @Test @TestForIssue(jiraKey = "HV-701") public void testSettingCustomMessageParameter() { diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/ExpressionLanguageMessageInterpolationTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/ExpressionLanguageMessageInterpolationTest.java index 7d132673c7..b4d074e1e2 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/ExpressionLanguageMessageInterpolationTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/ExpressionLanguageMessageInterpolationTest.java @@ -67,7 +67,8 @@ public void testExpressionLanguageGraphNavigation() { notNullDescriptor, user, null, - Collections.emptyMap() + Collections.emptyMap(), + true ); String expected = "18"; @@ -81,7 +82,8 @@ public void testUnknownPropertyInExpressionLanguageGraphNavigation() { notNullDescriptor, new User(), null, - Collections.emptyMap() + Collections.emptyMap(), + true ); String expected = "${validatedValue.foo}"; @@ -170,7 +172,8 @@ public void testLocaleBasedFormatting() { notNullDescriptor, 42.00000d, null, - Collections.emptyMap() + Collections.emptyMap(), + true ); // german locale @@ -229,7 +232,8 @@ public void testCallingWrongFormatterMethod() { notNullDescriptor, 42.00000d, null, - Collections.emptyMap() + Collections.emptyMap(), + true ); String expected = "${formatter.foo('%1$.2f', validatedValue)}"; @@ -304,7 +308,8 @@ private MessageInterpolatorContext createMessageInterpolatorContext(ConstraintDe descriptor, null, null, - Collections.emptyMap() + Collections.emptyMap(), + true ); } } diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/MessageInterpolatorContextTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/MessageInterpolatorContextTest.java index 6a5dc7b94b..ea3702cda7 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/MessageInterpolatorContextTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/MessageInterpolatorContextTest.java @@ -66,7 +66,8 @@ public void testContextWithRightDescriptorAndValueAndRootBeanClassIsPassedToMess constraintDescriptors.iterator().next(), validatedValue, TestBean.class, - Collections.emptyMap() + Collections.emptyMap(), + true ) ) ) @@ -82,13 +83,13 @@ public void testContextWithRightDescriptorAndValueAndRootBeanClassIsPassedToMess @Test(expectedExceptions = ValidationException.class) public void testUnwrapToImplementationCausesValidationException() { - Context context = new MessageInterpolatorContext( null, null, null, Collections.emptyMap() ); + Context context = new MessageInterpolatorContext( null, null, null, Collections.emptyMap(), true ); context.unwrap( MessageInterpolatorContext.class ); } @Test public void testUnwrapToInterfaceTypesSucceeds() { - Context context = new MessageInterpolatorContext( null, null, null, Collections.emptyMap() ); + Context context = new MessageInterpolatorContext( null, null, null, Collections.emptyMap(), true ); MessageInterpolator.Context asMessageInterpolatorContext = context.unwrap( MessageInterpolator.Context.class ); assertSame( asMessageInterpolatorContext, context ); @@ -109,7 +110,8 @@ public void testGetRootBeanType() { null, null, rootBeanType, - Collections.emptyMap() + Collections.emptyMap(), + true ); assertSame( context.unwrap( HibernateMessageInterpolatorContext.class ).getRootBeanType(), rootBeanType ); diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/ResourceBundleMessageInterpolatorTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/ResourceBundleMessageInterpolatorTest.java index 62ac4b1862..2db32877ac 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/ResourceBundleMessageInterpolatorTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/ResourceBundleMessageInterpolatorTest.java @@ -279,7 +279,8 @@ private MessageInterpolatorContext createMessageInterpolatorContext(ConstraintDe descriptor, null, null, - Collections.emptyMap() + Collections.emptyMap(), + true ); } diff --git a/engine/src/test/java/org/hibernate/validator/testutils/ValidatorUtil.java b/engine/src/test/java/org/hibernate/validator/testutils/ValidatorUtil.java index d6ef65d443..a64c3dd511 100644 --- a/engine/src/test/java/org/hibernate/validator/testutils/ValidatorUtil.java +++ b/engine/src/test/java/org/hibernate/validator/testutils/ValidatorUtil.java @@ -235,6 +235,6 @@ public static T getValidatingProxy(I implementor, Validator exe } public static HibernateConstraintValidatorContext getConstraintValidatorContext() { - return new ConstraintValidatorContextImpl(null, DefaultTimeProvider.getInstance(), null, null); + return new ConstraintValidatorContextImpl(null, DefaultTimeProvider.getInstance(), null, null, true); } } diff --git a/tck-runner/src/test/resources/test.policy b/tck-runner/src/test/resources/test.policy index fedfaede4e..1f737bca49 100644 --- a/tck-runner/src/test/resources/test.policy +++ b/tck-runner/src/test/resources/test.policy @@ -29,7 +29,8 @@ grant codeBase "file:${localRepository}/org/hibernate/hibernate-validator/${proj permission java.lang.RuntimePermission "setContextClassLoader"; permission org.hibernate.validator.HibernateValidatorPermission "accessPrivateMembers"; - + permission java.lang.RuntimePermission "getenv.ORG_HIBERNATE_VALIDATOR_EXPRESSION_LANGUAGE_ENABLED"; + permission java.util.PropertyPermission "org.hibernate.validator.expressionLanguageEnabled", "read"; // JAXB permission java.util.PropertyPermission "mapAnyUriToUri", "read"; }; @@ -42,7 +43,8 @@ grant codeBase "file:${basedir}/../engine/target/hibernate-validator-${project.v permission java.lang.RuntimePermission "setContextClassLoader"; permission org.hibernate.validator.HibernateValidatorPermission "accessPrivateMembers"; - + permission java.lang.RuntimePermission "getenv.ORG_HIBERNATE_VALIDATOR_EXPRESSION_LANGUAGE_ENABLED"; + permission java.util.PropertyPermission "org.hibernate.validator.expressionLanguageEnabled", "read"; // JAXB permission java.util.PropertyPermission "mapAnyUriToUri", "read"; }; From 9d41cafdced59d279f2c5fa8dcd62613bd09a575 Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Thu, 12 Jun 2025 20:58:38 +0200 Subject: [PATCH 120/124] Use older version of maven + https maven repositories + "hide" osgi behind a dedicated build profile and do not use develocity scans --- Jenkinsfile | 102 +----------------- .../xml/JaxpContainedInDeploymentIT.java | 2 +- osgi/integrationtest/pom.xml | 6 ++ pom.xml | 5 +- 4 files changed, 12 insertions(+), 103 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 5daa73b2c8..246e9cb2d3 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -78,7 +78,7 @@ import org.hibernate.jenkins.pipeline.helpers.alternative.AlternativeMultiMap */ @Field final String DEFAULT_JDK_TOOL = 'OracleJDK8 Latest' -@Field final String MAVEN_TOOL = 'Apache Maven 3.9' +@Field final String MAVEN_TOOL = 'Apache Maven 3.2' // Default node pattern, to be used for resource-intensive stages. // Should not include the controller node. @@ -141,7 +141,7 @@ helper.runWithNotification { } maven { defaultTool MAVEN_TOOL - producedArtifactPattern "org/hibernate/validator/*" + producedArtifactPattern "org/hibernate/*" } } @@ -238,9 +238,8 @@ Resulting execution plan: """ dir(helper.configuration.maven.localRepositoryPath) { - stash name:'default-build-result', includes:"org/hibernate/validator/**" + stash name:'default-build-result', includes:"org/hibernate/**" } - stash name:'default-build-jacoco-reports', includes:"**/jacoco.exec" } } } @@ -304,65 +303,6 @@ Resulting execution plan: parallel(parameters) } } - - stage('Sonar analysis') { - def sonarCredentialsId = helper.configuration.file?.sonar?.credentials - if (sonarCredentialsId) { - runBuildOnNode { - withMavenWorkspace { - if (enableDefaultBuild && enableDefaultBuildIT) { - unstash name: "default-build-jacoco-reports" - } - environments.content.jdk.enabled.each { JdkBuildEnvironment buildEnv -> - unstash name: "${buildEnv.tag}-build-jacoco-reports" - } - environments.content.wildflyTck.enabled.each { JdkBuildEnvironment buildEnv -> - unstash name: "${buildEnv.tag}-build-jacoco-reports" - } - - // we don't clean to keep the unstashed jacoco reports: - sh "mvn package -Pskip-checks -Pci-build -DskipTests -Pcoverage-report ${toTestJdkArg(environments.content.jdk.default)}" - - - // WARNING: Make sure credentials are evaluated by sh, not Groovy. - // To that end, escape the '$' when referencing the variables. - // See https://www.jenkins.io/doc/book/pipeline/jenkinsfile/#string-interpolation - withCredentials([usernamePassword( - credentialsId: sonarCredentialsId, - usernameVariable: 'SONARCLOUD_ORGANIZATION', - // https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/scanners/sonarscanner-for-maven/#analyzing - passwordVariable: 'SONAR_TOKEN' - )]) { - // We don't want to use the build cache or build scans for this execution - def miscMavenArgs = '-Dscan=false -Dno-build-cache' - sh """ \ - mvn sonar:sonar \ - ${miscMavenArgs} \ - -Dsonar.organization=\${SONARCLOUD_ORGANIZATION} \ - -Dsonar.host.url=https://sonarcloud.io \ - -Dsonar.projectKey=hibernate_hibernate-validator \ - -Dsonar.projectName="Hibernate Validator" \ - -Dsonar.projectDescription="Hibernate Validator, declare and validate application constraints" \ - ${helper.scmSource.pullRequest ? """ \ - -Dsonar.pullrequest.branch=${helper.scmSource.branch.name} \ - -Dsonar.pullrequest.key=${helper.scmSource.pullRequest.id} \ - -Dsonar.pullrequest.base=${helper.scmSource.pullRequest.target.name} \ - ${helper.scmSource.gitHubRepoId ? """ \ - -Dsonar.pullrequest.provider=GitHub \ - -Dsonar.pullrequest.github.repository=${helper.scmSource.gitHubRepoId} \ - """ : ''} \ - """ : """ \ - -Dsonar.branch.name=${helper.scmSource.branch.name} \ - """} \ - """ - } - } - } - } else { - echo "Skipping Sonar report: no credentials." - } - } - } // End of helper.runWithNotification // Job-specific helpers @@ -571,41 +511,7 @@ void withMavenWorkspace(Map args, Closure body) { } void mvn(String args) { - def develocityMainCredentialsId = helper.configuration.file?.develocity?.credentials?.main - def develocityPrCredentialsId = helper.configuration.file?.develocity?.credentials?.pr - def develocityBaseUrl = helper.configuration.file?.develocity?.url - if ( !helper.scmSource.pullRequest && develocityMainCredentialsId ) { - // Not a PR: we can pass credentials to the build, allowing it to populate the build cache - // and to publish build scans directly. - withEnv(["DEVELOCITY_BASE_URL=${develocityBaseUrl}"]) { - withCredentials([string(credentialsId: develocityMainCredentialsId, - variable: 'DEVELOCITY_ACCESS_KEY')]) { - withGradle { // withDevelocity, actually: https://plugins.jenkins.io/gradle/#plugin-content-capturing-build-scans-from-jenkins-pipeline - sh "mvn $args" - } - } - } - } - else if ( helper.scmSource.pullRequest && develocityPrCredentialsId ) { - // Pull request: we can't pass credentials to the build, since we'd be exposing secrets to e.g. tests. - // We do the build first, then publish the build scan separately. - tryFinally({ - sh "mvn $args" - }, { // Finally - withEnv(["DEVELOCITY_BASE_URL=${develocityBaseUrl}"]) { - withCredentials([string(credentialsId: develocityPrCredentialsId, - variable: 'DEVELOCITY_ACCESS_KEY')]) { - withGradle { // withDevelocity, actually: https://plugins.jenkins.io/gradle/#plugin-content-capturing-build-scans-from-jenkins-pipeline - sh 'mvn develocity:build-scan-publish-previous || true' - } - } - } - }) - } - else { - // No Develocity credentials. - sh "mvn $args" - } + sh "mvn $args" } // try-finally construct that properly suppresses exceptions thrown in the finally block. diff --git a/integration/src/test/java/org/hibernate/validator/integration/wildfly/xml/JaxpContainedInDeploymentIT.java b/integration/src/test/java/org/hibernate/validator/integration/wildfly/xml/JaxpContainedInDeploymentIT.java index deb21cbd6b..d390c3a343 100644 --- a/integration/src/test/java/org/hibernate/validator/integration/wildfly/xml/JaxpContainedInDeploymentIT.java +++ b/integration/src/test/java/org/hibernate/validator/integration/wildfly/xml/JaxpContainedInDeploymentIT.java @@ -60,7 +60,7 @@ public static Archive createTestArchive() { .addClass( Camera.class ) .addAsResource( validationXml(), "META-INF/validation.xml" ) .addAsResource( mappingXml(), "META-INF/my-mapping.xml" ) - .addAsLibrary( Maven.resolver().resolve( "xerces:xercesImpl:2.9.1" ).withoutTransitivity().asSingleFile() ) + .addAsLibrary( Maven.configureResolver().withRemoteRepo( "maven.central.repo", "https://repo1.maven.org/maven2", "default" ).resolve( "xerces:xercesImpl:2.9.1" ).withoutTransitivity().asSingleFile() ) .addAsResource( "log4j.properties" ) .addAsWebInfResource( EmptyAsset.INSTANCE, "beans.xml" ); } diff --git a/osgi/integrationtest/pom.xml b/osgi/integrationtest/pom.xml index 07f683410c..b445737de2 100644 --- a/osgi/integrationtest/pom.xml +++ b/osgi/integrationtest/pom.xml @@ -151,6 +151,12 @@ maven-surefire-plugin false + + + org.ops4j.pax.url.mvn.repositories + https://repo1.maven.org/maven2@id=maven.central.repo + + diff --git a/pom.xml b/pom.xml index 0abf6e258b..a93ed08c99 100644 --- a/pom.xml +++ b/pom.xml @@ -861,10 +861,7 @@ - pre-jdk9 - - 1.8 - + osgi osgi From 2a603198bb1dfa9be05ab0cfe5b08a7b190333ad Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Fri, 13 Jun 2025 09:31:36 +0200 Subject: [PATCH 121/124] [Jenkins tag job] README.md updated by tag build 5.3.6.SP1 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 83fbc1145f..416293a55f 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ Logging will delegate any log requests to that provider. org.hibernate hibernate-validator - 5.3.6.Final + 5.3.6.SP1 You also need an API and implementation of the Unified Expression Language. These dependencies must be explicitly added in an SE environment. From 48732cf06d839c45ba2a55491e17bad5bd444f95 Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Fri, 13 Jun 2025 09:32:11 +0200 Subject: [PATCH 122/124] [Jenkins tag job] changelog.txt updated by tag build 5.3.6.SP1 --- changelog.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/changelog.txt b/changelog.txt index 957c43b00e..d5e14104cb 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,6 +1,12 @@ Hibernate Validator Changelog ============================= +5.3.6.SP1 (2025-06-13) +------------------------- + +** Improvement + * HV-1816 Disable Expression Language by default for custom constraint violations (Partial backport of internal changes only) + 5.3.6.Final (19-10-2017) ------------------------- From 14dbd75b02f409458f447b90458fd8dbc07b8dac Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Fri, 13 Jun 2025 09:33:46 +0200 Subject: [PATCH 123/124] [Jenkins tag job] Preparing tag build 5.3.6.SP1 --- annotation-processor/pom.xml | 2 +- build-config/pom.xml | 2 +- cdi/pom.xml | 2 +- distribution/pom.xml | 2 +- documentation/pom.xml | 2 +- engine-jdk8-tests/pom.xml | 2 +- engine/pom.xml | 2 +- integration/pom.xml | 2 +- osgi/integrationtest/pom.xml | 2 +- osgi/karaf-features/pom.xml | 2 +- osgi/pom.xml | 2 +- performance/pom.xml | 2 +- pom.xml | 2 +- tck-runner/pom.xml | 2 +- test-utils/pom.xml | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/annotation-processor/pom.xml b/annotation-processor/pom.xml index 4acc0cffbd..2e72ba69ce 100644 --- a/annotation-processor/pom.xml +++ b/annotation-processor/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6.SP1-SNAPSHOT + 5.3.6.SP1 ../pom.xml diff --git a/build-config/pom.xml b/build-config/pom.xml index 9218a02442..15d0706579 100644 --- a/build-config/pom.xml +++ b/build-config/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6.SP1-SNAPSHOT + 5.3.6.SP1 ../pom.xml diff --git a/cdi/pom.xml b/cdi/pom.xml index a0ca1770e0..26e98380ab 100644 --- a/cdi/pom.xml +++ b/cdi/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6.SP1-SNAPSHOT + 5.3.6.SP1 ../pom.xml diff --git a/distribution/pom.xml b/distribution/pom.xml index b086b60c99..e717b8f5df 100644 --- a/distribution/pom.xml +++ b/distribution/pom.xml @@ -10,7 +10,7 @@ hibernate-validator-parent org.hibernate - 5.3.6.SP1-SNAPSHOT + 5.3.6.SP1 ../pom.xml diff --git a/documentation/pom.xml b/documentation/pom.xml index ff4d806451..11ee12fe52 100644 --- a/documentation/pom.xml +++ b/documentation/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6.SP1-SNAPSHOT + 5.3.6.SP1 ../pom.xml diff --git a/engine-jdk8-tests/pom.xml b/engine-jdk8-tests/pom.xml index 3ed0ba522f..ddbd5fce06 100644 --- a/engine-jdk8-tests/pom.xml +++ b/engine-jdk8-tests/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.6.SP1-SNAPSHOT + 5.3.6.SP1 hibernate-validator-engine-jdk8-tests diff --git a/engine/pom.xml b/engine/pom.xml index 637d1e248c..b4f744fe91 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6.SP1-SNAPSHOT + 5.3.6.SP1 ../pom.xml diff --git a/integration/pom.xml b/integration/pom.xml index 11d5e22f8f..5d6fce0617 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6.SP1-SNAPSHOT + 5.3.6.SP1 ../pom.xml diff --git a/osgi/integrationtest/pom.xml b/osgi/integrationtest/pom.xml index b445737de2..4ae836c1a6 100644 --- a/osgi/integrationtest/pom.xml +++ b/osgi/integrationtest/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-osgi org.hibernate - 5.3.6.SP1-SNAPSHOT + 5.3.6.SP1 ../pom.xml diff --git a/osgi/karaf-features/pom.xml b/osgi/karaf-features/pom.xml index 7c8a8274cf..df735b8bff 100644 --- a/osgi/karaf-features/pom.xml +++ b/osgi/karaf-features/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-osgi org.hibernate - 5.3.6.SP1-SNAPSHOT + 5.3.6.SP1 ../pom.xml diff --git a/osgi/pom.xml b/osgi/pom.xml index 48403b8406..3293ce9781 100644 --- a/osgi/pom.xml +++ b/osgi/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6.SP1-SNAPSHOT + 5.3.6.SP1 ../pom.xml diff --git a/performance/pom.xml b/performance/pom.xml index 43af392d04..feee31d398 100644 --- a/performance/pom.xml +++ b/performance/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6.SP1-SNAPSHOT + 5.3.6.SP1 ../pom.xml diff --git a/pom.xml b/pom.xml index a93ed08c99..0f74359fb2 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.6.SP1-SNAPSHOT + 5.3.6.SP1 pom Hibernate Validator Aggregator diff --git a/tck-runner/pom.xml b/tck-runner/pom.xml index 6e22cc472a..b24d167664 100644 --- a/tck-runner/pom.xml +++ b/tck-runner/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6.SP1-SNAPSHOT + 5.3.6.SP1 ../pom.xml diff --git a/test-utils/pom.xml b/test-utils/pom.xml index 43d83a1b76..8fd78882e1 100644 --- a/test-utils/pom.xml +++ b/test-utils/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.6.SP1-SNAPSHOT + 5.3.6.SP1 hibernate-validator-test-utils From f9e581fcdf391512effadc612468e66053b41b5f Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Fri, 13 Jun 2025 09:34:39 +0200 Subject: [PATCH 124/124] [Jenkins tag job] Preparing for the next iteration 5.3.6.SP2-SNAPSHOT --- annotation-processor/pom.xml | 2 +- build-config/pom.xml | 2 +- cdi/pom.xml | 2 +- distribution/pom.xml | 2 +- documentation/pom.xml | 2 +- engine-jdk8-tests/pom.xml | 2 +- engine/pom.xml | 2 +- integration/pom.xml | 2 +- osgi/integrationtest/pom.xml | 2 +- osgi/karaf-features/pom.xml | 2 +- osgi/pom.xml | 2 +- performance/pom.xml | 2 +- pom.xml | 2 +- tck-runner/pom.xml | 2 +- test-utils/pom.xml | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/annotation-processor/pom.xml b/annotation-processor/pom.xml index 2e72ba69ce..f9babae1fd 100644 --- a/annotation-processor/pom.xml +++ b/annotation-processor/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6.SP1 + 5.3.6.SP2-SNAPSHOT ../pom.xml diff --git a/build-config/pom.xml b/build-config/pom.xml index 15d0706579..6ea722bdd9 100644 --- a/build-config/pom.xml +++ b/build-config/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6.SP1 + 5.3.6.SP2-SNAPSHOT ../pom.xml diff --git a/cdi/pom.xml b/cdi/pom.xml index 26e98380ab..f9120fbfd0 100644 --- a/cdi/pom.xml +++ b/cdi/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6.SP1 + 5.3.6.SP2-SNAPSHOT ../pom.xml diff --git a/distribution/pom.xml b/distribution/pom.xml index e717b8f5df..1b143d9762 100644 --- a/distribution/pom.xml +++ b/distribution/pom.xml @@ -10,7 +10,7 @@ hibernate-validator-parent org.hibernate - 5.3.6.SP1 + 5.3.6.SP2-SNAPSHOT ../pom.xml diff --git a/documentation/pom.xml b/documentation/pom.xml index 11ee12fe52..1dd3f97ec2 100644 --- a/documentation/pom.xml +++ b/documentation/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6.SP1 + 5.3.6.SP2-SNAPSHOT ../pom.xml diff --git a/engine-jdk8-tests/pom.xml b/engine-jdk8-tests/pom.xml index ddbd5fce06..3d8efd1119 100644 --- a/engine-jdk8-tests/pom.xml +++ b/engine-jdk8-tests/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.6.SP1 + 5.3.6.SP2-SNAPSHOT hibernate-validator-engine-jdk8-tests diff --git a/engine/pom.xml b/engine/pom.xml index b4f744fe91..0d64163d3c 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6.SP1 + 5.3.6.SP2-SNAPSHOT ../pom.xml diff --git a/integration/pom.xml b/integration/pom.xml index 5d6fce0617..6415b4483b 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6.SP1 + 5.3.6.SP2-SNAPSHOT ../pom.xml diff --git a/osgi/integrationtest/pom.xml b/osgi/integrationtest/pom.xml index 4ae836c1a6..cb41a08f47 100644 --- a/osgi/integrationtest/pom.xml +++ b/osgi/integrationtest/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-osgi org.hibernate - 5.3.6.SP1 + 5.3.6.SP2-SNAPSHOT ../pom.xml diff --git a/osgi/karaf-features/pom.xml b/osgi/karaf-features/pom.xml index df735b8bff..4c3ff2c817 100644 --- a/osgi/karaf-features/pom.xml +++ b/osgi/karaf-features/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-osgi org.hibernate - 5.3.6.SP1 + 5.3.6.SP2-SNAPSHOT ../pom.xml diff --git a/osgi/pom.xml b/osgi/pom.xml index 3293ce9781..770967acc6 100644 --- a/osgi/pom.xml +++ b/osgi/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6.SP1 + 5.3.6.SP2-SNAPSHOT ../pom.xml diff --git a/performance/pom.xml b/performance/pom.xml index feee31d398..95057f1cda 100644 --- a/performance/pom.xml +++ b/performance/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6.SP1 + 5.3.6.SP2-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index 0f74359fb2..4190775b99 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.6.SP1 + 5.3.6.SP2-SNAPSHOT pom Hibernate Validator Aggregator diff --git a/tck-runner/pom.xml b/tck-runner/pom.xml index b24d167664..fde1115b0e 100644 --- a/tck-runner/pom.xml +++ b/tck-runner/pom.xml @@ -11,7 +11,7 @@ hibernate-validator-parent org.hibernate - 5.3.6.SP1 + 5.3.6.SP2-SNAPSHOT ../pom.xml diff --git a/test-utils/pom.xml b/test-utils/pom.xml index 8fd78882e1..faa9bca5c8 100644 --- a/test-utils/pom.xml +++ b/test-utils/pom.xml @@ -10,7 +10,7 @@ org.hibernate hibernate-validator-parent - 5.3.6.SP1 + 5.3.6.SP2-SNAPSHOT hibernate-validator-test-utils