Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ContextClassLoader not hooking

Tags:

java

I'm trying to define a custom ClassLoader.

public class ExampleLoader extends ClassLoader
{
    public Class<?> findClass(String name) throws ClassNotFoundException
    {
        System.out.println("This never gets printed");
        return super.findClass(name);
    }

    public Class<?> loadClass(String name, boolean b)
        throws ClassNotFoundException
    {
        System.out.println("This never gets printed");
        return super.loadClass(name, b);
    }
}

And of course my code to test it:

public class Tester
{
    public static void main(String[] args)
    {
        Thread t = new FooThread();
        t.setContextClassLoader(new ExampleLoader());
        t.start();
    }
}

class FooThread extends Thread
{
    public void run()
    {
        new RandomClass();
    }
}

The problem is that my lines never get printed. Clearly I'm missing something.

like image 488
Jim Avatar asked Aug 08 '10 03:08

Jim


1 Answers

This is related to bug 4868493. Here's a cite of relevance:

Unfortunately the documentation for getContextClassLoader and setContextClassLoader might lead one to the conclusion that the submitter's code should work as expected.

However, there is a basic rule in class loading - no class can ever automatically load a class which is "downstream", i.e. which cannot be directly loaded by that class' ClassLoader or one of its ancestor ClassLoaders.

This is described in a number of places. For example, meditate on the white paper available here: http://www.javageeks.com/Papers/ClassForName/index.html to gain enlightenment.

The key point seems to be that the context class loader is not used automatically by the Java language. It's only a conventional place to store the context class loader so that other classes can use it with the 3-argument form of Class.forName.

The spec for Thread.getContextClassLoader and Thread.setContextClassLoader should be clarified, and the meaning of "context class loader" should be clarified. Re-classifying as a doc bug.

The spec has not been clarified yet.

To get it to work what you initially want, replace new RandomClass() by

Class.forName(RandomClass.class.getName(), 
              true,
              getContextClassLoader()).newInstance();

This prints, contradictorily, the following:

This never gets printed
like image 109
BalusC Avatar answered Sep 30 '22 09:09

BalusC