Menu

#41 2.2.3 is missing bridge method fixes from 2.2.2

open
nobody
None
5
2013-04-01
2013-04-01
No

CGLIB 2.2.3 does not work with Guice, specifically it fails the testInterceptingNonBridgeWorks unit test. When I compare cglib-src-2.2.2.jar with the sources in cglib.2.2.3.zip (both downloaded from the Files section) the following diff shows that 2.2.3 removed various bridge method fixes that were in 2.2.2:

diff -r -w -u 2.2.2/src/proxy/net/sf/cglib/core/TypeUtils.java 2.2.3/src/proxy/net/sf/cglib/core/TypeUtils.java
--- 2.2.2/src/proxy/net/sf/cglib/core/TypeUtils.java 2011-04-20 11:53:40.000000000 +0100
+++ 2.2.3/src/proxy/net/sf/cglib/core/TypeUtils.java 2004-06-25 00:15:20.000000000 +0100
@@ -75,10 +75,6 @@
return (Constants.ACC_SYNTHETIC & access) != 0;
}

- public static boolean isBridge(int access) {
- return (Constants.ACC_BRIDGE & access) != 0;
- }
-
// getPackage returns null on JDK 1.2
public static String getPackageName(Type type) {
return getPackageName(getClassName(type));
Only in 2.2.2/src/proxy/net/sf/cglib/proxy: BridgeMethodResolver.java
diff -r -w -u 2.2.2/src/proxy/net/sf/cglib/proxy/CallbackGenerator.java 2.2.3/src/proxy/net/sf/cglib/proxy/CallbackGenerator.java
--- 2.2.2/src/proxy/net/sf/cglib/proxy/CallbackGenerator.java 2011-04-20 11:53:40.000000000 +0100
+++ 2.2.3/src/proxy/net/sf/cglib/proxy/CallbackGenerator.java 2006-01-11 23:47:44.000000000 +0000
@@ -31,6 +31,5 @@
int getIndex(MethodInfo method);
void emitCallback(CodeEmitter ce, int index);
Signature getImplSignature(MethodInfo method);
- void emitInvoke(CodeEmitter e, MethodInfo method);
}
}
diff -r -w -u 2.2.2/src/proxy/net/sf/cglib/proxy/Enhancer.java 2.2.3/src/proxy/net/sf/cglib/proxy/Enhancer.java
--- 2.2.2/src/proxy/net/sf/cglib/proxy/Enhancer.java 2011-04-20 11:53:40.000000000 +0100
+++ 2.2.3/src/proxy/net/sf/cglib/proxy/Enhancer.java 2007-03-16 02:57:18.000000000 +0000
@@ -876,7 +876,6 @@
final Map indexes = new HashMap();
final Map originalModifiers = new HashMap();
final Map positions = CollectionUtils.getIndexMap(methods);
- final Map declToBridge = new HashMap();

Iterator it1 = methods.iterator();
Iterator it2 = (actualMethods != null) ? actualMethods.iterator() : null;
@@ -895,20 +894,7 @@
groups.put(generators[index], group = new ArrayList(methods.size()));
}
group.add(method);
-
- // Optimization: build up a map of Class -> bridge methods in class
- // so that we can look up all the bridge methods in one pass for a class.
- if (TypeUtils.isBridge(actualMethod.getModifiers())) {
- Set bridges = (Set)declToBridge.get(actualMethod.getDeclaringClass());
- if (bridges == null) {
- bridges = new HashSet();
- declToBridge.put(actualMethod.getDeclaringClass(), bridges);
- }
- bridges.add(method.getSignature());
}
- }
-
- final Map bridgeToTarget = new BridgeMethodResolver(declToBridge).resolveAll();

