I have one question regarding concepts of class loading. How to load a .class file twice in JVM. I am also writing an excerpt of code that I have written to accomplish this.
Both classloaders start the lookup in their parent classloader (that's what the super()
call is about). So actually the super classloader loads it in both cases.
You can try this:
String pathToJar = "C:\\path\\to\\my.jar";
String className = "com.mypackage.ClassA";
URLClassLoader cl1 = new URLClassLoader(new URL[] { new URL(pathToJar) });
URLClassLoader cl2 = new URLClassLoader(new URL[] { new URL(pathToJar) });
Class<?> c1 = cl1.loadClass(className);
Class<?> c2 = cl2.loadClass(className);
System.out.println(c1);
System.out.println(c2);
System.out.println(c1==c2);
cl1.close();
cl2.close();
Make sure that my.jar
is NOT on your classpath.
In both cases you are using the same ClassLoader to perform the loading. You have two ClassLoaders but each just call super.loadClass() which delegates to the same parent ClassLoader which is AppClassLoader.
Try this
public class Test1 {
static class TestClassLoader1 extends ClassLoader {
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
if (!name.equals("Test1")) {
return super.loadClass(name);
}
try {
InputStream in = ClassLoader.getSystemResourceAsStream("Test1.class");
byte[] a = new byte[10000];
int len = in.read(a);
in.close();
return defineClass(name, a, 0, len);
} catch (IOException e) {
throw new ClassNotFoundException();
}
}
}
public static void main(String[] args) throws Exception {
Class<?> c1 = new TestClassLoader1().loadClass("Test1");
Class<?> c2 = new TestClassLoader1().loadClass("Test1");
System.out.println(c1);
System.out.println(c2);
System.out.println(c1 == c2);
}
}
output
class Test1
class Test1
false