I have the following interceptor developed for byte-buddy:
public class SecurityInterceptor() {
@RuntimeType
public static Object intercept(
@SuperCall Callable<Object> supercall,
@This Object target,
@Origin Method method,
@AllArguments Object[] args) {
// Check args and annotations ...
Object obj = supercall.call();
// Post-process obj content ...
}
}
The interceptor is registered as follows:
Unloaded<Object> unloaded = new ByteBuddy()
.rebase(type, classFileLocator)
.method(ElementMatchers.isAnnotatedWith(Secured.class))
.intercept(MethodDelegation.to(SecurityInterceptor.class))
.make();
wovenClass.setBytes(unloaded.getBytes());
and this happens inside a WeavingHook
in OSGi. The problem is that rebasing with @SuperCall
alters the original code as such
public User getUser(final String s) throws Exception {
return SecurityInterceptor.intercept((Callable)new UsersServiceImpl$auxiliary$xhbBRSr4(this, s),
(Object)this, UsersServiceImpl.cachedValue$nlgHrwy3$sn5qca3, new Object[] { s });
}
where UsersServiceImpl$auxiliary$xhbBRSr4
is a synthetic class that is generated by byte-buddy:
class UsersServiceImpl$auxiliary$xhbBRSr4 implements Runnable, Callable
{
private UsersServiceImpl argument0;
private String argument1;
@Override
public Object call() throws Exception {
return this.argument0.getUser$original$6ve6X5gN$accessor$nlgHrwy3(this.argument1);
}
@Override
public void run() {
this.argument0.getUser$original$6ve6X5gN$accessor$nlgHrwy3(this.argument1);
}
UsersServiceImpl$auxiliary$xhbBRSr4(final UsersServiceImpl argument0, final String argument2) {
this.argument0 = argument0;
this.argument1 = argument2;
}
}
where UsersServiceImpl
is the class being weaved.
So what I need is to add all these synthetic classes in the class space of the UsersServiceImpl
's bundle (or in general make synthetic classes "accessible" from that bundle). Is this possible?
In the end I used a different approach:
Unloaded<Object> unloaded = new ByteBuddy()
.redefine(type, classFileLocator)
.visit(Advice.to(SecurityAdvice.class)
.on(ElementMatchers.isAnnotatedWith(Secured.class)))
.make();
with
public class SecurityAdvice {
@Advice.OnMethodEnter
private static void enter(@Advice.AllArguments Object[] args) {
//...
}
@Advice.OnMethodExit
private static void exit(@Advice.Return(typing = Typing.DYNAMIC) Object value) {
//...
}
}
this only alters the original class's bytecode without introducing additional synthetic types.