【问题标题】:Load libs from a different classloader in a web application从 Web 应用程序中的不同类加载器加载库
【发布时间】:2012-11-14 06:47:25
【问题描述】:

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

【问题讨论】:

    标签: java tomcat web-applications classloader axis


    【解决方案1】:

    如果您想在运行时以编程方式加载类,您可以使用 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 的类加载器不知道它!

    【讨论】:

    • 如果我从Tomcat web-app 内部执行此操作会有问题吗?
    • 我希望不是 :) 你应该对这种方法没问题,你甚至可以通过这种方式多次加载同一个 jar。但请注意,由不同类加载器加载的类不能一起工作,所以正如我所说,要完全正确可能会很棘手。自从我上次不得不摆弄类加载器以来也已经很长时间了,所以我不能保证任何事情......
    • 能否提供更全面的代码sn-p作为例子或者很好的参考例子?
    • @Jim 我更新了我的帖子。如果您现在认为它有帮助,请接受答案和/或投票...
    • +1.So URLClassLoader 将在一个 不同 类加载器中加载类而不是我的网络应用程序?例如,它不会被委托给加载我的网络应用程序的 same 类加载器?
    猜你喜欢
    • 1970-01-01
    • 2018-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多