[hibernate-issues] [Hibernate-JIRA] Issue Comment Edited: (HV-492) Validation of CGLIB enhanced Objects always return null

Christian Fehmer (JIRA) noreply at atlassian.com
Tue Jun 14 11:25:24 EDT 2011


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

Christian Fehmer edited comment on HV-492 at 6/14/11 10:25 AM:
---------------------------------------------------------------

>From the architectural point of view you are right, HV should not know about any byte code enhancers. But HV uses reflection to access the private fields directly so it will fail on any byte code enhancer. As far a i know it is not possible for byte code enhancers to intercept the field access themselves. Should libraries using reflection in this way be aware of bytecode enhancers?
My "patch" is not very accurate, it is just a fast and ugly workaround for my problem, I will replace it with the annotations on method level. 
If the behavior will remain it is very hard to find the problem for others, because HV just proceeds with the null value, no exception no warning. But without checking for bytecode enhancers i currently have no idea how to detect this error on the HV side. 
One possible solution would be to use getters if aviable each time, not only when the object is enhanced, but that will decrease the performance as well.
EDIT: i just tested that object.getClass().getField(member.getName()) will fail on an enhanced object and  object.getClass().equals(member.getDeclaringClass()) returns false

      was (Author: christianfehmer):
    From the architectural point of view you are right, HV should not know about any byte code enhancers. But HV uses reflection to access the private fields directly so it will fail on any byte code enhancer. As far a i know it is not possible for byte code enhancers to intercept the field access themselves. Should libraries using reflection in this way be aware of bytecode enhancers?
My "patch" is not very accurate, it is just a fast and ugly workaround for my problem, I will replace it with the annotations on method level. 
If the behavior will remain it is very hard to find the problem for others, because HV just proceeds with the null value, no exception no warning. But without checking for bytecode enhancers i currently have no idea how to detect this error on the HV side. 
One possible solution would be to use getters if aviable each time, not only when the object is enhanced, but that will decrease the performance as well.
EDIT: i just tested that object.getClass().getField(member.getName()) will fail on an enhanced object.
  
> Validation of CGLIB enhanced Objects always return null
> -------------------------------------------------------
>
>                 Key: HV-492
>                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HV-492
>             Project: Hibernate Validator
>          Issue Type: Bug
>    Affects Versions: 4.1.0.Final, 4.2.0.Beta2
>         Environment: Hibernate Validator 4.1.0-final and 4.2.0-BETA2, cglib 2.2
>            Reporter: Christian Fehmer
>
> A validation of a cglib enhanced object will always validate "null". 
> The validator (i tested it with an custom validator) always gets "null" as the value in the isValid method. The cglib enhanced object has a field "selection" and a getter/setter pair for this field. The hibernate validator uses the org.hibernate.validator.util.ReflectionHelper to access the field selection directly. That fails on a cglib enhanced object.
> My workaround for now: I replaced the org.hibernate.validator.util.ReflectionHelper.getValue method. When object is a cglib enhanced object i invoke the getter method instead of accessing the field directly.
> replaced method:
> {code}
> 	public static Object getValue(Member member, Object object) {
> 		Object value = null;
> 		if (member instanceof Method) {
> 			...
> 		} else if (member instanceof Field) {
> 			// FIX: use getter method on cglib fields
> 			if (object.getClass().getName().contains("$$")) {
> 				String methodName = member.getName();
> 				methodName = "get"+ String.valueOf(methodName.charAt(0)).toUpperCase()+ methodName.substring(1);
> 				try {
> 					Method method = member.getDeclaringClass().getMethod(
> 							methodName);
> 					method.setAccessible(true);
> 					value = method.invoke(object);
> 				} catch (Exception e) {
> 					throw new ValidationException("Unable to access  "
> 							+ methodName, e);
> 				}
> 			} else {
> 				...
> 			}
> 		}
> 		return value;
> 	}
> {code}

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