CustomloaderDep无法强制转换为CustomloaderDep?

时间:2015-12-26 17:44:22

标签: java classloader

我得到了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


        }

1 个答案:

答案 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加载