标签: byte-buddy

使用Byte Buddy的仪器问题

我让Byte Buddy作为代理运行并且它成功地拦截了我的绝大部分代码库,顺便说一句,它是相当大的代码库!虽然有一些异常值我无法检测,我在下面记录了这些异常值,希望你能知道答案!

1. CGLIB生成的类

Spring生成一些额外的类,这些类与我的类具有相同的名称,但是"$$EnhancerByCGLIB$$"附加到末尾并且这些类导致错误.我得到的错误是:

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)
Run Code Online (Sandbox Code Playgroud)

事实上,我没有兴趣检测CGLIB生成的类,因此希望排除这些.什么是最好的方法?目前,我按名称匹配,但我想知道这是否是最佳方式.

.and(not(nameContains("EnhancerByCGLIB")))
Run Code Online (Sandbox Code Playgroud)

2.打包私有和私有类

我看到的另一个问题是检测a package private或a private class.

Package private 代码看起来像这样:

abstract class BaseBean {
    Object methodA(final String customerNumber){}
}
Run Code Online (Sandbox Code Playgroud)

我得到的错误是:

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

Private class 代码看起来像这样:

public class Object A {
 //variables & methods...
 private class ObjectB {}
}
Run Code Online (Sandbox Code Playgroud)

我得到的错误是:

Caused by: …
Run Code Online (Sandbox Code Playgroud)

java bytecode agent byte-buddy

4
推荐指数
1
解决办法
1114
查看次数

如何使用 Byte-Buddy 从接口构建 Java 类的具体实现?

我有一个界面,可以说它看起来像这样。

public interface TestObject {
    String getString();

    Long getLong();
}
Run Code Online (Sandbox Code Playgroud)

我想使用 ByteBuddy 实际构建此对象的具体实现。

这是我尝试过的。

public class Runme {

