类加载器和Apache Tomcat共享.jar文件

时间:2010-06-19 19:38:34

标签: java tomcat classloader

如果我的webapp和Tomcat之间需要共享的类(例如自定义域和主体),那么包含这些类的.jar文件应该放在哪里?

目前我将.jar放在$ {CATALINA_HOME} / lib中。从同一类型的类分配引用时,此结果是ClassCastException。这是一个例子:

MyCustomPrincipal principal = (MyCustomPrincipal)FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal();

上述方法抛出ClassCastException。该方法返回一个实际的MyCustomPrincipal类型(因为这是我的自定义领域在执行身份验证时为Tomcat提供的),显然是由不同的类加载器创建的。我如何解决这个问题,以便Tomcat和我的webapp都可以使用MyCustomPrincipal?

http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html

感谢任何帮助。 安德鲁

1 个答案:

答案 0 :(得分:4)

看起来你已经加载了2个副本,一个在tomcat中,一个在你的WEB-INF / lib jar或你部署的应用程序的其他类路径中。

您获得类路径异常的原因在于WAR查找类的方式。与普通的Java规则相反,战争首先在战争中查找类,然后才将请求传递给父类加载器。

类的标识依赖于类加载器,并且在1个类加载器中加载的同一个类在将其转换为另一个类加载器时会生成一个类转换异常。

解决方案是确保战争不包含容器应提供的类。如果您使用maven,您可以将这些依赖项标记为“已提供”,如果您使用ant,则必须将类路径列表拆分为2并对其进行编译,但仅使用构建战争所需的那些。