[hibernate-issues] [Hibernate-JIRA] Commented: (HHH-3870) Hibernate proxies Groovy's getMetaClass method breaking proxies when used with Groovy

Graeme Rocher (JIRA) noreply at atlassian.com
Tue Apr 21 10:29:17 EDT 2009


    [ http://opensource.atlassian.com/projects/hibernate/browse/HHH-3870?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=32958#action_32958 ] 

Graeme Rocher commented on HHH-3870:
------------------------------------

It is unfortunately not changeable now. Feel free to provide suggestions on the Groovy JIRA on how it can be solved. For sure accessing a property of a subclass is bad, however you have to understand Groovy is dynamic :-)

In Java you would get a classcast exception, however because of Groovy's dynamic dispatch it allows you to invoke methods dynamically using duck typing to the underlying proxied instance. However this is falling over because the getMetaClass method is being proxied itself which confuses Groovy and makes it get the wrong meta class causing the IllegalArgumentException.

Anyway slight change to the proposed fix:

{code}
	private static final MethodFilter FINALIZE_FILTER = new MethodFilter() {
		public boolean isHandled(Method m) {
			// skip finalize methods
			return !( m.getParameterTypes().length == 0 && ((m.getName().equals( "finalize" ) || m.getName().equals( "getMetaClass" )) ));
		}
	};
{code}

But as I said ideally the proxying mechanism of Hibernate should a) work out of the box with Groovy and b) be more configurable for other cases where this must be an issue



> Hibernate proxies Groovy's getMetaClass method breaking proxies when used with Groovy
> -------------------------------------------------------------------------------------
>
>                 Key: HHH-3870
>                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3870
>             Project: Hibernate Core
>          Issue Type: Bug
>    Affects Versions: 3.2.6, 3.3.0.CR1, 3.3.0.CR2, 3.3.0.GA, 3.3.0.SP1, 3.3.1
>            Reporter: Graeme Rocher
>            Assignee: Emmanuel Bernard
>            Priority: Critical
>
> Say you have a class hierarchy like A->B-C and you obtain a proxied instance of C
> {code}
> A a = session.load(A, 1L)
> {code}
> When Groovy invokes a method it looks up the objects metaclass by calling the getMetaClass() method on A. The pseudo code for Groovy method dispatch is something like:
> {code}
> a.getMetaClass().invokeMethod(a, "foo")
> {code}
> The problem is that the getMetaClass() method is being proxied onto the underlying instance of C so when a.getMetaClass() is called you get the MetaClass for the class C, but because of the way Hibernate creates proxies it is not an instance of C at all, but instead an dynamically created subclass of A. The result is you get an IllegalArgumentException that is hard to debug.
> In Grails we have worked around this by customizing Hibernate's proxy creation mechanism to not proxy the getMetaClass() method. The problem this mechanism is currently insanely difficult to customize and also usage of Groovy on its own outside of Grails is still broken with Hibernate (such as inside JBoss Seam)
> It would be great if one of two things could be done:
> a) Hibernate does not proxy the getMetaClass() method at all this could be done by modifying JavassistLazyInitializer and the associated cglib one as follows:
> {code}
> 	private static final MethodFilter FINALIZE_FILTER = new MethodFilter() {
> 		public boolean isHandled(Method m) {
> 			// skip finalize methods
> 			return !( m.getParameterTypes().length == 0 && (m.getName().equals( "finalize" ) || m.getName().equals( "getMetaClass" ) ));
> 		}
> 	};
> {code}
> b) The mechanism for creating proxies is made easier to customize so that the getMetaClass() method can be easily excluded via some configuration or something. However, this would still mean that out of the box Hibernate is broken when used with Groovy unless the solution a) is applied too

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