14

I'm loading classes using a custom class loader. For the most part, everything works, but sometimes when I load particularly complex projects/libraries, I get a strange bug:

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(...)

Looking at the Javadocs, I wouldn't expect defineClass to throw this particular error. org/apache/commons/codec/binary/Hex is the class I'm trying to load. It's almost as if defineClass wants a copy of the class before it'll define the class - which makes no sense to me.

Ideas?

Matthew Murdoch
  • 30,874
  • 30
  • 96
  • 127
Jim
  • 2,111
  • 4
  • 25
  • 34
  • 1
    Could you show your code? Did you just overwrite findClass() as recommended? Otherwise you have to be quite careful to get everything right. – Voo May 30 '11 at 18:41
  • *It's almost like define class wants a copy of the class before it'll define the class*, no it doesn't want a copy of the class. And how did you managed to define a package name `class`? – bestsss May 30 '11 at 19:12
  • @bestsss presumably the stack trace is just obfuscated with a poor choice of package names – Brett Kail May 31 '11 at 06:03
  • 1
    @bkail, I understand that, it was a sarcastic remark since the stack trace actually misses the important data of the cyclic referencing. – bestsss May 31 '11 at 12:56
  • 2
    @bestsss it is possible to use "class" in the package name by writing a class file directly. it seems the question you really wanted answered was: @Jim can you please provide the full stack trace? – Brett Kail May 31 '11 at 14:29

2 Answers2

17

A ClassCircularityError is thrown when some class is a (direct or indirect) superclass of itself, some interface (directly or indirectly) extends itself or similar.

This should normally not occur as a well-behaved compiler will not produce such classes, but using different versions of a library (or using several libraries containing different versions of a class) could bring this problem.

Scan your libraries for double class names, in particular have a look if there are multiple versions of the mentioned org.apache.commons.codec.binary.Hex class.

Paŭlo Ebermann
  • 73,284
  • 20
  • 146
  • 210
1

A ClassCircularityError is also thrown when an exception occurs during the definition of a class, for example when using a custom class loader.

The exception's type is misleading, but I think you can check the enclosed exception which should reflect what really happened.

(Full disclosure: I write my own class loaders.)

Here is an example:

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

Here, the StackOverflowError thrown inside my class loader is the actual cause of the problems. No class circularities were involved. Initially I was confused by the message too.

Stefan Reich
  • 1,000
  • 9
  • 12
  • I suspect that one of the main causes of a Stack Overflow in a class loader is a circular class definition, or at least this is what someone thought when catching this error and converting/wrapping it into a ClassCircularityErrror. – Paŭlo Ebermann Aug 18 '22 at 12:04
  • @PaŭloEbermann Yeah, very possible. Also, it then logically follows that we should rename this website to Class Circularity Errror. – Stefan Reich Aug 19 '22 at 13:57