【问题标题】:What is the Maven dependency for Java EE7 and CDI 2.0?Java EE7 和 CDI 2.0 的 Maven 依赖项是什么?
【发布时间】:2017-10-30 02:51:41
【问题描述】:

我正在使用 JavaEE 7,但我想使用 CDI 2.0 API(也使用 Weld 和 Tomcat,Jersey)。当我有以下 Maven 依赖项时,它使用旧的 CDI API for Event(所以没有 fireAsync):

    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-api</artifactId>
        <version>7.0</version>
    </dependency>

在下面添加它并不能解决问题(因为第一个 maven 依赖项覆盖了它):

    <dependency>
        <groupId>javax.enterprise</groupId>
        <artifactId>cdi-api</artifactId>
        <version>2.0</version>
    </dependency>

如何通过 Maven 获得我需要的所有东西(Jersey/Jax-RS、Servlets、ServerEndpoint、CDI 2.0/Tomcat 8 中的 Weld)?

【问题讨论】:

  • 尝试删除 javaee-api 并将其替换为 implementation &lt;dependency&gt; &lt;groupId&gt;org.jboss.weld.servlet&lt;/groupId&gt; &lt;artifactId&gt;weld-servlet-core&lt;/artifactId&gt; &lt;version&gt;3.0.0.Final&lt;/version&gt; &lt;/dependency&gt;

标签: java maven tomcat cdi weld


【解决方案1】:

截至目前(2017 年 5 月),EE 8 仍未发布。任何 EE 7 API 依赖项都将引入 CD 1.2。因此,您需要使用 Maven 来解决冲突的依赖版本。我可以想到两种方法:

1) 在定义 EE 7 API 之前定义 CDI 依赖项

pom.xml&lt;dependencyManagement&gt; 部分中声明版本时,Maven 从上到下解析依赖关系,例如第一次遇到定义版本。这意味着如果您首先定义javax.exterprise:cdi-api:2.0,那么它将采用 2.0,一旦您达到 EE API,CDI 版本将被忽略。听起来很hacky,这是操作dep的很常见的方法。管理部分。

当使用经典的&lt;dependency&gt;时,dep 分辨率的算法不同,并使用“最近定义”的原则。将依赖项映像为以您的项目为根的树。始终采用树中从根到给定依赖项版本的最短路径(最低深度)。在相同深度的情况下,首先遇到的是(从 Maven 2.0.9 开始)。

因此,在这种情况下,只需直接使用版本定义 cdi-api 依赖项即可解决问题(深度为 1,而 EE API 深度为 2)。

2) 使用工件中的排除项

我自己没有尝试过,但理论上,应该可以从 EE 7 API 依赖项中排除 cdi-api。大致如下:

<dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-api</artifactId>
    <version>7.0</version>
    <exclusions>
        <exclusion>
            <groupId>javax.exterprise</groupId>
            <artifactId>cdi-api</artifactId>
        </exclusion>
    </exclusions>
</dependency>

【讨论】:

  • 其实你的第一个答案不太对。 Maven 使用最近获胜策略,这意味着如果您的树中有两次相同的依赖项,则选择最近的一个(不是指第一个)。但是,它看起来不适用于提供的依赖项(或可选依赖项)。
  • 嗯,提供和可选是我猜的另一回事。但除此之外,我多次遇到我在这里描述的内容——使用了最顶层的 dep。我想这在某种意义上使它“最近”。但我真的不想阅读整个 Maven 文档来找到定义它的段落。如果您知道在哪里可以找到它,请分享。
  • 我同意你的观点,我也遇到过你描述的情况,但总是(据我记得)提供或测试范围(运行时或编译范围从来没有问题)。这是文档:maven.apache.org/guides/introduction/…,请参阅“依赖中介”。
  • @Rouliboy 我想我知道我们分歧的原因 - 经典的 &lt;dependency&gt;&lt;dependencyManagement&gt; 部分之间存在差异。后者确实使用基于深度的最近的dep,而是使用我描述的壁橱。而且由于 OP 对您的回答发表评论说交换有帮助,我猜他确实在管理部分有它。至于你的 cmets - 你适合经典的依赖,但也要注意,在相同深度的情况下,首先遇到的是。将编辑答案以使其更清晰。
  • 感谢您的澄清。但是,对于这篇文章的原始问题,它似乎不起作用。我在没有依赖管理部分的情况下进行了测试,maven 没有选择最近的依赖项,而是第一个依赖项。我会再试一次。
【解决方案2】:

如果您将 cdi-api 依赖项放在 javaee-api 之前,它将解决您的问题,并且 maven 会选择“好的”cdi-api 依赖项。

对于第二个问题,7.0 版本中的javaee-api 足以拥有所有 Java EE 7 API。请注意,CDI 2.0 不是 Java EE 7 规范的一部分,这就是您需要手动添加它的原因。

【讨论】:

  • 这确实有效,但它似乎是错误的或坏主意。它实际上只是首先加载这些定义并让其他定义“失败”。但是加载 javaee-api 的 jar 可能与加载的 cdi 2 类有问题。
  • 在 Java EE 规范的 8.0 版本最终确定之前,您需要这样做。
猜你喜欢
  • 2020-08-02
  • 2020-08-16
  • 2015-04-13
  • 1970-01-01
  • 2017-06-03
  • 2019-03-10
  • 1970-01-01
  • 2016-10-11
  • 2015-03-13
相关资源
最近更新 更多