    public static void main(String[] args) {
        ByteBuddy bb = new ByteBuddy();

        Class<?> clz = bb
                .subclass(TestObject.class)
      .method(any()).intercept(MethodDelegation.to(Interceptor.class))
            .make()
            .load(Object.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
            .getLoaded();

    try {
        Object test = clz.newInstance();

    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }

}

public class Interceptor {

    public Object intercept(@Origin String method, @AllArguments Object[] args) throws Throwable {
        System.out.println("I have intercepted a call");

        return …
Run Code Online (Sandbox Code Playgroud)

java bytecode byte-buddy

4
推荐指数
1
解决办法
1265
查看次数

使用Byte Buddy添加具有给定值的注释

如何使用Byte Buddy添加具有给定值的注释?

我正在为JUnit生成测试类,我想通过注释生成的类@RunWith(SomeRunner.class).

java bytecode byte-buddy

4
推荐指数
1
解决办法
873
查看次数

Javaagent Instrumentation Framework 的 JUnit 测试框架

为 Java 代理和检测库的代码创建单元测试的标准方法是什么?我已经使用 Byte Buddy 框架创建了一个 Java 代理,用于在 Web 应用程序之上开发分析器,现在我想为该代理编写 JUnit 测试用例。

java junit unit-testing byte-buddy

4
推荐指数
1
解决办法
2363
查看次数

使用ByteBuddy定义具有通用类型的字段

我刚开始与ByteBuddy一起玩,并且正在研究几个示例,以便掌握它。

我试图通过此练习完成的工作是用ByteBuddy替换一些使用ASM的代码。

到目前为止,当涉及到非泛型类型时,我已经取得了成功。例如,我可以轻松地定义一个像这样的字段

builder.defineField("names", List.class, Visibility.PRIVATE)
Run Code Online (Sandbox Code Playgroud)

如果我只想创建一个原始List类型的字段。

但是,在介绍泛型时,我很困惑。

显然,我定义字段的方式(使用Class)意味着通用类型会丢失。阅读文档(尤其是该Working with generic types部分)后,我无法真正弄清楚如果List字段具有已知的通用类型(例如,如果它是另一个POJO)如何构造List字段。假设我有以下POJO:

public class Dummy {
   private String name;

   //getters, setters
}
Run Code Online (Sandbox Code Playgroud)

并且我想创建一个的字段List<Dummy>,我将如何完成这样的任务?

谢谢!

java byte-buddy

4
推荐指数
1
解决办法
543
查看次数

如何使用 Bytebuddy 拦截字段访问(无需 getter/setter)

我正在尝试使用bytebuddy来拦截getfieldputfield访问。我已经阅读了该网站上相当全面的文档,但据我所知,它涵盖了向字段添加 getter 和 setter,而不是拦截字段访问。

这基本上是我想做的事情:

...
obj.prop = value;
x = obj.prop;
...
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,我试图在字段访问之前/之后调用一些方法(或插入一些字节码)。我正在考虑使用Advice它来做到这一点,但除了方法之外,我找不到其他方法来实现它。

编辑:

我正在使用 Java 代理来执行此操作。我有一个想法,添加 adup来复制对象引用,然后调用我定义的静态方法来拦截访问(我只关心被引用的对象,而不是字段)。

java byte-buddy

4
推荐指数
1
解决办法
822
查看次数

“没有兼容的附件提供程序可用”是什么意思

最近,我使用字节伙伴开发了一个Java代理。eclipse中的开发很好,然后我将代理程序投入生产并发出以下消息:

No compatible attachment provider is available

以及从行开始的一些堆栈跟踪

static {
  ByteBuddyAgent.install();
}
Run Code Online (Sandbox Code Playgroud)

java byte-buddy

4
推荐指数
1
解决办法
1051
查看次数

如何使用 Byte Buddy 从 MethodDescription 中获取 Java 方法参数的实际名称?

受这篇文章http://mydailyjava.blogspot.com/2022/02/using-byte-buddy-for-proxy-creation.html的启发,我成功拦截了一个方法调用,检查所有方法参数的值,并返回一个模拟回应。

但是,我无法获取参数的实际名称(如源代码中所示)。我只能得到诸如“arg0”之类的名称。

我所做的最大努力是,在方法匹配器中,我可以访问方法的 MethodDescription,并且可以获得参数的 ParameterDescription。

@Override
public DynamicType.Builder<?> apply(DynamicType.Builder<?> builder, TypeDescription typeDescription, ClassFileLocator classFileLocator) {
    logger.info("OiiPlugin processing "+typeDescription);
    return builder
            .method(new ElementMatcher<MethodDescription>() {
                @Override
                public boolean matches(MethodDescription target) {
                    boolean isTarget = target.getDeclaredAnnotations().isAnnotationPresent(MockMe.class);
                    if (isTarget) {
                        ParameterDescription p = target.getParameters().get(0);
                        logger.info(
                                "Parameter 0 NAME:"+p.getActualName()+":"+p.getName()+":"+p.getInternalName());
                    };
                    return isTarget;
                }
            })
            .intercept(MethodDelegation.to(
                    OiiInterceptor.class
            ));
}
Run Code Online (Sandbox Code Playgroud)

然而,它的 getActualName() 返回空字符串。

[INFO] OiiPlugin processing class com.example.research.oii.client.ExampleClient
[INFO] Parameter 0 NAME::arg0:arg0
Run Code Online (Sandbox Code Playgroud)

我确实通过 maven 插件配置添加了 javac -g:vars 参数,以指示 javac 将参数名称放入 .class 文件中。

    <plugin>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.8.0</version> …
Run Code Online (Sandbox Code Playgroud)

java byte-buddy

4
推荐指数
1
解决办法
387
查看次数

简单的方法拦截与Byte Buddy之前和之后

在撰写本文时的Byte Buddy教程中,所有内容都得到了解释,但是一个简单的after和before方法拦截器不存在,正如我在下面解释的那样,我错过了什么或者教程很复杂.(请参阅LoggerInterceptor示例给出方法但不是对象,ChangingLoggerInterceptor示例给出对象但不调用方法)

我想要实现的是在setter方法执行后调用对象的方法.如何编写拦截器并在Java 6中使用它?

public class DirtyClass{

private String _sField;
private boolean _bDirty;

public void setField(String sField) {
    _sField = sField;
    //setDirty(true); to be appended after proxying
}
public String getField() {
    return _sField;
}
public void setDirty(boolean bDirty){
    _bDirty = bDirty;
}
public boolean isDirty(){
    return _bDirty;
}
}

DirtyClass d = new ByteBuddy().subclass(DirtyClass.class)...???

d.setField("dirty now");
System.out.println(d.isDirty()); //Expecting true
Run Code Online (Sandbox Code Playgroud)

java bytecode byte-buddy

3
推荐指数
1
解决办法
2469
查看次数

SpringBoot 2.1.0 尝试集成数据库访问时抛出 ClassNotFoundException

我有一个简单的SpringBoot 2.1.0应用程序,并尝试使用JPA. spring-boot-starter-data-jpa一切都是通过“ ”依赖项设置的pom.xml,但是当我启动应用程序时,我得到了这个ClassNotFoundException

我已经尝试手动添加 byte-buddy 作为依赖项,但这没有任何改变。

有人已经解决这个问题了吗?

非常感谢您提前的每一个提示!

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: net/bytebuddy/matcher/ElementMatchers
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1745)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:576)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1083)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:853)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248)

Caused by: java.lang.NoClassDefFoundError: net/bytebuddy/matcher/ElementMatchers
at org.hibernate.bytecode.internal.bytebuddy.BytecodeProviderImpl.<clinit>(BytecodeProviderImpl.java:43)
at …
Run Code Online (Sandbox Code Playgroud)

java spring-data-jpa spring-boot byte-buddy

3
推荐指数
2
解决办法
5746
查看次数