0

Whilst debugging an unrelated issue, I've noticed that one of our newer projects has javax.faces.component.UIComponent on the classpath twice at different versions. They are loaded from these 2 dependencies, which are provided in the Tomee lib directory:

    <!-- 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>

Whilst this isn't causing any problems at the moment, I like to kill Classpath conflicts on sight, I know they'll come back to bite me at some point.

Where should this class be coming from?

Many thanks in advance.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
StuPointerException
  • 7,117
  • 5
  • 29
  • 54

1 Answers1

2

This isn't going to conflict as both are marked as provided. I.e. the responsibility is on the target runtime (which is TomEE in your specific case). So you can safely leave as-is.

But the ordering is not ideal. The impl specific API should be ranked before the spec specific API. This is not required for correct functioning of the code, but it is usually required for correct functioning of the tooling. For example, Eclipse builtin debugger picks the first one listed, but in this specific case it's actually the impl specific API which is being loaded. So you might face source code lines to be "out of sync" with actually executed lines while debugging, because Eclipse is attaching the source code from spec specific API. And this is only annoying.

So ideally, in order to get the IDE to load and attach the right source code files during debugging, reorder them as below:

<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>

But if you don't care about this all, and just want to get away with the minimal possible pom, then remove the impl specific API(s) so that it will run on any Java EE 8 container other than ones which only ship with MyFaces.

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

See also:

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555