We're updating the issue view to help you get more done. 

Significant contention in Hibernate validation TypeResolver usage

Description

In a production application, we encountered an issue of significant lock contention in Hibernate Validator 5.4.2 (included in the latest DropWizard framework). The stack traces of affected threads looked like:

1 2 3 4 5 6 7 8 9 10 11 - waiting to lock <0x77f3c3ee> (a com.fasterxml.classmate.util.ResolvedTypeCache) owned by dw-582 - POST /quotes/v1/searchQuotes id=582 at com.fasterxml.classmate.util.ResolvedTypeCache.find(ResolvedTypeCache.java:50) at com.fasterxml.classmate.TypeResolver._fromClass(TypeResolver.java:351) at com.fasterxml.classmate.TypeResolver.resolve(TypeResolver.java:112) at org.hibernate.validator.internal.engine.ValidationContext.getValidatedValueUnwrapper(ValidationContext.java:394) at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.getInitializedConstraintValidator(ConstraintTree.java:160) ... at org.hibernate.validator.internal.engine.ValidatorImpl.validateReturnValue(ValidatorImpl.java:320) at org.hibernate.validator.internal.engine.ValidatorImpl.validateReturnValue(ValidatorImpl.java:280) at io.dropwizard.jersey.validation.DropwizardConfiguredValidator.validateResult(DropwizardConfiguredValidator.java:103)

When an application received an initial burst of traffic, a significant number of threads were locked up with the same stack trace (in one instance, 962 threads) until the application became unavailable.

The classmate library had a similar report of this issue in GitHub (https://github.com/FasterXML/java-classmate/issues/40). As part of this issue, the maintainer of classmate introduced a new ConcurrentTypeCache TypeResolver in 1.4.0 which switches the underlying cache from using a synchronized LinkedHashMap to a ConcurrentHashMap.

Unfortunately, there doesn't appear to be any way to modify the Hibernate TypeResolver (https://github.com/hibernate/hibernate-validator/blob/45e7fdf275989e5c022d4a6bd3a8ad6a8fb88dfe/engine/src/main/java/org/hibernate/validator/internal/util/TypeResolutionHelper.java#L21) when instantiating a Hibernate validator. Would it be possible to consider one of the following improvements to the Hibernate Validator API to fix this contention?

Either:

  • Upgrade to classmate 1.4.0 and switch from the default TypeResolver (which uses LinkedHashMap) to an appropriately sized ConcurrentTypeCache TypeResolver. Note: The ConcurrentTypeCache is not an LRU cache so there is an expensive clearing of the cache when it reaches capacity - depending on the application, it might be necessary to tune this size in order to avoid rebuilding the cache.

Or:

  • Provide a means via an API for a consumer of Hibernate Validator to override the default TypeResolver or TypeResolutionHelper to tune this cache as needed.

Thanks!

Environment

None

Status

Assignee

Unassigned

Reporter

PhilipW

Labels

None

Worked in

None

Feedback Requested

None

Feedback Requested By

None

backPortable

None

Community Help Wanted

None

Suitable for new contributors

None

Requires Release Note

None

Pull Request

None

backportDecision

None

backportReEvaluate

None

Components

Affects versions

5.4.2.Final

Priority

Major