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
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.