bval-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Liam Miller-Cushon (JIRA)" <>
Subject [jira] [Created] (BVAL-129) JDK8 - Annotations on synthetic bridge methods break bval
Date Sun, 04 May 2014 19:06:14 GMT
Liam Miller-Cushon created BVAL-129:

             Summary: JDK8 - Annotations on synthetic bridge methods break bval
                 Key: BVAL-129
             Project: BVal
          Issue Type: Bug
          Components: jsr303
    Affects Versions: 0.5, 1.1.0-alpha
         Environment: JDK8
            Reporter: Liam Miller-Cushon

As of jdk8, the java compiler now copies annotations onto synthetic bridge methods. See
for more information about the change. When javac creates synthetic copies of methods the
method signatures are erased. This violates assumptions made by bval.

Consider the following example:

@Constraint(validatedBy = { MyValidator.class })
public @interface SomeAnnotation { … }

public static class MyValidator implements ConstraintValidator<SomeAnnotation, String>
{ … }

public interface Id<T> {
  T getId();

public static class ObjectToValidate implements Id<String> {
  public String getId() { return null; }

The compiler creates a bridge method for ObjectToValidate.getId with the erased return type
of Object. Prior to jdk8 this method had no annotations and was ignored by bval, but with
the change in jdk8 the validation fails:

$ export JAVA_HOME=/Library/Java/JavaVirtualMachinesLibrary/Java/JavaVirtualMachines/jdk1.7.0_45.jdk/Contents/Home/
&& mvn clean package exec:java -Dexec.mainClass="Test"

$ export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/ &&
mvn clean package exec:java -Dexec.mainClass="Test"
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(
	at java.lang.reflect.Method.invoke(
	at org.codehaus.mojo.exec.ExecJavaMojo$
Caused by: javax.validation.UnexpectedTypeException: No validator could be found for type
java.lang.Object. See: @SomeAnnotation at public java.lang.Object Test$ObjectToValidate.getId()
	at org.apache.bval.jsr303.AnnotationProcessor.checkOneType(
	at org.apache.bval.jsr303.AnnotationProcessor.getConstraintValidator(
	at org.apache.bval.jsr303.AnnotationProcessor.applyConstraint(
	at org.apache.bval.jsr303.AnnotationProcessor.processAnnotation(
	at org.apache.bval.jsr303.AnnotationProcessor.processAnnotations(
	at org.apache.bval.jsr303.Jsr303MetaBeanFactory.processClass(
	at org.apache.bval.jsr303.Jsr303MetaBeanFactory.buildMetaBean(
	at org.apache.bval.MetaBeanBuilder.buildForClass(
	at org.apache.bval.MetaBeanManager.findForClass(
	at org.apache.bval.jsr303.ClassValidator.validate(
	at Test.main(
	... 6 more

Proposed solution:

To preserve the behaviour bval had pre-jdk8, it can simply ignore the synthetic bridge methods.
The following patch would accomplish this:

--- src/main/java/org/apache/bval/jsr303/
+++ src/main/java/org/apache/bval/jsr303/
@@ -139,6 +139,9 @@
         final Method[] methods = doPrivileged(SecureActions.getDeclaredMethods(beanClass));
         for (Method method : methods) {
+            if (method.isSynthetic() || method.isBridge()) {
+                continue;
+            }
             String propName = null;
             if (method.getParameterTypes().length == 0) {
                 propName = MethodAccess.getPropertyName(method);

This message was sent by Atlassian JIRA

View raw message