我们有多个web应用程序被打包成war并部署在jetty服务器的jetty.base中。我们使用的是 9.4.26.v20200117
Jetty的版本。比方说。a.war, b.war, c.war and d.war
. 这些分为两类。Group 1 -> a.war and b.war
,和 Group 2 -> c.war and d.war
. 我们有外部依赖的jar文件在 jetty.base/lib/ext
和 jetty.base/lib/group2
. 在我们的组织中,只有第1组webapps是我的团队所拥有的,第2组是其他团队所拥有的。
我们有 -module-ext
启用,因此在 jetty.base/lib/ext
加载到服务器classpath中,并把 extraClassPath
配置在上下文xml(c.xml和d.xml)中用于第2组webapps从 jetty.base/lib/group2
.
这里的问题是,当我通过外部jar升级在 jetty.base/lib/ext
到最新的版本,这影响了第2组的webapps自 jetty.base/lib/ext
被加载到系统classpath中,并且它对所有的Web应用程序都是可见的。我们决定打破这种组间的耦合。我们(第1组)不能使用extraClassPath配置,因为我们有同一个实例要在第1组的web应用中共享。我想一个可能的方法是,在下面的目录中创建一个目录。jetty.base/lib
(说。jetty.base/lib/group1
),并将外部罐子从 jetty.base/lib/ext
到 jetty.base/lib/group1
,创建自定义的classpath,并将外部jar从 jetty.base/lib/group1
并将这个自定义的classpath配置为只对第1组Web应用程序可用。任何关于如何实现这一目标的建议或任何其他可能的解决方案都将受到赞赏。
先谢谢你
"跨webapps的共同依赖 "是JNDI存在的原因之一。
"为了减小war包的大小 "是个假理由(Jetty已经测试过高达4GB的war文件,WEB-INFlib中约有5000个jar,合计超过2000000万条)。
方案一:正确使用WAR文件,消除共享依赖关系。
如果你 跳过 共同的共享依赖,你...
方案2:正确使用JNDI。
如果你仍然需要共享资源(注意我说的是 "资源",不是依赖关系,也不是classloader等),那么可以考虑通过API设置资源,并用JNDI共享该资源。
你会在服务器级别将资源绑定到你选择的JNDI位置,只暴露API作为使用技术。
将 API jars(而不是实现 jars)放在你的 war 文件中。WEB-INF/lib
的每个webapp。
有的webapp,通过JNDI查找访问公共资源,通过API使用该资源。
这样就可以分清资源和各个类加载器如何正确操作。
服务器类加载器负责共同资源的内涵。
每个webapp类加载器负责自己的API jar,通过JNDI层访问公共资源。
方案3:放弃整个WebApp类加载器的隔离,反转行为。
考虑到你对问题的描述,这个选项不太可能是一个好的选择,只是为了完整起见,在这里包括它。
在你的 WebAppContext
你可以完全改变classloader查找行为的工作方式。 从Servlet特定的方式,到Java特定的方式。
使用 WebAppContext.setParentLoaderPriority(true)
来使用Java行为。
这意味着当你的webapp需要一个类时,它会先检查父类加载器(服务器),然后再由webapp加载一个类。