类路径上的 UIComponent 两次,应该从哪里导入?

UIComponent on classpath twice, where should it be imported from?

在调试一个不相关的问题时,我注意到我们的一个较新项目在 class 路径上有两次不同版本的 javax.faces.component.UIComponent。它们是从这 2 个依赖项加载的,它们是 Tomee lib 目录中的 provided

    <!-- Parent POM-->
    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-api</artifactId>
        <version>8.0</version>
        <scope>provided</scope>
    </dependency>

    <!-- Web POM-->
    <dependency>
        <groupId>org.apache.myfaces.core</groupId>
        <artifactId>myfaces-api</artifactId>
        <version>2.3.3</version>
        <scope>provided</scope>
    </dependency>

虽然目前这不会造成任何问题,但我喜欢在看到类路径冲突时立即解决,我知道他们会在某个时候回来咬我。

这个class应该来自哪里?

非常感谢。

这不会发生冲突,因为两者都标记为 provided。 IE。责任在目标 运行time 上(在您的特定情况下是 TomEE)。所以你可以安全地离开原样。

但是顺序不太理想。 impl 特定 API 应排在 之前 规范特定 API。这不是代码正常运行所必需的,但通常是工具正常运行所必需的。例如,Eclipse 内置调试​​器选择列出的第一个,但在这种特定情况下,它实际上是正在加载的 impl 特定 API。因此,在调试时,您可能会遇到源代码行 "out of sync" 与实际执行行的情况,因为 Eclipse 正在附加来自规范特定 API 的源代码。这很烦人。

因此,理想情况下,为了让 IDE 在调试期间加载并附加正确的源代码文件,请按以下方式重新排序它们:

<dependency>
    <groupId>org.apache.myfaces.core</groupId>
    <artifactId>myfaces-api</artifactId>
    <version>2.3.3</version>
    <scope>provided</scope>
</dependency>

<dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-api</artifactId>
    <version>8.0</version>
    <scope>provided</scope>
</dependency>

但是,如果您不关心这一切,只想尽可能少地使用 pom,那么请删除具体的 impl API(s),这样它就会 运行在任何 Java EE 8 容器上,而不是仅随 MyFaces 一起提供的容器。

<dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-api</artifactId>
    <version>8.0</version>
    <scope>provided</scope>
</dependency>

另请参阅:

  • How to properly install and configure JSF libraries via Maven?