如何将战争合二为一?

Posted

技术标签:

【中文标题】如何将战争合二为一?【英文标题】:How to merge wars into one? 【发布时间】:2010-12-04 17:21:14 【问题描述】:

在我们公司,我们有许多不同的模块构建为单独的战争。 每个客户都可以挑选他想购买的模块。 由于所有模块共享相同的会话、安全上下文等,因此将它们合并到单个战争中是有意义的。

是否可以自动化此过程?例如,它应该合并 web.xml,计算每个 wars 的依赖关系,复制 .jsp 和 .class 等文件。顺便说一下,我们正在使用 Maven,但无法找到解决此问题的方法。

【问题讨论】:

【参考方案1】:

这显然是可能的,但我认为你最好首先处理一个单一的 WAR。对我来说,后期对 WAR 内容的“挑选和混合”听起来像是一场噩梦。

【讨论】:

如果客户不购买模块,那么我不想将模块分发给客户(并诉诸隐藏它..)。此外,这样的战争将是巨大的——这对于发展等目的来说是非常不切实际的。【参考方案2】:

一般来说 - 不,这是不可能的。如果您有重复的 JSP 名称怎么办? Servlet 名称/映射?加载不同参数的相同上下文侦听器(如果您使用 Spring / Struts / 等则很常见)?你明白了。

在您的特定情况下,这可能会也可能不会,具体取决于您的具体情况。提取战争和复制 JSP/类/库很容易;合并 web.xml 有点复杂,因为您必须维护元素顺序 - 手动定义“合并的”web.xml 可能更容易。

【讨论】:

如果发现任何此类冲突,我会很高兴拥有中止该工具。 我认为策略可以处理那些直接的名称冲突(覆盖使用“首先获胜”策略,尽管“包括次战获胜的战争”对我来说更有意义。我想要执行此操作并合并 web-xmls 并映射来自 sub-war 的 servlet 和过滤器并在结果中可用。如果 servlet 名称或 servlet 映射路径发生冲突,则如上所述有解决冲突的策略。在以下情况下非常有用您有一个基础平台,您希望将其组合到不同的最终项目/产品中。【参考方案3】:

您也许可以使用 One-Jar 获得一些东西。

http://one-jar.sourceforge.net/

它可能无法满足您的所有需求。

【讨论】:

【参考方案4】:

我记得cargo-maven2-plugin 有一个uberwar 的魔力。我没有使用过它,但我知道它旨在合并战争,但您需要小心避免冲突。

对源的快速扫描表明您定义了merge descriptor 来确定如何合并战争。不幸的是,documentation site 已丢失,因此我无法提供更多详细信息。

您可以查看Codehaus Jira 网站以了解其当前状态。

要使用插件,您需要像这样指定配置:

<build>
  <plugins>
    <plugin>
      <groupId>org.codehaus.cargo</groupId>
      <artifactId>cargo-maven2-plugin</artifactId>
      <version>1.0</version>
      <extensions>true</extensions>
      <configuration>
      <descriptor>merge.xml</descriptor>
      </configuration>
    </plugin>
  </plugins>
</build>
<dependencies>
  <dependency>
    <groupId>project1.groupId</groupId>
    <artifactId>project1</artifactId>
    <type>war</type>
    <version>1.0.0</version>
  </dependency>
  <dependency>
    <groupId>project2.groupId</groupId>
    <artifactId>project2</artifactId>
    <type>war</type>
    <version>1.2.0</version>
  </dependency>
</dependencies> 

(仍在寻找 merge.xml 示例)

【讨论】:

@Pascal 我倾向于同意,但如果没有重构选项,这提供了一种解决方法 @Rich 当然,这是真的,我给了你我的 +1。我删除了我之前的评论,因为它可能会被误解。【参考方案5】:

考虑到 djna 和 ChssPly76 提到的风险,您可以通过使用带有 Maven WAR plugin 的覆盖来实现这一点。这将要求您分离 servlet 映射以确保您没有任何 URL 冲突等,但它可能会成功。

基本上,您创建一个具有多个 WAR 依赖项的模块并使用插件将它们合并到一个新的模块中。

【讨论】:

这适用于几乎所有来自不同 webapp 战争的文件(非冲突)。你知道合并不同 web.xml 文件的方法吗?【参考方案6】:

EAR 旨在容纳多种物品。这对你来说有可能吗?


编辑:首先,让我们假设没有重复的资源(哪个应该放在最终的 jar 中?)并且所有 jar 都是兼容的(每个库只有一个版本等)。

除了需要仔细合并的各种 XML 文件外,您应该可以只复制 WEB-INF/ 的内容。最简单的方法可能是使用 XSLT 样式表,它允许您保存两个 XML 文档并将它们合并(如果我没记错的话,这是标签)。每个 xml 文件都需要一个,以便确定您正确执行此操作 - 只需考虑 JSF 导航。

所以,我的建议是简单的资源副本和手工制作的 XSLT 样式表 pr xml 配置文件。

【讨论】:

这是一个选项(这将限制 Web 服务器的数量),但在这种情况下,我仍然需要在战争之间共享会话和安全上下文。一些应用服务器允许在战争之间共享 http 会话,但这似乎不是标准功能。 我知道 EAR 可以容纳多个不相关的 web 应用程序,但不会将两个 web 应用程序合并为一个?但我认为我需要更多地研究如何使用 EAR。推荐任何参考或 EAR 项目来看看?

以上是关于如何将战争合二为一?的主要内容,如果未能解决你的问题,请参考以下文章

如何将代理创建为战争文件?

如何使用詹金斯管道将战争部署到tomcat?

如何让 Maven 将战争常见的所有罐子放在同一个 EAR 到 EAR 根目录中?

如何使用另一场战争中的类文件

如何在 Liferay 门户 6.2 中部署地理服务器战争

如何将 Spring Boot 应用程序战争部署到 AWS Elastic Beanstalk?