[hibernate-issues] [Hibernate-JIRA] Issue Comment Edited: (HV-495) Many locks on AnnotatedElements

Loïc DIAS DA SILVA (JIRA) noreply at atlassian.com
Wed Jun 15 10:35:24 EDT 2011


    [ http://opensource.atlassian.com/projects/hibernate/browse/HV-495?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=42602#action_42602 ] 

Loïc DIAS DA SILVA edited comment on HV-495 at 6/15/11 9:35 AM:
----------------------------------------------------------------

No, i have not kept the JRA traces sorry.. ;(
You can find below an example (incomplete) of some of our annotations :

        @ValidatedMethodCall
	public Response xxxxxxx (
			@User(message = ID_ERROR) @PathParam("xxx") int otherMemberId,
			@Page @Range(min = MIN_PAGE, max = MAX_PAGE_CONTACTS, message = PAGE_NUMBER_ERROR_CONTACTS) @DefaultValue(DEFAULT_PAGE) @QueryParam(PAGE_PARAM) Integer pageNumber,
			@Limit @Range(min = MIN_LIMIT, max = MAX_LIMIT, message = LIMIT_SIZE_ERROR) @DefaultValue(DEFAULT_LIMIT) @QueryParam(LIMIT_PARAM) Integer limit,
			@DefaultValue("false") @QueryParam("xxxxxxxx") Boolean xxxxxxxxx,
			@DefaultValue(GraphUtils.NONE_DETAIL_LEVEL) @QueryParam(DETAIL_PARAM) DetailLevel xxxxxxx)

I used a tomcat instance with 300 threads and the locks begin to occur when i launch the third injector (each JMeter injector configured with 500 threads).

I used previously Apache bval with exactly the same issue and really closed trace, i have kept in some mails the trace, if it can be useful :

{noformat}
>    -- Blocked trying to get lock: java/lang/Class at 0x7fb9f047f820[unlocked]
>             at jrockit/vm/Threads.waitForUnblockSignal()V(Native Method)
>             at jrockit/vm/Locks.fatLockBlockOrSpin(Locks.java:1675)[optimized]
>             at jrockit/vm/Locks.lockFat(Locks.java:1776)[optimized]
>             at jrockit/vm/Locks.monitorEnterSecondStageHard(Locks.java:1312)[optimized]
>             at jrockit/vm/Locks.monitorEnterSecondStage(Locks.java:1259)[optimized]
>             at sun/reflect/annotation/AnnotationType.getInstance(AnnotationType.java:63)[inlined]
>             at sun/reflect/annotation/AnnotationParser.parseAnnotation(AnnotationParser.java:202)[inlined]
>             at sun/reflect/annotation/AnnotationParser.parseAnnotations2(AnnotationParser.java:69)[optimized]
>             at sun/reflect/annotation/AnnotationParser.parseAnnotations(AnnotationParser.java:52)[inlined]
>             at java/lang/reflect/Field.declaredAnnotations(Field.java:1016)[inlined]
>             at java/lang/reflect/Field.getDeclaredAnnotations(Field.java:1009)[optimized]
>             ^-- Holding lock: java/lang/reflect/Field at 0x7fb95b173cc8[thin lock]
>             at org/apache/bval/jsr303/Jsr303MetaBeanFactory.processAnnotations(Jsr303MetaBeanFactory.java:282)[inlined]
>             at org/apache/bval/jsr303/Jsr303MetaBeanFactory.processClass(Jsr303MetaBeanFactory.java:138)[inlined]
>             at org/apache/bval/jsr303/Jsr303MetaBeanFactory.buildMetaBean(Jsr303MetaBeanFactory.java:102)[optimized]
>             at org/apache/bval/MetaBeanBuilder.buildForClass(MetaBeanBuilder.java:128)[inlined]
>             at org/apache/bval/MetaBeanManager.findForClass(MetaBeanManager.java:102)[optimized]
>             at org/apache/bval/jsr303/ClassValidator.getConstraintsForClass(ClassValidator.java:342)[inlined]
>             at org/apache/bval/jsr303/extensions/MethodValidatorImpl.validateParameters(MethodValidatorImpl.java:98)[optimized]
>             at xxxxxx.validatedMethodCallBefore(xxxxxxx.java:xxxxx)[optimized]
>             at *api endpoint method* (xxxxxxx.java:xxxx)
{noformat}

I instanciate the validator in this way, using AspectJ :

{code:title=MethodValidationAspect.java|borderStyle=solid}
import java.util.Arrays;
import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.ValidatorFactory;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.hibernate.validator.method.MethodValidator;

@Aspect
public class MethodValidationAspect {

	static private ValidatorFactory factory;

	// ==========================================================================

	static {
		factory = Validation.buildDefaultValidatorFactory();
	}

	// ==========================================================================

	static private MethodValidator getMethodValidator() {
		return factory.getValidator().unwrap(MethodValidator.class);
	}

	@Pointcut("execution(@xxxxxx.ValidatedMethodCall * *(..))")
	public void validatedMethodCall(final JoinPoint _thisJoinPoint) {
	}

	// ==========================================================================

	/**
	 * @param _thisJoinPoint
	 */
	@Before("validatedMethodCall(JoinPoint)")
	public void validatedMethodCallBefore(final JoinPoint _thisJoinPoint) {

		final MethodSignature methodSignature = (MethodSignature) _thisJoinPoint.getSignature();

		final Set<? extends ConstraintViolation<?>> validationErrors = MethodValidationAspect.getMethodValidator()
				.validateAllParameters(_thisJoinPoint.getThis(), methodSignature.getMethod(), _thisJoinPoint.getArgs());

		if (!validationErrors.isEmpty()) {
			throw buildValidationException(validationErrors);
		}

	}

	// ==========================================================================

	/**
	 * @param validationErrors The errors detected in a method/constructor call.
	 * @return A RuntimeException with information about the detected validation errors.
	 */

	private IllegalArgumentException buildValidationException(
			final Set<? extends ConstraintViolation<?>> _validationErrors) {
		final StringBuilder sb = new StringBuilder();
		for (ConstraintViolation<?> cv : _validationErrors) {
			sb.append(cv.getMessage() + "\n");
		}
		return new IllegalArgumentException(sb.toString());
	}

}
{code}

Hope it can helps..
Regards.
++

      was (Author: mglcel):
    No, i have not kept the JRA traces sorry.. ;(
You can find below an example (incomplete) of some of our annotations :

        @ValidatedMethodCall
	public Response xxxxxxx (
			@User(message = ID_ERROR) @PathParam("xxx") int otherMemberId,
			@Page @Range(min = MIN_PAGE, max = MAX_PAGE_CONTACTS, message = PAGE_NUMBER_ERROR_CONTACTS) @DefaultValue(DEFAULT_PAGE) @QueryParam(PAGE_PARAM) Integer pageNumber,
			@Limit @Range(min = MIN_LIMIT, max = MAX_LIMIT, message = LIMIT_SIZE_ERROR) @DefaultValue(DEFAULT_LIMIT) @QueryParam(LIMIT_PARAM) Integer limit,
			@DefaultValue("false") @QueryParam("xxxxxxxx") Boolean xxxxxxxxx,
			@DefaultValue(GraphUtils.NONE_DETAIL_LEVEL) @QueryParam(DETAIL_PARAM) DetailLevel xxxxxxx)

I used a tomcat instance with 300 threads and the locks begin to occur when i launch the third injector (each JMeter injector configured with 500 threads).

I used previously Apache bval with exactly the same issue and really closed trace, i have kept in some mails the trace, if it can be useful :

>    -- Blocked trying to get lock: java/lang/Class at 0x7fb9f047f820[unlocked]
>             at jrockit/vm/Threads.waitForUnblockSignal()V(Native Method)
>             at jrockit/vm/Locks.fatLockBlockOrSpin(Locks.java:1675)[optimized]
>             at jrockit/vm/Locks.lockFat(Locks.java:1776)[optimized]
>             at jrockit/vm/Locks.monitorEnterSecondStageHard(Locks.java:1312)[optimized]
>             at jrockit/vm/Locks.monitorEnterSecondStage(Locks.java:1259)[optimized]
>             at sun/reflect/annotation/AnnotationType.getInstance(AnnotationType.java:63)[inlined]
>             at sun/reflect/annotation/AnnotationParser.parseAnnotation(AnnotationParser.java:202)[inlined]
>             at sun/reflect/annotation/AnnotationParser.parseAnnotations2(AnnotationParser.java:69)[optimized]
>             at sun/reflect/annotation/AnnotationParser.parseAnnotations(AnnotationParser.java:52)[inlined]
>             at java/lang/reflect/Field.declaredAnnotations(Field.java:1016)[inlined]
>             at java/lang/reflect/Field.getDeclaredAnnotations(Field.java:1009)[optimized]
>             ^-- Holding lock: java/lang/reflect/Field at 0x7fb95b173cc8[thin lock]
>             at org/apache/bval/jsr303/Jsr303MetaBeanFactory.processAnnotations(Jsr303MetaBeanFactory.java:282)[inlined]
>             at org/apache/bval/jsr303/Jsr303MetaBeanFactory.processClass(Jsr303MetaBeanFactory.java:138)[inlined]
>             at org/apache/bval/jsr303/Jsr303MetaBeanFactory.buildMetaBean(Jsr303MetaBeanFactory.java:102)[optimized]
>             at org/apache/bval/MetaBeanBuilder.buildForClass(MetaBeanBuilder.java:128)[inlined]
>             at org/apache/bval/MetaBeanManager.findForClass(MetaBeanManager.java:102)[optimized]
>             at org/apache/bval/jsr303/ClassValidator.getConstraintsForClass(ClassValidator.java:342)[inlined]
>             at org/apache/bval/jsr303/extensions/MethodValidatorImpl.validateParameters(MethodValidatorImpl.java:98)[optimized]
>             at xxxxxx.validatedMethodCallBefore(xxxxxxx.java:xxxxx)[optimized]
>             at *api endpoint method* (xxxxxxx.java:xxxx)

I instanciate the validator in this way, using AspectJ :

import java.util.Arrays;
import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.ValidatorFactory;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.hibernate.validator.method.MethodValidator;

@Aspect
public class MethodValidationAspect {

	static private ValidatorFactory factory;

	// ==========================================================================

	static {
		factory = Validation.buildDefaultValidatorFactory();
	}

	// ==========================================================================

	static private MethodValidator getMethodValidator() {
		return factory.getValidator().unwrap(MethodValidator.class);
	}

	@Pointcut("execution(@xxxxxx.ValidatedMethodCall * *(..))")
	public void validatedMethodCall(final JoinPoint _thisJoinPoint) {
	}

	// ==========================================================================

	/**
	 * @param _thisJoinPoint
	 */
	@Before("validatedMethodCall(JoinPoint)")
	public void validatedMethodCallBefore(final JoinPoint _thisJoinPoint) {

		final MethodSignature methodSignature = (MethodSignature) _thisJoinPoint.getSignature();

		final Set<? extends ConstraintViolation<?>> validationErrors = MethodValidationAspect.getMethodValidator()
				.validateAllParameters(_thisJoinPoint.getThis(), methodSignature.getMethod(), _thisJoinPoint.getArgs());

		if (!validationErrors.isEmpty()) {
			throw buildValidationException(validationErrors);
		}

	}

	// ==========================================================================

	/**
	 * @param validationErrors The errors detected in a method/constructor call.
	 * @return A RuntimeException with information about the detected validation errors.
	 */

	private IllegalArgumentException buildValidationException(
			final Set<? extends ConstraintViolation<?>> _validationErrors) {
		final StringBuilder sb = new StringBuilder();
		for (ConstraintViolation<?> cv : _validationErrors) {
			sb.append(cv.getMessage() + "\n");
		}
		return new IllegalArgumentException(sb.toString());
	}

}


Hope it can helps..
Regards.
++
  
> Many locks on AnnotatedElements
> -------------------------------
>
>                 Key: HV-495
>                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HV-495
>             Project: Hibernate Validator
>          Issue Type: Patch
>          Components: validators
>    Affects Versions: 4.2.0.CR1
>         Environment: GNU/Linux, JVM 6.0, Hibernate Validator 4.2.0.CR1
>            Reporter: Loïc DIAS DA SILVA
>             Fix For: 4.x
>
>         Attachments: jmeter-graph.docx, patch-ldds.patch
>
>
> Hi all, we use Hibernate Validator 4.2.0-CR1 (previously Apache BVAL) for one of our API projects.
> All is working fine for our needs except one big issue recently discovered during JMeter tests.
> Several injectors make many requests from some Amazon cloud servers to our API and starting from a number of requests the response time begins to increase eavily, making a big jump from about 100ms in average to more than 5s.
> After investigating we have seen many locks in some AnnotatedElement methods (mainly getAnnotation).
> I've then made a little patch on hibernate in order to cache this kind of requests as i've not found any other cleaver/yet implemented way..
> Since this patch all is working very well for us..
> Regards.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

       



More information about the hibernate-issues mailing list