6

I have Byte Buddy up and running as an agent and it is successfully intercepting the vast majority of my codebase, which is quite large by the way! There are though a few outliers which I could not instrument and which I have documented below in the hope that you might know the answer!

1. CGLIB generated classes

Spring generates some additional classes that have the same name as my classes but have "$$EnhancerByCGLIB$$" appended to the end and these are causing errors. The error I get is:

java.lang.IllegalStateException: Cannot resolve type description for com.mycompany.MySpringBean$$EnhancerByCGLIB$$ee9d3c37_2
at net.bytebuddy.pool.TypePool$Resolution$Illegal.resolve(TypePool.java:152)
at net.bytebuddy.pool.TypePool$LazyFacade$LazyResolution$LazyTypeDescription.resolve(TypePool.java:3158)
at net.bytebuddy.pool.TypePool$LazyFacade$LazyResolution$LazyTypeDescription.getModifiers(TypePool.java:3238)
at net.bytebuddy.ByteBuddy.rebase(ByteBuddy.java:697)

In truth, I have no interest in instrumenting the CGLIB generated classes and therefore wish to exclude these. What is the best approach? For the moment, I am matching by name but I wonder if this is the best way.

.and(not(nameContains("EnhancerByCGLIB")))

2. Package Private and Private Classes

Another issue I am seeing is instrumenting a package private or a private class.

Package private code looks like this:

abstract class BaseBean {
    Object methodA(final String customerNumber){}
}

The error I get is:

Caused by: java.lang.IllegalAccessException:
    Class net.bytebuddy.implementation.LoadedTypeInitializer$ForStaticField cannot 
    access a member of class com.mycompany.BaseBean with modifiers "public static"

Private class code looks like this:

public class Object A {
 //variables & methods...
 private class ObjectB {}
}

The error I get is:

Caused by: java.lang.IllegalAccessException:
    Class net.bytebuddy.implementation.LoadedTypeInitializer$ForStaticField cannot 
    access a member of class com.mycompany.ObjectA$ObjectB with modifiers "public static"

Can Byte Buddy instrument package private or private classes?

3. Silent fails

This is just a general question but is it possible to instruct Byte Buddy to fail silently on each class? This is so that any such errors do not prevent the application from starting up or Byte Buddy from instrumenting as many as it can.

4. Public methods in public abstract classes

My code is something like:

package com.mycompany;
public interface InterfaceA{
    Object provideAccess(final String id);
}

package com.mycompany;
public abstract class BaseBeanA implements InterfaceA { 
  //some general helper methods
}

package com.mycompany;
public abstract class BaseBeanB extends BaseBeanA { 
    //some specific helper methods
}

package com.mycompany;
public class BeanImpl extends BaseBeanB {   
    protected Object provideAccess(final String id) {
    }
}

This causes the following error on instrumenting BaseBeanB:

java.lang.IllegalArgumentException: None of [protected void java.lang.Object.finalize() throws java.lang.Throwable, public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException, public final void java.lang.Object.wait() throws java.lang.InterruptedException, public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException, public boolean java.lang.Object.equals(java.lang.Object), public java.lang.String java.lang.Object.toString(), public native int java.lang.Object.hashCode(), public final native java.lang.Class java.lang.Object.getClass(), protected native java.lang.Object java.lang.Object.clone() throws java.lang.CloneNotSupportedException, public final native void java.lang.Object.notify(), public final native void java.lang.Object.notifyAll(), public java.lang.Object com.mycompany.MyInterceptor.intercept(java.util.concurrent.Callable,java.lang.Object[],java.lang.reflect.Method,java.lang.Class) throws java.lang.Exception] allows for delegation from public abstract Object com.mycompany.InterfaceA.provideAccess(java.lang.String)

user1563817
  • 121
  • 1
  • 5

1 Answers1

7

1. CGLIB generated classes

Your solution is correct. As a matter of fact, it is always good for performance to specify classes by name. For example, if you can exclude an entire package, Byte Buddy can already discard a class without even parsing the class file as the name is available separately.

The reason that the instrumentation for cglib-generated classes fails is that there is no byte code for these classes available.

2. Package Private &Private classes

You found a bug here. I recently refactored this logic to not requiring accessibility for synthetic fields by making them public but I simply forgot about package-private fields. This is fixed on the master branch and will be released in 0.7-rc7.

3. Silent fails

If instrumentation fails, this failure is always reported to an AgentBuilder.Listener. Other than that, the failure has no effect as it is implied by the ClassFileTransformer API. Do you observe any exceptions that are passed through? You might also want to check out the most recent version where the listener AgentBuilder was significantly refactored.

4. Public methods in public abstract classes

Your interceptor defines a parameter of type Callable which I assume is annotated by SuperCall. This injects a proxy to invoke the intercepted method’s super method if it exists. For an abstract method like the one you are trying to intercept, this does not work and Byte Buddy decides that your interceptor is not bindable. Therefore, the exception is thrown.

Saying this, by excluding the methods of the Object type from delegation, Byte Buddy does not consider them for delegation. This improves performance.

Mogsdad
  • 44,709
  • 21
  • 151
  • 275
Rafael Winterhalter
  • 42,759
  • 13
  • 108
  • 192
  • Thanks for the comments, I am on 0.7-rc5 but see that you have released rc6. I will upgrade and check. It sounds like that bug fix will go into rc7 so? I also have another one for you which I have added to the original question, if you don't mind having a look. Cheers, John – user1563817 Oct 30 '15 at 10:23