the virtual machine specification specifies the parent delegation mechanism of the classloader, but due to the problem of the runtime package (namespace), there is isolation, as mentioned in the book, but every class load will save a class file, but I run the custom class loader and load the java.lang.String
class many times, why there is no cache locally the second time, do I forget to rewrite that method?
related codes
public class MyClassLoader extends ClassLoader {
private static Path classDir = Paths.get("/Users/echo/");
public MyClassLoader() {
super();
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
byte[] classBytes = readClassBytes(name);
if (null == classBytes || classBytes.length == 0) {
throw new ClassNotFoundException("can not load the class " + name + ".");
}
return defineClass(name, classBytes, 0, classBytes.length);
}
private byte[] readClassBytes(String name) throws ClassNotFoundException {
String classPath = name.replace(".", File.separator);
Path classFullPath = classDir.resolve(Paths.get(classPath + ".class"));
if (!classFullPath.toFile().exists()) {
throw new ClassNotFoundException("the class " + name + " not found.");
}
try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
Files.copy(classFullPath, bos);
return bos.toByteArray();
} catch (IOException e) {
throw new ClassNotFoundException("load the class " + name + " occur error.", e);
}
}
@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
synchronized (getClassLoadingLock(name)) {
Class<?> c = findLoadedClass(name);
if (c != null) {
System.out.println(".");
}
if (c == null) {
long t0 = System.nanoTime();
try {
if (getParent() != null) {
c = getParent().loadClass(name);
if (c != null) {
System.out.println(".");
}
} else {
c = getSystemClassLoader().loadClass(name);
if (c != null) {
System.out.println(".");
}
}
} catch (ClassNotFoundException e) {
}
if (c == null) {
long t1 = System.nanoTime();
c = findClass(name);
if (c != null) {
System.out.println(".");
}
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
}
}
MyClassLoader classLoader = new MyClassLoader();
classLoader.loadClass("java.lang.String");
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
classLoader.loadClass("java.lang.String");