简体   繁体   中英

Load libs from a different classloader in a web application

When a web application is loaded in Tomcat it is loaded by a specific classloader, right?
I assume that all libraries (under WEB-INF\\lib ) used by this web application are all loaded by this same classloader?
In this case, is there a way to load a library under a different classloader without any issues?
The reason I want to do this is because Axis uses some configuration properties that are bound to the classloader and would like to do requests with different properties thereby use a different classloader.
Is this possible?

If you want to load classes programmatically at run time, you can use URLClassLoader, but it can be quite tricky to really get it right. You would do something like this:

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 */);

Then you should be able to create a new instance of this class and use it.

Edit: Here is a more concrete example, albeit not using Axis because it would be too difficult to set up. I have create a JAR file that contains the following class:

public class Hello {
    public Hello(String config) {

    }

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

I have copied this jar file to the source folder of my test project, so I can find it using UrlClassloaderTest.class.getResource("hello.jar") . In a web app, you should probably put it into WebContent/WEB-INF (or something similar) and use the method javax.servlet.ServletContext.getRealPath("WEB-INF/hello.jar") to find it. I can then access the Hello class using the URLClassLoader and reflection:

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);
    }
}

Note that I can not use Hello as a type here because it is not on the class path of the application, and so it is not known to the class loader of the class UrlClassLoaderTest !

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM