Why throwing an exception tries to loads the class which extends Exception (though it is not executed) but not a regular class
Asked Answered
L

1

9

I have the below classes.

I have manually compiled the classes using javac and ran the Driver class.

Later removed the entity.class and MyCustomException.class and ran the app like below.

java Driver test

The below error is complained about MyCustomException is missing but not about the Entity class. So, not clear why JRE complaining about MyCustomException class but not the Entity class.

Indeed I have removed code throw new MyCustomException(); but I did not encounter error about Entity class.

Caused by: java.lang.NoClassDefFoundError: com/techdisqus/exception/MyCustomException

Please note that the IF condition will NOT be executed as I am passing command argument as test

Why is it throwing an exception is causing to load the MyCustomException which would be never executed but the JVM does not load any other regular class unless condition is satisfied, as here Entity class here. Please check Driver.java below.

MyCustomException.java

public class MyCustomException extends RuntimeException {

}

Entity.java

public class Entity {
}

Driver.java

public class Driver {


    public static void main(String[] args) {

        String s = args[0];
        if("true".equals(s)){
            Entity entity = new Entity(); // This is not loaded, unless s is true
            throw  new MyCustomException(); // this is loaded even s is NOT true.
        }else{
            System.out.println("success");
        }
    }
}

enter image description here

Thanks for help

Lanai answered 21/2, 2019 at 14:10 Comment(3)
Something to try: get rid of Entity, it just obscures things. Then see if there is a difference between the error messages you get when you throw new MyCustomException() and simply call new MyCustomException() without throwing.Kunkel
@Arkadiy yes, it causes error while throw MyCustomException.. I think I would edit the question to make it clear.. and accepted answer answers this part.. I realised it has to do with throw not about creating object.Lanai
Yes indeed, please edit the question. The answer is great, it deserves the best question you can give it :)Kunkel
D
9

(this is an educated guess; I'm by no means an expert on JVM internals)

I assume the error happens during verification, when the loaded class undergoes some sanity checks so the runtime can make some assumptions later.

One of the checks is a typecheck of bytecode instructions. Specifically athrow:

An athrow instruction is type safe iff the top of the operand stack matches Throwable.

So at this point, the classloader has to load MyCustomException to check whether it extends Throwable

Deicer answered 21/2, 2019 at 15:54 Comment(3)
Exactly. But it’s important to keep in mind that this is an implementation specific behavior and other JVMs may handle this differently.Epicene
@Epicene you're probably right, but I don't see how the JVM spec I linked above leaves much wiggle room to avoid losing the exception class.Deicer
There’s some freedom regarding the point of verification. The HotSpot JVM does it when trying to enter the main method, but it could also do it earlier, when initializing the containing Driver class, or later, right before actually trying to execute the athrow instruction. On the other hand, the absence of the Entity class is only detected before actually trying to execute the new instruction, but another implementation could check this at method entry or even class initialization already.Epicene

© 2022 - 2024 — McMap. All rights reserved.