Sunday, February 23, 2020

Peril of reentrant defineClass: ClassCircularityError

Today I tried to make a Java application faster by eagerly loading a lot of classes into a classloader at once when the first of a set was requested. This did not work well. When the JVM loads a class in response to a defineClass call, it makes sure that there are no cycles in the inheritance hierarchy. This check is done immediately, requesting all parent classes from the classloader. If those haven't been loaded yet, my classloader would be called again (with the first defineClass call still on the call stack) and try to eagerly load a bunch of additional stuff. Apparently the JVM doesn't expect unrelated classes to be defined in this fallout from a defineClass call: if the next class defined isn't the next one up the inheritance hierarchy, a ClassCircularityError will be thrown even in the absence of actual circularity.

No comments:

Post a Comment