关于java:使用Byte Buddy进行检测的问题

Problems with instrumentation using Byte Buddy

我有一个字节伙伴,作为一个代理运行,它成功地截获了我的绝大多数代码库,顺便说一下,这相当大!尽管有一些异常值我无法检测到,我已经记录在下面,希望您能知道答案!

1。cglib生成的类

Spring生成了一些额外的类,这些类与我的类同名,但在末尾附加了"$$EnhancerByCGLIB$$",这些都会导致错误。我得到的错误是:

1
2
3
4
5
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)

实际上,我对检测cglib生成的类没有兴趣,因此希望排除这些类。最好的方法是什么?目前,我正在按名字配对,但我想知道这是否是最好的方式。

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

2。打包私有类和私有类

我看到的另一个问题是检测package privateprivate class

package private代码如下:

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

我得到的错误是:

1
2
3
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代码如下:

1
2
3
4
public class Object A {
 //variables & methods...
 private class ObjectB {}
}

我得到的错误是:

1
2
3
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"

字节伙伴仪器可以是package private还是private classes

三。沉默失败

这只是一个一般性的问题,但是否可以指示byte buddy在每个类上安静地失败?这样一来,任何此类错误都不会阻止应用程序启动或阻止字节伙伴尽可能多地检测。

4。公共抽象类中的公共方法

我的代码是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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) {
    }
}

这会导致检测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)


1。cglib生成的类

您的解决方案是正确的。事实上,按名称指定类对性能总是有利的。例如,如果您可以排除整个包,那么字节伙伴就可以放弃一个类,而不必解析类文件,因为该名称可以单独使用。

cglib生成的类的检测失败的原因是这些类没有可用的字节代码。

2。打包私有类和私有类

你在这里发现了一个虫子。我最近重构了这个逻辑,使其公开,从而不需要对合成字段进行访问,但我只是忘记了打包私有字段。它固定在主分支上,将在0.7-rc7中发布。

三。沉默失败

如果仪器出现故障,该故障总是报告给AgentBuilder.Listener。除此之外,故障没有任何影响,因为它是由ClassFileTransformerAPI所暗示的。您是否注意到通过的任何异常情况?您可能还想查看最新版本,其中侦听器AgentBuilder被显著地重构。

4。公共抽象类中的公共方法

您的拦截器定义了一个类型为Callable的参数,我假设该参数由SuperCall注释。这会注入一个代理来调用被截取方法的超级方法(如果存在的话)。对于一个抽象的方法,比如您试图截取的方法,这不起作用,字节伙伴决定截取程序不可绑定。因此,抛出异常。

这么说,通过从委托中排除对象类型的方法,byte buddy不会将它们视为委托。这提高了性能。