私は次の操作を実行しようとしたとき、私はロード・コールで例外を取得:MethodDelegationまたはForwardingでByte Buddyプロキシを作成するには?
Field datasourceExtensionField = Grid.class.getDeclaredField("datasourceExtension");
datasourceExtensionField.setAccessible(true);
RpcDataProviderExtension rpcDataProviderExtension = (RpcDataProviderExtension) datasourceExtensionField.get(grid);
Field activeItemHandlerField = RpcDataProviderExtension.class.getDeclaredField("activeItemHandler");
activeItemHandlerField.setAccessible(true);
Object activeItemHandler = activeItemHandlerField.get(rpcDataProviderExtension);
Field keyMapperField = activeItemHandler.getClass().getDeclaredField("keyMapper");
keyMapperField.setAccessible(true);
KeyMapper original = (KeyMapper) keyMapperField.get(activeItemHandler);
KeyMapper wrapper = new ByteBuddy() //
.subclass(KeyMapper.class) //
.defineField("original", KeyMapper.class, Visibility.PUBLIC) //
.method(ElementMatchers.any()) //
.intercept(Forwarding.toField("original")) //
.method(ElementMatchers.named("get")) //
.intercept(MethodDelegation.to(new KeyMapperWrapper(grid, original))) //
.make() //
.load(KeyMapperWrapper.class.getClassLoader()) //
.getLoaded() //
.newInstance();
// give wrapper the reference to the original
wrapper.getClass().getDeclaredField("original").set(wrapper, original);
// replace original with wrapper
keyMapperField.set(activeItemHandler, wrapper);
例外:
java.lang.VerifyError: Bad access to protected data in invokevirtual
Exception Details:
Location:
com/vaadin/server/KeyMapper$ByteBuddy$WlWljaQa.clone()Ljava/lang/Object; @4: invokevirtual
Reason:
Type 'com/vaadin/server/KeyMapper' (current frame, stack[0]) is not assignable to 'com/vaadin/server/KeyMapper$ByteBuddy$WlWljaQa'
Current Frame:
bci: @4
flags: { }
locals: { 'com/vaadin/server/KeyMapper$ByteBuddy$WlWljaQa' }
stack: { 'com/vaadin/server/KeyMapper' }
Bytecode:
0x0000000: 2ab4 000c b600 1cb0
at java.lang.Class.getDeclaredFields0(Native Method)
at java.lang.Class.privateGetDeclaredFields(Class.java:2583)
at java.lang.Class.getDeclaredField(Class.java:2068)
at net.bytebuddy.implementation.LoadedTypeInitializer$ForStaticField.onLoad(LoadedTypeInitializer.java:101)
at net.bytebuddy.implementation.LoadedTypeInitializer$Compound.onLoad(LoadedTypeInitializer.java:180)
at net.bytebuddy.dynamic.TypeResolutionStrategy$Passive.initialize(TypeResolutionStrategy.java:75)
at net.bytebuddy.dynamic.DynamicType$Default$Unloaded.load(DynamicType.java:4525)
at net.bytebuddy.dynamic.DynamicType$Default$Unloaded.load(DynamicType.java:4514)
at test.KeyMapperWrapper.patch(KeyMapperWrapper.java:62)
私は明らかにForwarding
が動作するようになっているか理解していないよ、何午前私は間違っている?
私の意図は、既存のKeyMapper
を1つの単一の方法をに上書きするプロキシに置き換え、残りを元に委譲することです。
編集:私は今も同じ例外がスローされ、MethodDelegation
で試してみました:
.method(ElementMatchers.any()) //
.intercept(MethodDelegation.to(original)) //
.method(ElementMatchers.named("get")) //
.intercept(MethodDelegation.to(new KeyMapperWrapper(grid, original))) //
ありがとうございました!私がサブクラス化しようとしているのはpublicメソッドしかないので、合法ではありませんか?しかし、私が必要とする次のプロキシは、すべてのパブリックメソッドを持っていない可能性がありますので、おそらくInvocationHandlerAdapterを使用する方がよいでしょうか? (呼び出す前にmethod.setAccessible(true)を使用します) – Zalumon
'Object'からメソッドを継承します。問題のある問題のメソッドは、検証者のエラーからわかるように 'Object :: clone'でした。 –
私は、ありがとう!私はInvocationHandlerAdapterアプローチに固執すると思います。 – Zalumon