Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ByteBuddy未重新定义静态方法_Java_Bytecode_Byte Buddy - Fatal编程技术网

Java ByteBuddy未重新定义静态方法

Java ByteBuddy未重新定义静态方法,java,bytecode,byte-buddy,Java,Bytecode,Byte Buddy,我尝试使用ByteBuddy重新定义两种方法,如下所示: ClassLoader classLoader = ClassLoader.getSystemClassLoader(); ClassLoadingStrategy.Default classLoadingStrategy = ClassLoadingStrategy.Default.INJECTION; new ByteBuddy().redefine(CommandBase.class).method(returns(Item.cla

我尝试使用ByteBuddy重新定义两种方法,如下所示:

ClassLoader classLoader = ClassLoader.getSystemClassLoader();
ClassLoadingStrategy.Default classLoadingStrategy = ClassLoadingStrategy.Default.INJECTION;
new ByteBuddy().redefine(CommandBase.class).method(returns(Item.class)).intercept(MethodDelegation.to(CppItemInterceptor.class)).make().load(classLoader, classLoadingStrategy);
new ByteBuddy().redefine(CommandBase.class).method(returns(Block.class)).intercept(MethodDelegation.to(CppBlockInterceptor.class)).make().load(classLoader, classLoadingStrategy);
try {
    System.out.println(CppBlockInterceptor.getBlockByText(null, "1").getLocalizedName());
    System.out.println(CommandBase.getBlockByText(null, "1").getLocalizedName());
} catch (Exception e) {
    e.printStackTrace();
}

对CppBlockInterceptor的直接调用产生了预期的输出,但是对应该被替换的方法的调用仍然使用旧的行为。有什么原因吗?

您的
CommandBase
类在您有机会重新定义它之前已经加载了。如果不使用Java代理,Byte Buddy无法替换加载的类。尝试运行以下命令:

TypeDescription commandBase = new TypePool.Default.ofClassPath()
    .locate("my.package.CommandBase");
new ByteBuddy()
  .redefine(commandBase, ClassFileLocator.ForClassLoader.ofClassPath())
  .method(returns(Block.class)).intercept(MethodDelegation.to(CppBlockInterceptor.class))
  .make()
  .load(ClassLoader.getSystemClassLoader(), ClassLoadingStrategy.Default.INJECTOR);

CppBlockInterceptor.getBlockByText(null, "1").getLocalizedName()

在调用之前不显式引用
CommandBase
,它就会工作。不过,最好使用
AgentBuilder
和Java代理。被接受的答案不再是可编译的(这并不奇怪,因为5年多过去了)。使用Byte Buddy v1.10.17的正确代码如下:

TypeDescription typeDescription = TypePool.Default.ofSystemLoader()
    .describe("my.package.CommandBase")
    .resolve();
new ByteBuddy()
    .redefine(typeDescription, ClassFileLocator.ForClassLoader.ofSystemLoader())
    .method(returns(Block.class)).intercept(MethodDelegation.to(CppBlockInterceptor.class))
    .make()
    .load(ClassLoader.getSystemClassLoader(), ClassLoadingStrategy.Default.INJECTION);