StackOverflowError with Hibernate Validator 6.0.13.Final

Description

when the process working for two days,StackOverflowError always happen,the stacktrace is below:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 java.lang.StackOverflowError at java.util.Collections$UnmodifiableCollection.isEmpty(Collections.java:1031) at java.util.Collections$UnmodifiableCollection.isEmpty(Collections.java:1031) ...... at java.util.Collections$UnmodifiableCollection.isEmpty(Collections.java:1031) at java.util.Collections$UnmodifiableCollection.isEmpty(Collections.java:1031) at java.util.Collections$UnmodifiableCollection.isEmpty(Collections.java:1031) at java.util.Collections$UnmodifiableCollection.isEmpty(Collections.java:1031) at java.util.Collections$UnmodifiableCollection.isEmpty(Collections.java:1031) at java.util.Collections$UnmodifiableCollection.isEmpty(Collections.java:1031) at org.hibernate.validator.internal.engine.valueextraction.ValueExtractorResolver.getRuntimeCompliantValueExtractors(ValueExtractorResolver.java:316) at org.hibernate.validator.internal.engine.valueextraction.ValueExtractorResolver.getValueExtractorCandidatesForContainerDetectionOfGlobalCascadedValidation(ValueExtractorResolver.java:177) at org.hibernate.validator.internal.metadata.aggregated.CascadingMetaDataBuilder.build(CascadingMetaDataBuilder.java:227) at org.hibernate.validator.internal.metadata.aggregated.FieldCascadable$Builder.build(FieldCascadable.java:83) at org.hibernate.validator.internal.metadata.aggregated.FieldCascadable$Builder.build(FieldCascadable.java:64) at org.hibernate.validator.internal.metadata.aggregated.PropertyMetaData$Builder.lambda$build$1(PropertyMetaData.java:347) at org.hibernate.validator.internal.metadata.aggregated.PropertyMetaData$Builder$$Lambda$62/1651906449.apply(Unknown Source) at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) at java.util.HashMap$ValueSpliterator.forEachRemaining(HashMap.java:1625) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) at org.hibernate.validator.internal.metadata.aggregated.PropertyMetaData$Builder.build(PropertyMetaData.java:348) at org.hibernate.validator.internal.metadata.aggregated.PropertyMetaData$Builder.build(PropertyMetaData.java:151) at org.hibernate.validator.internal.metadata.aggregated.BeanMetaDataImpl$BuilderDelegate.build(BeanMetaDataImpl.java:784) at org.hibernate.validator.internal.metadata.aggregated.BeanMetaDataImpl$BeanMetaDataBuilder.build(BeanMetaDataImpl.java:648) at org.hibernate.validator.internal.metadata.BeanMetaDataManager.createBeanMetaData(BeanMetaDataManager.java:192) at org.hibernate.validator.internal.metadata.BeanMetaDataManager.lambda$getBeanMetaData$0(BeanMetaDataManager.java:160) at org.hibernate.validator.internal.metadata.BeanMetaDataManager$$Lambda$53/253243426.apply(Unknown Source) at java.util.concurrent.ConcurrentMap.computeIfAbsent(ConcurrentMap.java:324) at org.hibernate.validator.internal.metadata.BeanMetaDataManager.getBeanMetaData(BeanMetaDataManager.java:159) at org.hibernate.validator.internal.engine.ValidationContext$ValidationContextBuilder.forValidate(ValidationContext.java:566) at org.hibernate.validator.internal.engine.ValidatorImpl.validate(ValidatorImpl.java:155) at com.test.ValidateParameters.validateObject(ValidateParameters.java:31)

The environment is :x86_64 GNU/Linux JRE: 1.8.0_181 hibernate-validator:6.0.13Final
And our code is easy,just like this,first get validator in a static block,and then validate paramter for every request param:

1 2 3 4 5 6 7 //get validator Validator validator = Validation.byDefaultProvider() .providerResolver(new OsgiValidationProviderResolver()) .configure().messageInterpolator(resouce) .buildValidatorFactory().getValidator(); //validate parameter,this parameter is an Object,(we think it contains map attribute may have the problem). Set<ConstraintViolation> validateResultSets = validator.validate(parameter);

Our team have view the code,we doubt the following code(ValueExtractorResolver.java, getRuntimeCompliantValueExtractors) may has some problem in Multithreading,why it always happens for a long time?
When in thread one,the attribute "valueExtractorDescriptors" is not empty ,and it's type is java.util.map,then it will change to ImmutableSet,then a second thread run "valueExtractorDescriptors.isEmpty()",it will goes to the UnmodifiableCollection.isEmpty,this will recursion,at last it will throw SO Exception.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 private Set<ValueExtractorDescriptor> getRuntimeCompliantValueExtractors(Class<?> runtimeType, Set<ValueExtractorDescriptor> potentialValueExtractorDescriptors) { if ( nonContainerTypes.contains( runtimeType ) ) { return Collections.emptySet(); } Set<ValueExtractorDescriptor> valueExtractorDescriptors = possibleValueExtractorsByRuntimeType.get( runtimeType ); if ( valueExtractorDescriptors == null ) { //otherwise we just look for maximally specific extractors for the runtime type Set<ValueExtractorDescriptor> possibleValueExtractors = potentialValueExtractorDescriptors .stream() .filter( e -> TypeHelper.isAssignable( e.getContainerType(), runtimeType ) ) .collect( Collectors.toSet() ); valueExtractorDescriptors = getMaximallySpecificValueExtractors( possibleValueExtractors ); } if ( valueExtractorDescriptors.isEmpty() ) { nonContainerTypes.put( runtimeType, NON_CONTAINER_VALUE ); } else { Set<ValueExtractorDescriptor> extractorDescriptorsToCache = CollectionHelper.toImmutableSet( valueExtractorDescriptors ); possibleValueExtractorsByRuntimeType.put( runtimeType, extractorDescriptorsToCache ); return extractorDescriptorsToCache; } return valueExtractorDescriptors; }

Environment

The environment is :x86_64 GNU/Linux JRE: 1.8.0_181 hibernate-validator:6.0.13Final

Status

Assignee

Guillaume Smet

Reporter

tp123

Labels

Worked in

None

Feedback Requested

2019/01/03

Feedback Requested By

None

backPortable

None

Community Help Wanted

None

Suitable for new contributors

None

Requires Release Note

None

backportDecision

None

backportReEvaluate

None

Components

Fix versions

Affects versions

6.0.13.Final

Priority

Blocker
Configure