2012-11-14 23 views
2

當在Tomcat中加載Web應用程序時,它由特定的類加載器加載,對吧?
我假定這個Web應用程序使用的所有庫(在WEB-INF\lib下)都是由同一個類加載器加載的?
在這種情況下,有沒有辦法在不同的類加載器下加載一個庫而沒有任何問題?
我想這樣做的原因是因爲Axis使用了一些綁定到類加載器的配置屬性,並希望使用不同的屬性執行請求,從而使用不同的類加載器。
這可能嗎?從Web應用程序中的不同類加載器加載庫

回答

3

如果您想要在運行時以編程方式加載類,您可以使用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文件:

​​

我抄這個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); 
    } 
} 

請注意,我不能使用你好這裏一個類型,因爲它是不是應用程序的類路徑上,所以它是不知道類UrlClassLoaderTest的班加載器!

+0

如果我在Tomcat的網絡應用程序中執行此操作,會出現問題嗎? – Jim

+0

我希望不是:)你應該沒問題,你甚至可以用這種方法多次加載同一個jar。但請注意,由不同的類加載器加載的類不能一起工作,所以如我所說,要完全正確地實現這一點可能非常棘手。自從我上次不得不擺弄類加載器以來,也有相當長的一段時間,所以我不能保證任何東西...... –

+0

作爲示例還是很好的參考示例,是否可以提供更全面的代碼片段? – Jim

相關問題