我的部署环境非常混乱:jar文件分散在整个系统中,我无法控制它。例如,我的webapp使用最新版本的Javamail API,但似乎在$JAVA_HOME/jre/lib/ext
中有同一个库的多个副本(显然所有旧版本和不同版本)。这同样适用于数据库供应商的驱动程序,更不用说$CATALINA_HOME/lib
。 我无法清理任何内容,但显然我需要确保我的应用获得所需的最低版本的依赖项,因此我将所有必需的JAR放在WEB-INF/lib
中。根据Servlet规范和Tomcat docs:
当从Web应用程序的WebappX加载类的请求时 处理类加载器,这个类加载器将在本地查找 首先是存储库,而不是在查找之前委托
所以它应该解决我的问题。但是那个同样的医生说:
因此,从Web应用程序的角度来看,类或 资源加载按以下顺序在以下存储库中查找:
- JVM的Bootstrap类
- 系统类加载器类(如上所述)
- / WEB-INF /您的Web应用程序的类
您的Web应用程序的- / WEB-INF / lib / * .jar
- 常见的类加载器类(如上所述)
醇>
实际上/WEB-INF/lib
中的类在系统之后加载。这确实是预期的行为吗?你不觉得Tomcat文档是矛盾的吗?你知道任何servlet容器可以保证我能获得正确的依赖吗?我怎么解决这个问题?
答案 0 :(得分:4)
如果ext-folder被污染,你基本上不走运。
您唯一能做的就是将所需的所有代码(包括jar)重新打包到一个单独的包层次结构中并与您的应用程序打包。这意味着com.foo.Bar
将变为org.raffaele.com.foo.bar
或类似。然后只使用这些新名称。
注意带有类名的反射和字符串,但可以这样做。
我不知道是否有一个工具可以完全自动化这个过程。
答案 1 :(得分:4)
咬紧牙关并清理干净。
你提出的任何依赖于类加载顺序的解决方案都将是脆弱的,令人困惑的,并且非常难以调试。例如,如果你因某些原因忘记打包一个类,突然间你会选择一个略有不同的版本...我会在任何一天完全随意的行为中采取一个很好的干净的ClassNotFoundException!