Search code examples
javamaventomcatcdiweld

What is the Maven dependency for Java EE7 and CDI 2.0?


I'm using JavaEE 7 but I want to use the CDI 2.0 API (with Weld and Tomcat, Jersey too). When I have the following Maven dependency, it uses the old CDI API for Event (so no fireAsync):

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

Adding this below it does not fix the issue (since the first maven dependency overrides it):

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

How would I get all the things I need (Jersey/Jax-RS, Servlets, ServerEndpoint, CDI 2.0/Weld in Tomcat 8) via Maven?


Solution

  • As of now (May 2017), EE 8 still wasn't released. And any EE 7 API dependency will bring in CD 1.2. Therefore, you need to make use of Maven to resolve the conflicting dependency versions. I can think of two ways to this:

    1) Define CDI dependency before you define EE 7 API

    When declaring versions in your <dependencyManagement> section of your pom.xml, Maven resolves dependencies from top to bottom, e.g. first encountered defines version. This means if you first define javax.exterprise:cdi-api:2.0, then it will take 2.0 and once you reach EE API, CDI version will be ignored. Hacky as this sounds, this is quite common way of manipulating dep. management section.

    When using classical <dependency> the algorithm of dep resolution differs and uses the principal of 'nearest definition'. Image the dependencies as a tree with your project being the root. The shortest path (lowest depth) in the tree from root to the version of given dependency is always taken. In case of equal depths, first encountered is taken (since Maven 2.0.9).

    Therefore in this case, simply defining cdi-api dependency with version directly should do the trick (depth will be 1, while with EE API depth would be 2).

    2) Use exclusion(s) from artifact

    I haven't tried this myself but theoretically, it should be possible to exclude cdi-api from EE 7 API dependency. Something along these lines:

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