Does ClassLoader.resolveClass() actually do anything?

Viewed 71

This is the definition of java.lang.ClassLoader.resolveClass(Class) in OpenJDK 20+10:

    protected final void resolveClass(Class<?> c) {
        if (c == null) {
            throw new NullPointerException();
        }
    }

It appears to be doing nothing except checking that the argument is non-null. And yet, the doc comment claims:

    /**
     * Links the specified class.  This (misleadingly named) method may be
     * used by a class loader to link a class.  If the class {@code c} has
     * already been linked, then this method simply returns. Otherwise, the
     * class is linked as described in the "Execution" chapter of
     * <cite>The Java Language Specification</cite>.

Does calling this method actually do anything useful? Since it is final, subclasses cannot override it to make it do anything different. Is it literally a does-nothing-except-null-check method, or does the JVM somehow magically intercept its invocation and do something more?

1 Answers

Does calling this method actually do anything useful?

In Java 8 this method called a native method resolveClass0. I haven't looked at the Java 8 native method's implementation. It might already have been a no-op.

From Java 9 onwards it simply checks that the argument c is not null. So ... now, the answer is clearly No.

There were significant changes to the implementations of classloaders between Java 8 and 9 (see https://www.oracle.com/java/technologies/javase/9-all-relnotes.html). This were due in part to the need to support Java 9 modules.

My guess is that the Java 9 classloader changes made the resolveClass method either redundant or unhelpful . But rather than causing rework for people with custom classloaders, the Java team simply turned the method into a no-op.

Anyhow, the javadoc comment says:

Links the specified class. This (misleadingly named) method may be used by a class loader to link a class. If the class c has already been linked, then this method simply returns. Otherwise, the class is linked as described in the "Execution" chapter of "The Java Language Specification".

I can think of two possible explanations for making the method a no-op now:

  1. In current (Java 9+) classloader implementations, the class could always have been linked earlier, making the call redundant.

  2. They have decided that a custom classloader should no longer be allowed to decide when the class should be linked.

    • Maybe it caused complications that would be difficult to deal with in the updated classloader implementations?
    • Maybe it was thought to be a flaw in the original design?
Related