Set seenGen = new HashSet();
CodeEmitter se = ce.getStaticHook();
@@ -934,39 +920,6 @@
public Signature getImplSignature(MethodInfo method) {
return rename(method.getSignature(), ((Integer)positions.get(method)).intValue());
}
- public void emitInvoke(CodeEmitter e, MethodInfo method) {
- // If this is a bridge and we know the target was called from invokespecial,
- // then we need to invoke_virtual w/ the bridge target instead of doing
- // a super, because super may itself be using super, which would bypass
- // any proxies on the target.
- Signature bridgeTarget = (Signature)bridgeToTarget.get(method.getSignature());
- if (bridgeTarget != null) {
- // TODO: this assumes that the target has wider or the same type
- // parameters than the current.
- // In reality this should always be true because otherwise we wouldn't
- // have had a bridge doing an invokespecial.
- // If it isn't true, we would need to checkcast each argument
- // against the target's argument types
- e.invoke_virtual_this(bridgeTarget);
-
- Type retType = method.getSignature().getReturnType();
- // Not necessary to cast if the target & bridge have
- // the same return type.
- // (This conveniently includes void and primitive types,
- // which would fail if casted. It's not possible to
- // covariant from boxed to unbox (or vice versa), so no having
- // to box/unbox for bridges).
- // TODO: It also isn't necessary to checkcast if the return is
- // assignable from the target. (This would happen if a subclass
- // used covariant returns to narrow the return type within a bridge
- // method.)
- if (!retType.equals(bridgeTarget.getReturnType())) {
- e.checkcast(retType);
- }
- } else {
- e.super_invoke(method.getSignature());
- }
- }
public CodeEmitter beginMethod(ClassEmitter ce, MethodInfo method) {
CodeEmitter e = EmitUtils.begin_method(ce, method);
if (!interceptDuringConstruction &&
diff -r -w -u 2.2.2/src/proxy/net/sf/cglib/proxy/MethodInterceptorGenerator.java 2.2.3/src/proxy/net/sf/cglib/proxy/MethodInterceptorGenerator.java
--- 2.2.2/src/proxy/net/sf/cglib/proxy/MethodInterceptorGenerator.java 2011-04-20 11:53:42.000000000 +0100
+++ 2.2.3/src/proxy/net/sf/cglib/proxy/MethodInterceptorGenerator.java 2006-03-05 04:43:20.000000000 +0000
@@ -100,7 +100,7 @@
e = ce.begin_method(Constants.ACC_FINAL,
impl,
method.getExceptionTypes());
- superHelper(e, method, context);
+ superHelper(e, method);
e.return_value();
e.end_method();

@@ -126,21 +126,21 @@
e.return_value();

e.mark(nullInterceptor);
- superHelper(e, method, context);
+ superHelper(e, method);
e.return_value();
e.end_method();
}
generateFindProxy(ce, sigMap);
}

- private static void superHelper(CodeEmitter e, MethodInfo method, Context context)
+ private static void superHelper(CodeEmitter e, MethodInfo method)
{
if (TypeUtils.isAbstract(method.getModifiers())) {
e.throw_exception(ABSTRACT_METHOD_ERROR, method.toString() + " is abstract" );
} else {
e.load_this();
e.load_args();
- context.emitInvoke(e, method);
+ e.super_invoke(method.getSignature());
}
}

diff -r -w -u 2.2.2/src/proxy/net/sf/cglib/proxy/NoOpGenerator.java 2.2.3/src/proxy/net/sf/cglib/proxy/NoOpGenerator.java
--- 2.2.2/src/proxy/net/sf/cglib/proxy/NoOpGenerator.java 2011-04-20 11:53:42.000000000 +0100
+++ 2.2.3/src/proxy/net/sf/cglib/proxy/NoOpGenerator.java 2004-12-23 05:46:26.000000000 +0000
@@ -27,13 +27,12 @@
public void generate(ClassEmitter ce, Context context, List methods) {
for (Iterator it = methods.iterator(); it.hasNext();) {
MethodInfo method = (MethodInfo)it.next();
- if (TypeUtils.isBridge(method.getModifiers()) || (
- TypeUtils.isProtected(context.getOriginalModifiers(method)) &&
- TypeUtils.isPublic(method.getModifiers()))) {
+ if (TypeUtils.isProtected(context.getOriginalModifiers(method)) &&
+ TypeUtils.isPublic(method.getModifiers())) {
CodeEmitter e = EmitUtils.begin_method(ce, method);
e.load_this();
e.load_args();
- context.emitInvoke(e, method);
+ e.super_invoke();
e.return_value();
e.end_method();
}

Note: this was the only diff I expected based on the 2.2.3 release notes:

diff -r -w -u 2.2.2/src/proxy/net/sf/cglib/transform/impl/UndeclaredThrowableStrategy.java 2.2.3/src/proxy/net/sf/cglib/transform/impl/UndeclaredThrowableStrategy.java
--- 2.2.2/src/proxy/net/sf/cglib/transform/impl/UndeclaredThrowableStrategy.java 2006-03-04 21:43:18.000000000 +0000
+++ 2.2.3/src/proxy/net/sf/cglib/transform/impl/UndeclaredThrowableStrategy.java 2012-07-27 19:16:24.000000000 +0100
@@ -25,7 +25,9 @@
* in an alternative exception of your choice.
*/
public class UndeclaredThrowableStrategy extends DefaultGeneratorStrategy {
- private ClassTransformer t;
+
+
+ private Class wrapper;

/**
* Create a new instance of this strategy.
@@ -36,8 +38,7 @@
* <code>java.lang.reflect.UndeclaredThrowableException.class</code>
*/
public UndeclaredThrowableStrategy(Class wrapper) {
- t = new UndeclaredThrowableTransformer(wrapper);
- t = new MethodFilterTransformer(TRANSFORM_FILTER, t);
+ this.wrapper = wrapper;
}

private static final MethodFilter TRANSFORM_FILTER = new MethodFilter() {
@@ -47,7 +48,9 @@
};

protected ClassGenerator transform(ClassGenerator cg) throws Exception {
- return new TransformingClassGenerator(cg, t);
+ ClassTransformer tr = new UndeclaredThrowableTransformer(wrapper);
+ tr = new MethodFilterTransformer(TRANSFORM_FILTER, tr);
+ return new TransformingClassGenerator(cg, tr);
}
}

Discussion