gpt4 book ai didi

java - ByteBuddy - 重新调整 native 方法的基础

转载 作者:行者123 更新时间:2023-11-30 02:40:40 26 4
gpt4 key购买 nike

我正在检查是否可以使用 ByteBuddy 用更小、更优雅的解决方案替换一些庞大的 ASM 代码。其中一部分是“包装” native 方法,这意味着在类中为任何现有 native 方法添加前缀,并提供一个新的非 native 方法,该方法具有相同的名称和签名,调用前缀的方法。所有这些都可以在构建期间发生,因此我不需要任何代理,也不需要担心潜在的类架构更改等

从文档来看,这似乎是一个 rebase 案例,其中 ByteBuddy 留下原始方法的副本,并提供通过 @SuperCall 调用它的可能性。

除了无法影响原始方法的新名称(它们需要有前缀,而不是后缀)之外,以下代码还会导致以下错误:

        new ByteBuddy()
.rebase(typePool.describe("test.ClassWithNatives").resolve(), ClassFileLocator.ForClassLoader.ofClassPath())
.method(named("someNativeMethod"))
.intercept(MethodDelegation.to(NativeInterceptor.class))
.make()
.load(getClass().getClassLoader())
.getLoaded();

.

Exception in thread "main" java.lang.IllegalStateException: Error invoking java.lang.ClassLoader#findClass
at net.bytebuddy.dynamic.loading.ClassInjector$UsingReflection$Dispatcher$Direct.defineClass(ClassInjector.java:410)
at net.bytebuddy.dynamic.loading.ClassInjector$UsingReflection.inject(ClassInjector.java:183)
at net.bytebuddy.dynamic.loading.ClassLoadingStrategy$Default$InjectionDispatcher.load(ClassLoadingStrategy.java:187)
at net.bytebuddy.dynamic.loading.ClassLoadingStrategy$Default.load(ClassLoadingStrategy.java:120)
at net.bytebuddy.dynamic.TypeResolutionStrategy$Passive.initialize(TypeResolutionStrategy.java:79)
at net.bytebuddy.dynamic.DynamicType$Default$Unloaded.load(DynamicType.java:4376)
at net.bytebuddy.dynamic.DynamicType$Default$Unloaded.load(DynamicType.java:4366)
at ByteBuddyTest.wrapNatives(ByteBuddyTest.java:45)
at ByteBuddyTest.start(ByteBuddyTest.java:22)
at ByteBuddyTest.main(ByteBuddyTest.java:16)
Caused by: java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file ClassWithNatives
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at net.bytebuddy.dynamic.loading.ClassInjector$UsingReflection$Dispatcher$Direct.defineClass(ClassInjector.java:406)
... 9 more

用ByteBuddy可以实现这样的场景吗?

最佳答案

这只能通过 Instrumentation 使用 Java 代理来实现。否则,JVM 不知道如何对具有必须遵循方法命名约定的 native 适配器的 native 方法进行 rebase 。为了使 Byte Buddy 工作,原始代码被移动到一个不同的方法,以便从原始方法调用,否则这是不可能的。

使用 Java 代理,可以运行:

new AgentBuilder.Default()
.enableNativeMethodPrefix("foo")
.type(named("test.ClassWithNatives"))
.transform((b,t,c,m) -> b
.method(named("someNativeMethod"))
.intercept(MethodDelegation.to(NativeInterceptor.class))
).installOn(inst);

关于java - ByteBuddy - 重新调整 native 方法的基础,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41817982/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com