自定义类加载器不能正常工作

时间:2015-07-21 08:15:21

标签: java classloader

我想在加载类之前编写自己的自定义类加载器来执行某些操作。如果我想调用的主类很简单,下面的代码可以正常工作。例如,如果调用的main方法只打印一些消息,那么它可以正常工作而不会出错。但是,如果它调用一些复杂的main方法,例如,'com.iisi.rest.Start'中的main方法将使用如下所示的jersey创建一个http服务器,那么它就失败了。

HttpServer server =   
HttpServerFactory.create("http://127.0.0.1:10987/rest");
server.start();

这不是我要加载的那些类的问题,因为如果我注释掉下面的代码并让findSystemClass()方法加载类,那么一切都会运行良好。

claz = defineClass(name, classData, 0, classData.length);

我已经搜索了很长一段时间的答案,但仍然无法弄明白......

public class MyClassLoader extends ClassLoader {
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static void main(String[] args) {
        MyClassLoader myLoader = new MyClassLoader();
        Class claz;
        String realArgs[] = new String[0];
        try {
            claz = myLoader.loadClass("com.iisi.rest.Start", true);
            // claz = myLoader.loadClass("com.iisi.practice.Test", true);
            Class[] mainArgs = { (new String[1]).getClass() };
            Method main = claz.getMethod("main", mainArgs);
            Object[] argsArray = { realArgs };
            main.invoke(null, argsArray);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    @SuppressWarnings({ "rawtypes" })
    public Class<?> loadClass(String name, boolean resolve)
            throws ClassNotFoundException {
        Class claz = null;
        claz = findLoadedClass(name);
        if (claz != null) {
            return claz;
        }
        try {
            byte[] classData = readFile(name);
            if (classData != null) {
                claz = defineClass(name, classData, 0, classData.length);
                if (claz != null) {
                    System.out.println(name + " is loaded by MyClassLoader");
                }
            }
        } catch (FileNotFoundException e) {
            System.out.println(e.getMessage());
        } catch (Exception e) {
            System.out.println(e.getMessage());
        } catch (ClassFormatError e) {
            System.out.println(e.getMessage());
        }
        if (claz == null) {
            claz = findSystemClass(name);
            if (claz != null) {
                System.out.println(name + " is loaded by system class loader");
            }
        }
        // check
        if (claz == null) {
            System.out.println(name + " failed");
        }
        if (resolve && claz != null) {
            resolveClass(claz);
        }
        return claz;
    }
}

以下是我的部分错误消息......

com.sun.jersey.localization.Localizable is loaded by MyClassLoader
com.sun.jersey.localization.Localizer is loaded by MyClassLoader
java.util.MissingResourceException is loaded by system class loader
java.util.Locale is loaded by system class loader
com.sun.jersey.localization.LocalizableMessage is loaded by MyClassLoader
java.util.ResourceBundle is loaded by system class loader
java.text.MessageFormat is loaded by system class loader
java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.iisi.formal.MyClassLoader.main(MyClassLoader.java:56)
Caused by: com.sun.jersey.spi.service.ServiceConfigurationError: com.sun.jersey.spi.container.WebApplicationProvider: The class com.sun.jersey.server.impl.container.WebApplicationProviderImpl implementing provider interface com.sun.jersey.spi.container.WebApplicationProvider could not be instantiated: Cannot cast com.sun.jersey.server.impl.container.WebApplicationProviderImpl to com.sun.jersey.spi.container.WebApplicationProvider
    at com.sun.jersey.spi.service.ServiceFinder.fail(ServiceFinder.java:602)
    at com.sun.jersey.spi.service.ServiceFinder.access$800(ServiceFinder.java:159)
    at com.sun.jersey.spi.service.ServiceFinder$LazyObjectIterator.hasNext(ServiceFinder.java:892)
    at com.sun.jersey.spi.container.WebApplicationFactory.createWebApplication(WebApplicationFactory.java:64)
    at com.sun.jersey.api.container.ContainerFactory.createContainer(ContainerFactory.java:160)
    at com.sun.jersey.api.container.ContainerFactory.createContainer(ContainerFactory.java:264)
    at com.sun.jersey.api.container.ContainerFactory.createContainer(ContainerFactory.java:246)
    at com.sun.jersey.api.container.httpserver.HttpServerFactory.create(HttpServerFactory.java:117)
    at com.sun.jersey.api.container.httpserver.HttpServerFactory.create(HttpServerFactory.java:92)
    at com.iisi.rest.Start.main(Start.java:47)
    ... 5 more
Caused by: java.lang.ClassCastException: Cannot cast com.sun.jersey.server.impl.container.WebApplicationProviderImpl to com.sun.jersey.spi.container.WebApplicationProvider
    at java.lang.Class.cast(Class.java:3176)
    at com.sun.jersey.spi.service.ServiceFinder$LazyObjectIterator.hasNext(ServiceFinder.java:851)
    ... 12 more    

0 个答案:

没有答案