当Web应用程序以Tomcat加载时,它是由特定的类加载器加载的,对吗?
我假设此Web应用程序使用的所有库(在WEB-INF\lib下)都由同一类加载器加载吗?
在这种情况下,有没有办法在其他类加载器下加载库而不会出现任何问题?
我想这样做的原因是因为Axis使用绑定​​到类加载器的一些配置属性,并且希望使用不同的属性进行请求,从而使用不同的类加载器。
这可能吗?

最佳答案

如果要在运行时以编程方式加载类,则可以使用URLClassLoader,但要正确完成它可能非常棘手。您将执行以下操作:

URL[] urls = new URL[] {
    /* URL to your axis jar */,
    /* other URLs you need */
};
URLClassLoader classLoader = new URLClassLoader(urls, getClass().getClassLoader());
Class<...> axisClass = classLoader.findClass(/* fully qualified name */);

然后,您应该能够创建此类的新实例并使用它。

编辑:这是一个更具体的示例,尽管不使用Axis,因为它太难设置了。我创建了一个包含以下类的JAR文件:
public class Hello {
    public Hello(String config) {

    }

    public String getMessage() {
        return "Hello World";
    }
}

我已将此jar文件复制到测试项目的源文件夹中,因此可以使用UrlClassloaderTest.class.getResource("hello.jar")找到它。在Web应用程序中,您可能应该将其放入WebContent / WEB-INF(或类似内容)中,并使用javax.servlet.ServletContext.getRealPath("WEB-INF/hello.jar")方法进行查找。然后,我可以使用URLClassLoader和反射来访问Hello类:
public class UrlClassloaderTest {
    public static void main(String[] args) throws Exception {
        URL jarUrl = UrlClassloaderTest.class.getResource("hello.jar");
        URLClassLoader cl = new URLClassLoader(new URL[] { jarUrl }, UrlClassloaderTest.class.getClassLoader());

        Class helloClass = cl.loadClass("test.Hello");
        Constructor constructor = helloClass.getConstructor(String.class);
        Object helloObject = constructor.newInstance("some configuration");
        Method messageMethod = helloClass.getMethod("getMessage");
        String message = (String) messageMethod.invoke(helloObject);

        System.out.println(message);
    }
}

请注意,我不能在此处将Hello用作类型,因为它不在应用程序的类路径中,因此UrlClassLoaderTest类的类加载器不知道它!

09-11 19:12
查看更多