5

I am not clear on the following:
A class is loaded by JVM when needed, like lazy initialization, right?
Now if class A does an import of class B which class B actually is not in the file system (e.g. B.class was deleted or not delivered or any reason)
then does class A get loaded and runs if no method of class B is called?
Or class A is not able to run at all since the imports can not be resolved?
Or class A is loaded and run up to a certain point?

Jim
  • 18,826
  • 34
  • 135
  • 254

3 Answers3

8

import statement is only important for the compiler. In bytecode all references to other classes are fully qualified. That's why superflous imports don't matter at runtime.

In your case JVM will try to load all classes that are required to load and verify A, so it will try to load B immediately, but dependant classes are loaded lazily only when they are needed. Check out the following example:

public class A {

    public static void bar() {
        new B().foo();
    }

    public static void main(String[] args) {
        //bar();
    }

}

Compile A.java and delete B.class. Without calling bar() method your program will run just fine. But once you uncomment piece of code actually using B class you'll get nasty:

Exception in thread "main" java.lang.NoClassDefFoundError: B
    at A.bar(A.java:4)
    at A.main(A.java:8)
Caused by: java.lang.ClassNotFoundException: B
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
    ... 2 more

If B is not available, you'll get NoClassDefFound or similar.

Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
  • So this will happen trying to resolve the `imports`?Right. Right on constructing class `A`? – Jim Sep 26 '12 at 07:22
  • 2
    @Jim: No, JVM is **not** resolving any imports, imports are read and discarded during compilation. They don't exist in bytecode. In `.class` file all classes are fully qualified. – Tomasz Nurkiewicz Sep 26 '12 at 07:34
  • 2
    +1 I love it when to go to great length and in detail to explain exactly why "issue X" could not ever be a problem and they come back with; so its a real problem then. LOL. – Peter Lawrey Sep 26 '12 at 08:03
  • @TomaszNurkiewicz:In your code I assume that you forgot the `import` for class `B`? – Jim Sep 26 '12 at 12:28
  • 1
    @Jim: I was testing this in the same package, so no import was necessary. Feel free to use the same test code, but in different packages. But I guarantee that the results will be the same. – Tomasz Nurkiewicz Sep 26 '12 at 12:29
  • So my understanding is correct.As long as a method/class is not directly used, no runtime issue occurs.Right? – Jim Sep 26 '12 at 12:36
  • @Jim: initially I thought that classes are loaded eagerly, but my test above proves you are right. – Tomasz Nurkiewicz Sep 26 '12 at 12:40
0

If A.class require B.class which is missing. A.class can not be loaded.

Loading class is a recursion operation.

When A.class require B.class, the JVM search B.class in PermGen. If B.class is loaded and store in PermGen, JVM will not reload the B.class but get it from PermGen directly, otherwrise the JVM will load B.class recursively.

When JVM can not find B.class, it throw NoClassDefFoundError.

See more about NoClassDefFoundError in [Java Specification] :page 319.

lichengwu
  • 4,277
  • 6
  • 29
  • 42
0

You will get NoClassDefFoundError when you call the method that uses the definition of B.class. This will cause the class loader to search for B.class and load it in memory.

AFAIK there is one exception to this rule, Annotations. When you have an annotation that cannot be found at run time it will be ignored in some cases, see: Why doesn't a missing annotation cause a ClassNotFoundException at runtime?

janst
  • 102
  • 10