[
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)