[hibernate-issues] [Hibernate-JIRA] Resolved: (HHH-5094) PersistenceUtilHelper cannot access non-public fields/methods (it should be able to)
Hardy Ferentschik (JIRA)
noreply at atlassian.com
Tue Jun 15 10:57:01 EDT 2010
[ http://opensource.atlassian.com/projects/hibernate/browse/HHH-5094?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Hardy Ferentschik resolved HHH-5094.
------------------------------------
Resolution: Fixed
Fixed on 3.5.3 and trunk (3.6)
> PersistenceUtilHelper cannot access non-public fields/methods (it should be able to)
> ------------------------------------------------------------------------------------
>
> Key: HHH-5094
> URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-5094
> Project: Hibernate Core
> Issue Type: Bug
> Components: entity-manager
> Affects Versions: 3.5.0-Final
> Environment: 3.5.0-Final. Any environment
> Reporter: Philip Clay
> Assignee: Hardy Ferentschik
> Fix For: 3.5.3, 3.6
>
> Attachments: hibernate-entitymanager-bugreproduction.tgz
>
>
> PersistenceUtilHelper is only able to access public fields and public methods. As it is written, it cannot access non-public members.
> Internally, it incorrectly uses Class.getField(...) and Class.getMethod(...).
> It should use Class.getDeclaredField(...) and Class.getDeclaredMethod(...), so that it can see non-public members.
> I believe the use of getField and getMethod is not indented, because setAccessibility is the next call after that. Here is the code...
> {code}
> private static Object get(Object proxy, String property) {
> final Class<?> clazz = proxy.getClass();
> try {
> try {
> final Field field = clazz.getField( property ); // only retrieves public fields!!!
> setAccessibility( field ); // if you really only wanted public fields, this call is unnecessary!
> return field.get( proxy );
> }
> catch ( NoSuchFieldException e ) {
> final Method method = getMethod( clazz, property );
> if (method != null) {
> setAccessibility( method ); // if you really only wanted public methods, this call is unnecessary!
> return method.invoke( proxy );
> }
> ...
> }
> private static Method getMethod(Class<?> clazz, String methodName) {
> try {
> char string[] = methodName.toCharArray();
> string[0] = Character.toUpperCase( string[0] );
> methodName = new String( string );
> try {
> return clazz.getMethod( "get" + methodName ); // only retrieves public methods!!!
> }
> catch ( NoSuchMethodException e ) {
> return clazz.getMethod( "is" + methodName ); // only retrieves public methods!!!
> }
> ...
> }
> private static void setAccessibility(Member member) {
> if ( !Modifier.isPublic( member.getModifiers() ) ) {
> //Sun's ease of use, sigh...
> ( ( AccessibleObject ) member ).setAccessible( true ); // This is dead code! The input member will always be public
> }
> }
> {code}
> Notice the call to setAccessibility. The call to setAccessibility shows that one assumes that the field retrieved from getField() (or method from getMethod()) could be non-public, which in fact it can't. All fields returned from getField will always be public (same for getMethod()). So, essentially the code inside the if statement in setAccessibility is dead code.
> I have attached a tarball containing a failing testcase that shows the incorrect behavior.
> Explode the tarball and run "mvn test" to reproduce the incorrect behavior.
> Also, within the tarball, I have included an svn diff for a proposed patch.
> See the README.txt file within the tarball for more info.
> I first noticed this problem when using hibernate validator to validate some protected members, but I narrowed it down to a problem in PersistenceUtilHelper.
--
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