1

我正在开发一个 java web 应用程序,它部署在tomcat 7. 我Maven, Spring, spring security 3.0.5.RELEASE and JSF在这个应用程序中使用。

我想将 spring 和 jsf jar 文件放入CATALINA_HOME/lib,因为我也在其他应用程序中使用它们。现在我的战争文件中有大部分这些罐子。

我为从战争文件中分离罐子所做的步骤如下:

  1. 在中添加<scope>provided</scope> tag依赖项pom.xml
  2. 将jar文件放入CATALINA_HOME/lib

当我为 JSF jar 执行这些步骤时,一切正常。
但是当我对 spring 和 spring security jars 执行相同操作时,应用程序没有启动并抛出错误。

例如:如果我将<scope>provided</scope>标签添加到以下依赖项,我的应用程序将停止工作并引发Caused by: java.lang.ClassNotFoundException: org.springframework.core.io.Resource异常:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>${spring.version}</version>
</dependency>

请在此处查看完整的堆栈跟踪,并在此处查看pom.xml

如何使我的 webapp 与 CATALINA_HOME/lib 中的 spring jars 位置一起使用?

4

2 回答 2

1

将应用程序 jar 放在您的 tomcat lib 目录中通常是个坏主意。将它们全部保留在您的战争中,以便它们仅限于该应用程序。如果你搜索,你会发现这个异常重复了很多次。

人们犯的另一个常见错误(并且不明显)是,从 JVM 的角度来看,类的标识既是类名,又是加载它的类加载器的标识。因此,如果两个类加载器加载同一个类,则不能将一个的实例强制转换为另一个。

类加载器经常令人困惑,你最好坚持人们使用的标准方法。将所有应用程序 jar 放入您的应用程序中,WEB-INF/lib以便它们与其他应用程序隔离,并确保您在公共 lib 目录中没有任何重复的 jars。还要检查您的应用程序以确保您只有一个版本的每个 jar。

您通常需要provided在 Web 应用程序中标记为的唯一东西是servlet-apijar。

于 2013-02-28T13:29:09.397 回答
1

您遇到了类加载器问题。

您的某些类需要使用另一个类加载器加载的其他类。

有关详细信息,请参阅http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html

尝试将 Spring 排除在您的战争之外(分享它,或最小化战争的规模)似乎是个好主意,但它会导致麻烦。

即使你设法让它工作,你最终也会把日志 API 弄得一团糟......

于 2013-02-28T13:20:59.563 回答