【问题标题】:ClassCircularityError thrown by ClassLoader.defineClassClassLoader.defineClass 抛出的 ClassCircularityError
【发布时间】:2011-05-30 18:20:06
【问题描述】:

我正在使用自定义类加载器加载类。在大多数情况下,一切正常,但有时当我加载特别复杂的项目/库时,我会遇到一个奇怪的错误:

Exception in thread "main" java.lang.ClassCircularityError: 
  org/apache/commons/codec/binary/Hex
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:466)
    at my.custom.class.Loader.loadClass(...)

查看 Javadocs,我不希望 defineClass 抛出这个特定的错误。 org/apache/commons/codec/binary/Hex 是我要加载的类。就好像defineClass 在定义类之前想要一个类的副本——这对我来说毫无意义。

想法?

【问题讨论】:

  • 你能展示你的代码吗?您是否按照建议覆盖了 findClass() ?否则,你必须非常小心才能把所有事情都做好。
  • 就像定义类在定义类之前想要一个类的副本,不,它不想要类的副本。你是如何定义包名class的?
  • @bestsss 大概堆栈跟踪只是因为包名称选择不当而混淆了
  • @bkail,我明白,这是一个讽刺的评论,因为堆栈跟踪实际上错过了循环引用的重要数据。
  • @bestsss 可以通过直接编写类文件在包名中使用“类”。看来您真正想要回答的问题是:@Jim 你能提供完整的堆栈跟踪吗?

标签: java circular-dependency classloader


【解决方案1】:

当某个类是其自身的(间接)超类、某个接口(间接)扩展自身或类似时,将抛出 ClassCircularityError

这通常不会发生,因为行为良好的编译器不会生成此类类,但使用不同版本的库(或使用包含不同版本类的多个库)可能会带来此问题。

扫描您的库以查找双重类名,特别是查看是否存在上述org.apache.commons.codec.binary.Hex 类的多个版本。

【讨论】:

    【解决方案2】:

    在定义类期间发生异常时也会引发 ClassCircularityError,例如在使用自定义类加载器时。

    异常的类型具有误导性,但我认为您可以检查包含的异常,它应该反映实际发生的情况。

    (完全披露:我编写自己的类加载器。)

    这是一个例子:

    java.lang.StackOverflowError
        at java.base/java.lang.LinkageError.<init>(LinkageError.java:55)
        at java.base/java.lang.ClassCircularityError.<init>(ClassCircularityError.java:53)
    

    在这里,我的类加载器中抛出的 StackOverflowError 是问题的实际原因。没有涉及班级循环。一开始我也被这条消息弄糊涂了。

    【讨论】:

      猜你喜欢
      • 2011-02-09
      • 1970-01-01
      • 1970-01-01
      • 2023-01-23
      • 2015-12-30
      • 2012-06-12
      • 1970-01-01
      • 1970-01-01
      • 2013-05-24
      相关资源
      最近更新 更多