Java,自定义类加载器的问题

时间:2011-11-01 15:38:06

标签: java spring classloader

我正在编写一个自定义类加载器来加载我的一些类(不是全部)。

类加载器非常简单:

public Class loadClass(String className, boolean resolve) throws ClassNotFoundException {
    Class cls=findLoadedClass(className);
    if(cls!=null) {
        return cls;
    }
    // Search first for encrypted classes
    cls=decryptClass(className);
    if(cls==null) {
        // Then try with default system classloader
        cls=super.loadClass(className, resolve);
    }
    return cls;
}

这就是我使用它的方式:

// In my Launcher class
public static void main(String[] args) {
    MyClassLoader loader=new MyClassLoader();
    try {
        final Class main=loader.loadClass("com.MyAppMain");
        Method toInvoke=main.getMethod("main", args.getClass());
        toInvoke.invoke(main, new Object[]{args});
    }
    catch(Exception ex) {
    }
}

我的小测试项目似乎都没问题,但是当我在我的大项目中使用这个加载器(使用spring + hibernate和IoC的客户端 - 服务器应用程序)时不起作用。 我的类加载器中没有特殊例外,但是例如,新的Socket实例抛出“java.net.ConnectException:Connection refused”而没有真正的原因......

其他问题是我的主要形式不可见......以及其他类似的奇怪问题。

所以,问题是,我的类加载器导致的这些问题是以不同的方式加载不同类的类吗?


编辑1

我的项目使用spring,所以我使用@Autowired或有时

springApplicationContext.getBean(clazz);

注入一个bean。

问题是,如果这些类是加密的,那么spring无法找到我的bean(所以它们需要由我的类加载器加载)。 这个错误有一个解决方法吗? 感谢。


编辑2

我已经在Spring ClassPathXmlApplicationContext中设置了我的类加载器,现在我注意到spring使用我的类加载器来加载bean类,但是尽管如此它会抛出一个org.springframework.beans.factory.NoSuchBeanDefinitionException因为它找不到bean ...什么可以我做? 感谢

2 个答案:

答案 0 :(得分:0)

我看到两件可能值得研究的事情:

  • 代码使类加载器为parent-last。总是存在这会导致细微的类加载问题的风险。
  • 可能只是线程上下文类加载器没有正确设置。

答案 1 :(得分:0)

我不是很擅长类加载器,但是从代码中可以假设,如果你的类加载器找不到类,它将重定向到系统类加载器。当你运行应用程序独立时,它可能正常工作,就像你的样本一样,但如果它是在应用程序服务器上运行的web应用程序,它将失败。

应用程序服务器通常会创建类加载器的大型层次结构,并且具有用于加载应用程序类的单独的类加载器。在这种情况下,系统类加载器对您的Spring相关类一无所知,因此无法加载它们。

你必须记住,同一个类可能被几个类加载器加载,如果你试图比较来自不同类加载器的同一个类,它将会失败。

在你的情况下,我将在MyClassLoader构造函数中设置父类加载器。作为父类加载器,我认为你可以使用MyClassLoader.class.getClassLoader()。

public class MyClassLoader extends ClassLoader
{
    public MyClassLoader()
    {
       super(MyClassLoader.class.getClassLoader());
    }

    // other code
}

希望这可能有所帮助:)