4

I have come across eager loading in Java in two classes of Spring NestedRuntimeException and AbstractApplicationContext, both of these cases resolve the same Class loader issue using static code block, but the way they are used is confusing.

The confusion is regarding the call to ClassName.class.getName() in static code block, how does this resolve class loader issue.

static {
        // Eagerly load the ContextClosedEvent class to avoid weird classloader issues
        // on application shutdown in WebLogic 8.1. (Reported by Dustin Woods.)
        ContextClosedEvent.class.getName();
    }

If I were to do this same, I would get the class loader and load this class manually

Thread.currentThread()
.getContextClassLoader().loadClass(ContextClosedEvent.class.getName());

Any expert advice will be appreciated.

Reference

pcdhan
  • 87
  • 8
  • 4
    "Eager" just means that they load the class before it is really needed (normally the JVM would load it on first use). They do it here by having a `static` initializer that forces the class to be loaded by doing something (useless) with it. And it probably fixes the classloader issue because the thread classloader may be different when it is done lazily on first use. But I agree with you that it is a hack. – Thilo Jun 17 '19 at 11:22
  • i think this link help you, to get some knowledge [https://stackoverflow.com/a/2991015/6622913](https://stackoverflow.com/a/2991015/6622913) – Istiaque Hossain Jun 17 '19 at 11:50
  • 1
    FYI information, in your call, you will try to load the same class twice. – Antoniossss Jun 18 '19 at 06:45
  • @Thilo, It make sense, A call to a method will load the class, and using thread's class loader will throw checked exception which, they might want to avoid in static code block. – pcdhan Jun 18 '19 at 07:00

1 Answers1

4

In the first case, as bellow example, ContextClosedEvent will be loaded as soon as YourClass is used.

class YourClass {
    static {
        // Eagerly load the ContextClosedEvent class to avoid weird classloader issues
        // on application shutdown in WebLogic 8.1. (Reported by Dustin Woods.)
        ContextClosedEvent.class.getName();
    }
}

The second case, ContextClosedEvent will be loaded when your code is running, the loadClass method will be invoked 2 times. The first time is for ContextClosedEvent.class reference (invoked by JVM), the second time is your manual call.

The first time, ContextClosedEvent is actually loaded from class path. The second time, it depends on your ContextClassLoader. By default, JVM's class loader will findLoadedClass instead of load the class again.
As bellow example, loadClass method will be called twice when main method running.

class Main {
    public static void main(String[] args) throws ClassNotFoundException {
        Thread.currentThread()
            .getContextClassLoader().loadClass(ContextClosedEvent.class.getName());
    }
}

To see how static block works, run this example

class Main {
    public static void main(String[] args) {
        System.out.println("main method invoked");
    }
    static {
        System.out.println("static block invoked");
    }
}

Esc Điệp
  • 346
  • 2
  • 8
  • as you mention `findLoadedClass` is important here, it does not just load the class by invoking thread's class loader (second snippet), I confirmed this using VM args `-XX:+TraceClassLoading` – pcdhan Jun 18 '19 at 07:30