[ 
https://issues.apache.org/jira/browse/BVAL-129?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13989089#comment-13989089
 ] 

Liam Miller-Cushon edited comment on BVAL-129 at 5/4/14 7:09 PM:
-----------------------------------------------------------------

The complete working example described in the bug report is attached. To test 
with JDK7/JDK8:

$ export 
JAVA_HOME=/Library/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"


was (Author: cushon):
The complete working example described in the bug report. To test with 
JDK7/JDK8:

$ export 
JAVA_HOME=/Library/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"

> JDK8 - Annotations on synthetic bridge methods break bval
> ---------------------------------------------------------
>
>                 Key: BVAL-129
>                 URL: https://issues.apache.org/jira/browse/BVAL-129
>             Project: BVal
>          Issue Type: Bug
>          Components: jsr303
>    Affects Versions: 0.5, 1.1.0-alpha
>         Environment: JDK8
>            Reporter: Liam Miller-Cushon
>         Attachments: bvalrepro.zip
>
>
> As of jdk8, the java compiler now copies annotations onto synthetic bridge 
> methods. See https://bugs.openjdk.java.net/browse/JDK-6695379 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:
> ===
> @Retention(RetentionPolicy.RUNTIME)
> @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> {
>   @SomeAnnotation
>   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"
> …
> SUCCESS
> $ export 
> JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/ && 
> mvn clean package exec:java -Dexec.mainClass="Test"
> ...
> java.lang.reflect.InvocationTargetException
>       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>       at 
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
>       at 
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>       at java.lang.reflect.Method.invoke(Method.java:483)
>       at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:293)
>       at java.lang.Thread.run(Thread.java:744)
> 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(AnnotationProcessor.java:326)
>       at 
> org.apache.bval.jsr303.AnnotationProcessor.getConstraintValidator(AnnotationProcessor.java:301)
>       at 
> org.apache.bval.jsr303.AnnotationProcessor.applyConstraint(AnnotationProcessor.java:241)
>       at 
> org.apache.bval.jsr303.AnnotationProcessor.processAnnotation(AnnotationProcessor.java:149)
>       at 
> org.apache.bval.jsr303.AnnotationProcessor.processAnnotations(AnnotationProcessor.java:90)
>       at 
> org.apache.bval.jsr303.Jsr303MetaBeanFactory.processClass(Jsr303MetaBeanFactory.java:156)
>       at 
> org.apache.bval.jsr303.Jsr303MetaBeanFactory.buildMetaBean(Jsr303MetaBeanFactory.java:95)
>       at 
> org.apache.bval.MetaBeanBuilder.buildForClass(MetaBeanBuilder.java:131)
>       at 
> org.apache.bval.MetaBeanManager.findForClass(MetaBeanManager.java:102)
>       at 
> org.apache.bval.jsr303.ClassValidator.validate(ClassValidator.java:140)
>       at Test.main(Test.java:33)
>       ... 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/Jsr303MetaBeanFactory.java
> +++ src/main/java/org/apache/bval/jsr303/Jsr303MetaBeanFactory.java
> @@ -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
(v6.2#6252)

Reply via email to