[在某些情况下,我使用ByteBuddy子类化类时,出现IllegalAccessErrors。为什么?

问题描述 投票:1回答:1

((我是ByteBuddy的新用户。我使用的是ByteBuddy版本1.10.8和JDK 11,没有模块路径或模块系统的任何其他部分。)

我有一个这样声明的嵌套类:

public static class Frob {
  protected Frob() {
    super();
  }
  public String sayHello() {
    return "Hello!";
  }  
}

(其包含的类别为foo.bar.TestExplorations。]

当我创建一个名为Frob的动态子类foo.bar.Crap时,如下所示,一切正常,正如我期望的那样:

final String className = "foo.bar.Crap";
final DynamicType.Unloaded<?> dynamicTypeUnloaded = new ByteBuddy()
  .subclass(Frob.class)
  .name(className)
  .make();
final Class<?> mySubclass = dynamicTypeUnloaded
  .load(this.getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
  .getLoaded();
assertNotNull(mySubclass);
assertEquals(className, mySubclass.getName());
final Object frobSubclass = mySubclass.newInstance();
assertTrue(frobSubclass instanceof Frob);

但是如果我更改Frob的构造函数以使其为程序包私有,则从最终断言中会出现以下错误:

java.lang.IllegalAccessError: class foo.bar.Crap tried to access method 'void foo.bar.TestExplorations$Frob.<init>()' (foo.bar.Crap is in unnamed module of loader net.bytebuddy.dynamic.loading.ByteArrayClassLoader @5e3d57c7; foo.bar.TestExplorations$Frob is in unnamed module of loader 'app')

由于某种原因,即使Crapsuper()在同一程序包中,并且Crap被定义为程序包专用,Frob的构造函数也无法调用Frob()

我有一种责任感是JDK模块系统,尽管我故意(非常非常故意)不使用它。我知道模块系统不喜欢拆分包,这对我来说就像是在继续。是否有构造函数策略或其他机制来解决此问题?

byte-buddy
1个回答
0
投票

在Java中,只有同一个名称并且由相同的类加载器加载的包(与类相同)才等于另一个包。如果使用WRAPPER策略,则不能访问任何超类的程序包私有成员。 Byte Buddy不禁止生成,因为在Javac中这样做是合法的,但是您需要使用INJECTION策略来执行想要确保由相同的类加载器加载类的操作。请注意,它使用内部API,因此从Java 9开始,您宁愿使用ForLookup类加载策略。

© www.soinside.com 2019 - 2024. All rights reserved.