You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by "Attila Király (JIRA)" <ji...@apache.org> on 2010/10/14 09:25:33 UTC

[jira] Updated: (WICKET-3105) [wicket-ioc] Make it possible to use javassist instead of cglib for proxy generation

     [ https://issues.apache.org/jira/browse/WICKET-3105?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Attila Király updated WICKET-3105:
----------------------------------

    Attachment: cglib-javassist-test.zip

Attaching a test maven project. MyService is a class with a public final doStuff() method and that method calling a protected non final doInnerStuff() method.

MyServiceTest with test cases:

- the first cglib variant (cglib() method) is based on how o.a.w.proxy.LazyInitProxyFactory uses cglib (using proxy.invoker(obj, args) in interceptor): fails with "IllegalArgumentException: Protected method: doInnerStuff()I". This is what I see in practice too.

- the javassist variant showing how to do this the javassist way. Succseeds. (Btw. javassist can do other crazy things like adding methods and constructors to classes see [1] but I am not an expert in that).

- the second cglib variant (cglib2() method): after looking into cglib javadoc (see [2] & [3]), while doing the testcase, it turned out wicket uses cglib wrongly and cglib can proxy final methods too. This test variant uses proxy.invokeSuper(obj, args) in interceptor and it succseeds!

This seams to indicate that there is no need to include javassist variant after all only a one line change is needed (but I did not try that in the wicket build). (In my opinion however in the long run LazyInitProxyFactory really could get some refactoring).

[1]: javassist examples adding methods to classes: http://www.csg.is.titech.ac.jp/~chiba/javassist/tutorial/tutorial2.html#add
[2]: cglib MethodProxy.invoke() http://cglib.sourceforge.net/apidocs/net/sf/cglib/proxy/MethodProxy.html#invoke(java.lang.Object, java.lang.Object[])
[3]: cglib MethodProxy.invokeSuper() http://cglib.sourceforge.net/apidocs/net/sf/cglib/proxy/MethodProxy.html#invokeSuper(java.lang.Object, java.lang.Object[])

> [wicket-ioc] Make it possible to use javassist instead of cglib for proxy generation
> ------------------------------------------------------------------------------------
>
>                 Key: WICKET-3105
>                 URL: https://issues.apache.org/jira/browse/WICKET-3105
>             Project: Wicket
>          Issue Type: Improvement
>          Components: wicket-spring
>    Affects Versions: 1.4.12
>         Environment: spring 3.0.4; servlet 2.5, 3.0
>            Reporter: Attila Király
>         Attachments: cglib-javassist-test.zip
>
>
> I got bitten with the cglib limitation of not handling final methods. This is a real pain because it can result in cryptic exceptions (like "IllegalArgumentException: Protected method: [a method name what I didn't call explicitly]"). I have checked wicket jira and I see others have problem with cglib too (like the need for a non-private no-arg constructor). While javassist can not solve all these problems, but at least a few of it (final method proxying works but no-arg constructors still needed).
> So I suggest to modify wicket-ioc to support both cglib and javassist. Like this (refactoring and extending o.a.w.proxy.LazyInitProxyFactory class):
> - make an IProxyFactory interface as common ancestor. Make 3 classes implementing it (JdkProxyFactory for interfaces, CglibProxyFactory to reflect current class proxying and JavassistProxyFactory as the new implementation)
> - make an IProxyInvocationHandler interface and an AbstractProxyInvocationHandler to hold common interface superclasses and methods (currently as protected static presented in LazyInitProxyFactory)
> - make the 3 invocation handlers implement AbstractProxyInvocationHandler (2 are currently in LazyInitProxyFactory: JdkHandler and CGLibInterceptor and the 3rd would be the new JavassistMethodHandler)
> - make a new static classProxyFactory field in LazyInitProxyFactory that can be setted trough a public method. Its value should default to CglibProxyFactory (to be backward compatible).
> - modify LazyInitProxyFactory so it uses JdkProxyFactory for interfaces and the classProxyFactory for classes.
> - add javassist dependency to pom.xml as optional dependency (JavassistProxyFactory and JavassistMethodHandler should be outside of LazyInitProxyFactory class so they don't get loaded if they are not needed).
> In this way if someone wants to use javassist proxy instead of cglib only the followings are needed:
> - adding javassist to the dependent project's pom.
> - call LazyInitProxyFactory.setClassProxyFactory(new JavassistProxyFactory()); in the WebApplication init() method.
> I think these modifications could be made on the 1.4 branch too because they would not break the current public API of LazyInitProxyFactory (just add to it).
> Also could be made (but maybe these can't be done on the 1.4 branch because of compatibility):
> - pump cglib to 2.2 version from the current 2.1_3
> - factor cglib classes out from LazyInitProxyFactory and make cglib also an optional dependency
> I am willing to try to make a patch for this but first I would like to know the opinion of the wicket team about this.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.