标签: byte-buddy

我可以在同一个Maven项目的源文件中动态生成和引用类吗?

在Maven Build中,我使用字节代码生成库(Byte Buddy)动态生成一些Java类型.当然,这些类文件没有相应的源文件.这种方式只能生成几个类.该项目的大部分代码都是Java源代码.理想情况下,Java源代码将以静态方式引用生成的类型,而不是使用反射或运行时代码生成,这意味着类需要位于javac的编译类路径上.我是否可以在同一个Maven项目的编译类路径上获取生成的类,即没有单独的Maven项目和工件来保存包含源代码的Maven项目引用的生成的字节代码?

更新:我已经尝试将生成的类直接放入target/classesie project.build.outputDirectory,在Maven Build Lifecycle的早期,但它似乎不在类路径上.Maven编译器插件或 IDE 无法解析生成的类型.我还尝试使用Build Helper Maven插件在target包含生成的类的情况下添加一个额外的资源目录,然后自动将其复制到该目录中target/classes.该配置表现出相同的问题.

更新:我在GitHub上创建了一个完整的公共回购:https://github.com/mches/so-42376851

这是项目的Maven POM,我希望有静态类引用字节码增强类:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>demo</groupId>
        <artifactId>demo</artifactId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath>
    </parent>

    <artifactId>demo-enhanced</artifactId>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>generate-resources</phase>
                        <goals>
                            <goal>unpack</goal>
                        </goals>
                        <configuration>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>demo</groupId>
                                    <artifactId>demo-original</artifactId>
                                    <version>${project.version}</version>
                                    <overWrite>true</overWrite>
                                    <outputDirectory>${project.build.outputDirectory}</outputDirectory>
                                    <includes>**/*.class</includes>
                                    <excludes>META-INF/</excludes>
                                </artifactItem>
                            </artifactItems>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>net.bytebuddy</groupId>
                <artifactId>byte-buddy-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>process-resources</phase>
                        <goals>
                            <goal>transform</goal>
                        </goals>
                        <configuration> …
Run Code Online (Sandbox Code Playgroud)

java bytecode intellij-idea maven byte-buddy

14
推荐指数
1
解决办法
1616
查看次数

Mockito失败,内联的模拟启用了无效的参数名称异常

我启用了内联模拟,以便我可以模拟最终类,但现在我在使用Junit运行测试时遇到以下异常.

当我立即运行所有测试时,只有两个测试失败,但如果我单独运行测试,那么大多数测试都会失败.

我没有使用任何scala或android类(我知道).我正在使用lombok,但我尝试删除lombok注释任何它没有解决问题.

当删除mock-maker-inline时问题消失了,但我宁愿保留它.

我该如何解决这个问题?

org.mockito.exceptions.base.MockitoException: 
Mockito cannot mock this class: class com.example.MyClass.

If you're not sure why you're getting this error, please report to the mailing list.


Java               : 1.8
JVM vendor name    : Oracle Corporation
JVM vendor version : 25.112-b15
JVM name           : Java HotSpot(TM) 64-Bit Server VM
JVM version        : 1.8.0_112-b15
JVM info           : mixed mode
OS name            : Windows 10
OS version         : 10.0


You are seeing this disclaimer because Mockito is configured to …
Run Code Online (Sandbox Code Playgroud)

java junit mockito byte-buddy

11
推荐指数
2
解决办法
3671
查看次数

mock-maker-inline - 无法初始化内联 Byte Buddy 模拟制造商(power-mockito + jdk 8 + bytebuddy)

我正在使用 Powermockito 来模拟和监视静态类。版本:2.0.4

还使用mockito-core版本3.0.0。在我的一个项目中,我能够通过启用这里指定的 mock-maker-inline 来模拟静态 https://github.com/powermock/powermock-examples-maven/blob/master/mockito2/src/test/resources/ org/powermock/extensions/configuration.properties

但是,当我在另一个项目上尝试相同的方法时,遇到以下错误:

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.ghx.tpm.api.ISubscribedProductParameterService]: Factory method 'subscribedProductParameterService' threw exception; nested exception is java.lang.IllegalStateException: Could not initialize plugin: interface org.mockito.plugins.MockMaker (alternate: null)
Caused by: java.lang.IllegalStateException: Could not initialize plugin: interface org.mockito.plugins.MockMaker (alternate: null)
Caused by: java.lang.IllegalStateException: Failed to load interface org.mockito.plugins.MockMaker implementation declared in sun.misc.CompoundEnumeration@614aeccc
Caused by: java.lang.IllegalStateException: Failed to load MockMaker implementation: mock-maker-inline
Caused by: java.lang.IllegalStateException: Internal problem occurred, please report it. Mockito …
Run Code Online (Sandbox Code Playgroud)

byte-buddy powermockito

11
推荐指数
2
解决办法
1万
查看次数

如何在Java中实现包装装饰器?

问题是创建现有对象的动态增强版本.

我不能修改对象的Class.相反,我必须:

  • 它的子类
  • 将现有对象包装在新对象中 Class
  • 将所有原始方法调用委托给包装对象
  • 实现由另一个接口定义的所有方法

添加到现有对象的接口是:

public interface EnhancedNode {

  Node getNode();
  void setNode(Node node);

  Set getRules();
  void setRules(Set rules);

  Map getGroups();
  void setGroups(Map groups);

}
Run Code Online (Sandbox Code Playgroud)

有了Byte Buddy,我设法子类化并实现了我的界面.问题是委托给包装对象.我发现这样做的唯一方法是使用反射太慢(我对应用程序负载很重,性能很关键).

到目前为止我的代码是:

Class<? extends Node> proxyType = new ByteBuddy()
     .subclass(node.getClass(), ConstructorStrategy.Default.IMITATE_SUPER_TYPE_PUBLIC)
     .method(anyOf(finalNode.getClass().getMethods())).intercept(MethodDelegation.to(NodeInterceptor.class))
     .defineField("node", Node.class, Visibility.PRIVATE)
     .implement(EnhancedNode.class).intercept(FieldAccessor.ofBeanProperty())
     .defineField("groups", Map.class, Visibility.PRIVATE)
     .implement(EnhancedNode.class).intercept(FieldAccessor.ofBeanProperty())
     .defineField("rules", Set.class, Visibility.PRIVATE)
     .implement(EnhancedNode.class).intercept(FieldAccessor.ofBeanProperty())
     .make()
     .load(getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
     .getLoaded();
enhancedClass = (Class<N>) proxyType;
EnhancedNode enhancedNode = (EnhancedNode) enhancedClass.newInstance();
enhancedNode.setNode(node);
Run Code Online (Sandbox Code Playgroud)

Node子类/包装的对象在哪里.在NodeInterceptor被调用的方法前锋getNode财产.

这里的代码NodeInterceptor: …

java bytecode decorator byte-buddy

9
推荐指数
1
解决办法
1173
查看次数

Byte Buddy:为抽象类创建实现

我想在运行时为使用Byte Buddy的抽象类创建一个实现,我面临的问题java.lang.AbstractMethodError是,从创建的实例调用方法时会抛出a.我有一个abstract像这样的现有类(我实际上无法修改,实际上包含更多逻辑):

public abstract class Algorithm {
    abstract int execute();
}
Run Code Online (Sandbox Code Playgroud)

使用以下最小样本,我希望我的Algorithm实例返回一个常量值:

Class<?> type = new ByteBuddy()
                        .subclass(Algorithm.class)
                        .method(ElementMatchers.named("execute"))
                        .intercept(FixedValue.value(42))
                        .make()
                        .load(classLoader, ClassLoadingStrategy.Default.WRAPPER)
                        .getLoaded();
Algorithm instance = (Algorithm) type.newInstance();
System.out.println(myInstance.execute());
Run Code Online (Sandbox Code Playgroud)

然而,这会导致以下异常:

Exception in thread "main" java.lang.AbstractMethodError: package.Algorithm.execute()I
Run Code Online (Sandbox Code Playgroud)

(当我实验性地Algorithm改为a时interface,一切正常,但这并不能解决我的具体问题).

java bytecode interface class byte-buddy

9
推荐指数
1
解决办法
2403
查看次数

Byte-buddy:生成具有循环类型的类

我正在尝试生成具有循环类依赖性的类,类似于这个问题:Byte Buddy - 处理生成的类中的循环引用

作为一个最小的例子,我想要生成的类有这样的依赖:

//class A depends on class B, and vice-versa
final class A { B theB; }
final class B { A theA; }
Run Code Online (Sandbox Code Playgroud)

上面链接中接受的答案没有为我提供足够的信息来实现这一点.这是我试过的:

import net.bytebuddy.ByteBuddy;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
import net.bytebuddy.jar.asm.Opcodes;

public class ByteBuddyHello {

    public static void main(String[] args) {
        try {
            final ByteBuddy bb = new ByteBuddy();
            final TypeDescription.Latent typeDescrA = new TypeDescription.Latent("A", 0, null, null);
            final TypeDescription.Latent typeDescrB = new TypeDescription.Latent("B", 0, null, null);
            final DynamicType.Unloaded<Object> madeA = bb …
Run Code Online (Sandbox Code Playgroud)

java byte-buddy

9
推荐指数
1
解决办法
458
查看次数

显示生成的bytebuddy字节码

我正在使用ByteBuddy在运行时使用动态生成的字节代码创建一个类.生成的类执行它要执行的操作,但我想手动检查生成的字节代码,以确保它是正确的.

例如

Class<?> dynamicType = new ByteBuddy()
        .subclass(MyAbstractClass.class)
        .method(named("mymethod"))
        .intercept(new MyImplementation(args))
        .make()
        .load(getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
        .getLoaded();
Run Code Online (Sandbox Code Playgroud)

其中MyImplementation将多个StackManipulation命令链接在一起以创建动态生成的代码.

我可以将生成的类编写到文件中(因此我可以使用IDE手动检查),或者打印出生成的类的字节码吗?

java bytecode byte-buddy

8
推荐指数
2
解决办法
1222
查看次数

适用于Android Instrumentation测试的Mockito 2:无法初始化插件:接口org.mockito.plugins.MockMaker

我正在使用Mockito 2和Espresso进行单元测试,并且在尝试在Instrumentation测试中使用Mockito 2时遇到了问题。运行测试时,出现此错误

java.lang.IllegalStateException: Could not initialize plugin: interface org.mockito.plugins.MockMaker (alternate: null)
at org.mockito.internal.configuration.plugins.PluginLoader$1.invoke(PluginLoader.java:74)
at java.lang.reflect.Proxy.invoke(Proxy.java:913)
at $Proxy5.isTypeMockable(Unknown Source)
at org.mockito.internal.util.MockUtil.typeMockabilityOf(MockUtil.java:29)
at org.mockito.internal.util.MockCreationValidator.validateType(MockCreationValidator.java:22)
at org.mockito.internal.creation.MockSettingsImpl.validatedSettings(MockSettingsImpl.java:232)
at org.mockito.internal.creation.MockSettingsImpl.build(MockSettingsImpl.java:226)
at org.mockito.internal.MockitoCore.mock(MockitoCore.java:64)
at org.mockito.Mockito.mock(Mockito.java:1864)
at org.mockito.Mockito.mock(Mockito.java:1777)
at com.armop.insight.views.activity.InsightActivityTest.testUserResultReturnsEmpty(InsightActivityTest.kt:66)
at java.lang.reflect.Method.invoke(Native Method)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at android.support.test.internal.runner.junit4.statement.RunBefores.evaluate(RunBefores.java:80)
at android.support.test.rule.ActivityTestRule$ActivityStatement.evaluate(ActivityTestRule.java:433)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) …
Run Code Online (Sandbox Code Playgroud)

android mockito kotlin android-espresso byte-buddy

8
推荐指数
2
解决办法
4165
查看次数

在项目中使用mockito-inline会抛出“Mockito无法模拟此类”错误

我在我的项目中使用 Mockito 2.23.4 和 byte-buddy 1.9.3。我想模拟最终类和方法,所以我在这篇文章Mockito 模拟最终类和方法以及项目目录中的mock-maker-inline内部文件设置之后使用了mockito-inline 。我还跟进了Mockito 因无效参数名称异常而启用内联模拟而失败的帖子,但问题仍然存在。但是当我运行测试时,我得到下面的堆栈跟踪。org.mockito.plugins.MockMakersrc/test/resources/mockito-extensions

Java HotSpot(TM) 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended

Test ignored.

org.mockito.exceptions.base.MockitoException: 
Mockito cannot mock this class: class org.elasticsearch.client.RestHighLevelClient.

If you're not sure why you're getting this error, please report to the mailing list.


Java               : 15
JVM vendor name    : Oracle Corporation
JVM vendor version : 15.0.2+7-27
JVM name           : Java …
Run Code Online (Sandbox Code Playgroud)

java junit unit-testing mockito byte-buddy

8
推荐指数
1
解决办法
2万
查看次数

ByteBuddy代理接口

我正在尝试将Cglib代理转换为ByteBuddy.Cglib有net.sf.cglib.proxy.Proxy接口来拦截所有方法调用.我检查了ByteBuddy的文档但是找不到这样的例子.如果我没有用ByteBuddy实例化的每个对象都有这样的接口,我会再次重复同样的事情并且agin.使用ByteBuddy有更好的方法吗?

这是我的示例代码段:

服务:

public class MyService {

    public void sayFoo() {
        System.out.println("foo");
    }

    public void sayBar() {
        System.out.println("bar");
    }
}
Run Code Online (Sandbox Code Playgroud)

拦截器:

public class MyServiceInterceptor {

    public void sayFoo(@SuperCall Callable<Void> zuper) {
        try {
            zuper.call();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void sayBar(@SuperCall Callable<Void> zuper) {
        try {
            zuper.call();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

测试:

import net.bytebuddy.ByteBuddy;
import net.bytebuddy.ClassFileVersion;
import net.bytebuddy.dynamic.ClassLoadingStrategy;
import net.bytebuddy.instrumentation.MethodDelegation;
import net.bytebuddy.instrumentation.method.matcher.MethodMatchers;

public class Main {

    public static void …
Run Code Online (Sandbox Code Playgroud)

java reflection bytecode byte-buddy

7
推荐指数
1
解决办法
3159
查看次数