0

I'm trying to test that a class can be loaded to the jvm more then once but using different ClassLoader so my code tries to load a class (class name "Tzvika") twice first using the default ClassLoader and in the second try using the URLClassLoader
the problem is that i get the same reference for the URLClassLoader and the default ClassLoader what i'm doing wrong?

here code:

public static void main(String[] args) {
    Tzvika t1 = new Tzvika();
    System.out.println("t1 class loader: " + t1.getClass().getClassLoader());

    Tzvika t2 = null;
    try {
        URLClassLoader clsLoader = URLClassLoader.newInstance(new URL[] {new URL("file:/C://data/workspace/ashrait/tests/SampleClassLoader/bin/com/tzvika/sample/")});
        // same problem when i do this
        //URLClassLoader clsLoader = new URLClassLoader(new URL[] {new URL("file:/C://data/workspace/ashrait/tests/SampleClassLoader/bin/com/tzvika/sample/")});
        Class cls = clsLoader.loadClass("com.tzvika.sample.Tzvika");
        t2 = (Tzvika)cls.newInstance();
        System.out.println("t2 class loader: " + t2.getClass().getClassLoader());

    } catch (Exception e) {
        e.printStackTrace();
    }

}

here my console output:

t1 class loader: sun.misc.Launcher$AppClassLoader@1a52fdf
t2 class loader: sun.misc.Launcher$AppClassLoader@1a52fdf

1 Answers1

0

Create the URLClassLoader without a parent.

URLClassLoader clsLoader = URLClassLoader.newInstance(new URL[] {new URL("file:/C://data/workspace/ashrait/tests/SampleClassLoader/bin/com/tzvika/sample/")}, null);

Note also that you should specify the path to the root of the classpath, ie.

URLClassLoader clsLoader = URLClassLoader.newInstance(new URL[] {new URL("file:/C://data/workspace/ashrait/tests/SampleClassLoader/bin")});

To better clarify, the constructor of URLClassLoader states

The URLs will be searched in the order specified for classes and resources after first searching in the specified parent class loader.

So when you try to load a class from this ClassLoader, it will first check the parent ClassLoader, which is the bootstrap classloader, for the existence of that class. Since that parent class loader has already loaded a com.tzvika.sample.Tzvika class, it will return it.

Now, since the classes loaded by the parent class loader and your clsLoader are different, the instances of these classes therefore belong to different classes. So although you have com.tzvika.sample.Tzvika from both ClassLoaders, they are very much different.

That's the whole point of different ClassLoaders.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • Your answer work, but I noticed two additional issues that I would aprisiate your answer. 1. Why setting null in the parent? as I understand only the bootstrap's parent ClassLoader is null ? 2. Why am I getting ClassCastException while casting the object from cls.newInstance() to com.tzvika.sample.Tzvika – Tzvika Velich Oct 05 '14 at 05:51
  • @TzvikaVelich Yeah, I should have answered that earlier. I've edited with more details. Let me know if there's still something unclear. – Sotirios Delimanolis Oct 05 '14 at 05:59