更改方法

时间:2016-12-02 21:42:53

标签: java byte-buddy

是否有可能(只是)用Byte Buddy改变某些方法的可见性?我有一个带有私有静态方法的用户类,我需要委托对这些方法进行一些调用,但它目前因为它们是私有的而失败。所以,我想知道我是否可以通过添加公共修饰符来转换上述方法来重新定义用户类。

对于记录,在目标Java方法上调用setAccessible(true)方法不起作用,因为Byte Buddy仍然失败并出现以下异常:

java.lang.IllegalStateException: class net.bytebuddy.renamed.java.lang.Object$ByteBuddy$VHdvjIkb cannot see private java.lang.String org.mockaccino.MockaccinoTest.lambda$3() throws java.lang.Exception
at net.bytebuddy.implementation.MethodCall$MethodInvoker$ForContextualInvocation.invoke(MethodCall.java:2387)
...

我发现了一些可以解决问题的API,但我需要检测方法,这在我的案例中是不需要的。

例如:

byteBuddy.redefine(targetClass)
  .method(ElementMatchers.named(targetMethod.getName()))
  .intercept(???)
  .transform(Transformer.ForMethod.withModifiers(Visibility.PUBLIC))
  .make()
  .load(getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());

我的问题是:是否有一个拦截器能够调用正在重新定义的源方法体?

或者是否有其他方法可以使目标方法公开显示?

1 个答案:

答案 0 :(得分:2)

重新定义方法的修饰符不适用于已加载的类。 JVM拒绝任何添加/删除方法或更改任何方法属性的重新定义,例如它的修饰语。

为了使方法公开,您需要应用重组,而不是重新定义,您可以通过SuperMethodCall.INSTANCE来设置方法。需要在第一次加载相关类之前应用此转换。