Class.getAnnotations() returns a Proxy object wrapping the annotation class; these objects are cached. ConstraintDescriptorImpl uses the equals() method of the annotation, but the proxy object does not implement a equals method, so Object.equals() is used.
Under high load or low memory, the cached proxy objects get cleared and newly initialized, which breaks the equals-check and the validation gets skipped.
Annotation.annotationType() should be checked.
This bug may be related to HV-930 Closed
I'm still working on an unittest to show this behavior. At the moment we can reproduce it by hammering our Struts2 application with JMeter.