Search code examples
javaclassloader

Java ClassLoader: findClass is not called again after ClassNotFoundException occurs


Context: I have a microservice that at application BootStrap goes and gets all the classes it needs from another microservice as a Zip, then it loads all the classes this Zip contains and executes some code.

Problem:

What we are experiencing is that in some cases the service that gives the Zip with the classes does not answer (this is not the problem I want to address here).

The problem is that when this happens we throw a ClassNotFoundException and execute again and in this execution the programm again detects it needs to load a class it does not have... So it goes to the findClass() method and tries to get it by calling the Microservices asking for this class, but the service that gives the Zip with the class again does not respond so we throw another ClassNotFoundException... And again execute but this time it does not even try to call findClass() method, it is like Java is saying "okay this is definetely not here so im not even going to bother calling findClass()", I am trying to find where in the documentation is this specified (because I wanna see where is this specified, is it normal?).

Oracle Documentation ClassLoader

The closest I could find to what I experience is this

But in that case they do have the class, but the loader does not bother in loading it again because it detects it already has it, we are experiencing the same but in reverse, the loader does not have it, and it does not bother in trying again. Where is this in the docs?


Solution

  • Actually, the absence of a guaranty that multiple resolution attempts will be made is already enough to allow the behavior of remembering and reusing the result of the first symbol resolution attempt, whether it is a failure or success.

    But it’s even mandated behavior, as specified in The Java Virtual Machine Specification, §5.4.3. Resolution:

    Subsequent attempts to resolve the symbolic reference always fail with the same error that was thrown as a result of the initial resolution attempt.

    This is not be confused with manual invocations of loadClass on a ClassLoader instance.