Howdy,
I'm using ByteBuddy (1.11.16, currently) to replace cglib2 usage in an old, large codebase. My first area to upgrade is lazily resolved proxies that lazily resolve/instantiate their delegate on first method call. I'm using subclassing, using the @Pipe annotation, and injecting into existing classloader.
I'm generating subclasses of the proxied concrete class. The existing cglib2 implementation supports delegation of public, protected and package/default methods.
My ByteBuddy code seems to work fine for public methods (of course) and for package/default methods, but protected methods get an error like:
java.lang.IllegalArgumentException: None of [public static java.lang.Object com.example.package.PipeInterceptor.packageIntercept(com.example.PipeInvoker,atg.aop.LazilyResolvedProxy,com.example.LazilyResolvedProxy)] allows for delegation from protected java.lang.String com.example.package.ExampleClass.doProtected().
The code I'm using to handle protected and package/default methods looks up a per-package "pipe interceptor" class that is in the package of method.getDeclaringClass(). The code that invokes ByteBuddy on the per-package protected/package methods looks like:
// now, for each package with package or protected methods,
// create a subclass of pPipeInterceptor within that package...
for (Map.Entry<Package, Pair<ClassLoader, List<Method>>>
entryCur : packageToMethods.entrySet()) {
ClassLoader classLoader = entryCur.getValue().getCar();
Class<?> pipeInterceptorClass = getPipeInterceptorForPackage(
entryCur.getKey().getName(), classLoader);
builder = builder.method(
ElementMatchers.anyOf(entryCur.getValue().getCdr().toArray(new Method[0])))
.intercept(// do the above but with our pipe
MethodDelegation
.withDefaultConfiguration()
.withBinders(Pipe.Binder.install(PipeInvoker.class))
.to(pipeInterceptorClass));
}
I've double-checked that my "pipeInterceptorClass" class is in the right package, and that package and classloader are "==" (not just having the same name) with the ones from method.getDeclaringClass(). Since protected is more permissive than package/default (a proper superset, adding subclasses access to the method as well) seems like what works in-package for package/default should work for protected... but that doesn't appear to be the case.
Can anyone suggest what I might be doing wrong?