cglib / cglib

cglib - Byte Code Generation Library is high level API to generate and transform Java byte code. It is used by AOP, testing, data access frameworks to generate dynamic proxy objects and intercept field access.
https://github.com/cglib/cglib/wiki
Apache License 2.0
4.78k stars 885 forks source link

jdk 7+ Enhancer.getMethods (guice) #59

Open robbiepl opened 8 years ago

robbiepl commented 8 years ago

I use JDK 6 with Guice 2 (cglib also naturally) in my project. When I want to migrate to jdk 8 and Guice 4, I have a strange problem, hmhm I suspect higher jdk and cglib 3.2.0 (asm 5.x)

I prepared simple application for this case. cglib-test

The problem is Enhancer.getMethods(....)

For JDK 6 Enhancer returns one methods with my annotations (AnnotationFirst,AnnotationSecond)

public cglib.domain.SomeResponse cglib.SimpleHandler.handle(cglib.domain.SomeRequest) [@cglib.inter.anon.AnnotationFirst(), @cglib.inter.anon.AnnotationSecond()] public cglib.domain.ResponseAbstract cglib.SimpleHandler.handle(cglib.domain.GenericRequest) [] ....... .......

For higher JDK (7+) Enhancer returns magic two methods :/

public cglib.domain.SomeResponse cglib.SimpleHandler.handle(cglib.domain.SomeRequest) [@cglib.inter.anon.AnnotationFirst(), @cglib.inter.anon.AnnotationSecond()] public cglib.domain.ResponseAbstract cglib.SimpleHandler.handle(cglib.domain.GenericRequest) [@cglib.inter.anon.AnnotationFirst(), @cglib.inter.anon.AnnotationSecond()] ....... .......

Is this normal behavior cglib?

As a consequence, Guice creates two net.sf.cglib.proxy.Callback and double call each intereceptor.

raphw commented 8 years ago

The problem is that Java 8 allows default methods on interfaces. As a result, the Java compiler can add bridge methods to the interface type. Cglib was written in a time where Java 8 was not even on the horizon and therefore, this potential problem was not considered.

Supporting this would require a deeper lying change in the library. If you want to work around this, exlude bridge methods from interception using a filter.

sameb commented 8 years ago

Is this an issue you're seeing solely with using cglib, or with using AOP in Guice? If in Guice, it should be logging a warning that you may be double-intercepting a method (because it looks to see if it's intercepting bridge methods). The best solution is to tweak your matcher so it doesn't match on bridge/synthetic methods.