我得到了java.lang.ClassCastException: CustomloaderDependency cannot be cast to CustomloaderDependency
我知道原因是两个类由不同的类加载器加载(一个由customclassloader
加载,另一个默认为sun.misc.Launcher$AppClassLoader
)
我的自定义类加载器即使在使用-Djava.system.class.loader=CustomClassLoader
运行程序后也没有被使用,除非我没有明确地执行Class.forName("CustomloaderDependency", true, ClassLoader.getSystemClassLoader() );
但是当我执行new CustomloaderDependency() default sun.misc.Launcher$AppClassLoader is used
这是我的自定义类加载器
public class CustomClassLoader extends ClassLoader {
public CustomClassLoader() {
super();
}
/**
* This constructor is used to set the parent ClassLoader
*/
public CustomClassLoader(ClassLoader parent) {
super(parent);
}
/**
* Loads the class from the file system. The class file should be located in
* the file system. The name should be relative to get the file location
*
* @param name
* Fully Classified name of class, for example com.journaldev.Foo
*/
private Class getClass(String name) throws ClassNotFoundException {
String file = name + ".class";
byte[] b = null;
try {
// This loads the byte code data from the file
b = loadClassFileData(file);
// defineClass is inherited from the ClassLoader class
// that converts byte array into a Class. defineClass is Final
// so we cannot override it
Class c = defineClass(name, b, 0, b.length);
resolveClass(c);
return c;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
/**
* Every request for a class passes through this method. If the class is in
* com.journaldev package, we will use this classloader or else delegate the
* request to parent classloader.
*
*
* @param name
* Full class name
*/
@Override
public Class loadClass(String name) throws ClassNotFoundException {
System.out.println("Loading Class '" + name + "'" );
if (name.contains("CustomloaderDependency") || name.contains("TestCustomLoader")) {
System.out.println("Loading Class using CustomClassLoader");
return getClass(name);
}
return super.loadClass(name);
}
/**
* Reads the file (.class) into a byte array. The file should be
* accessible as a resource and make sure that its not in Classpath to avoid
* any confusion.
*
* @param name
* File name
* @return Byte array read from the file
* @throws IOException
* if any exception comes in reading the file
*/
private byte[] loadClassFileData(String name) throws IOException {
/*InputStream stream = ClassLoader.getSystemClassLoader().getResourceAsStream(
name);*/
// FileInputStream stream = new FileInputStream("F:\\workspaces\\test\\Test\\bin\\"+name);
FileInputStream stream = new FileInputStream("F:\\"+name);
int size = stream.available();
byte buff[] = new byte[size];
//DataInputStream in = new DataInputStream(stream);
stream.read(buff);
stream.close();
return buff;
}
}
这是我的测试类
我正在使用-Djava.system.class.loader=CustomClassLoader
运行此程序,但仍然看起来默认的类加载器用于我尝试使用
public class TestCustomLoader {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Class classObject = Class.forName("CustomloaderDependency", true, ClassLoader.getSystemClassLoader() );
Object customloaderDependency = classObject.newInstance();
System.out.println("classloader from my custom is "+customloaderDependency.getClass().getClassLoader());
// above prints CustomClassLoader@15db9742
System.out.println("classloader for casting is "+CustomloaderDependency.class.getClassLoader());
// above prints sun.misc.Launcher$AppClassLoader@14dad5dc
CustomloaderDependency finalObject = (CustomloaderDependency)customloaderDependency;
//above line i am getting exception
}
答案 0 :(得分:0)
我的工作是
@Override
public Class loadClass(String name) throws ClassNotFoundException {
System.out.println("Loading Class '" + name + "'" );
if (name.contains("CustomloaderDependency") || name.contains("TestCustomLoader")) {
System.out.println("Loading Class using CustomClassLoader");
return getClass(name);
}
return super.loadClass(name);
}
在上述修复之前,我的customclassloader正在调用加载TestCustomLoader
,但由于Launcher$AppClassLoader
我正在通过if (name.contains("CustomloaderDependency") ) {
加载它。
因此,所有它的依赖(如静态提到的类,即演员括号中的单词)也由Launcher$AppClassLoader
加载