Ahmad Shahwan
Ahmad Shahwan

Reputation: 1984

Use java automatic module cdi.api with maven and java 9+

I want to use CDI functionality in a java module. I'd like my code to remain generic and do not depend on a particular implementation.

I use Java 11 and Maven 3.6.0.

For a simplicity, my goal is reduced to importing package javax.enterprise.context in a java file. When I do so without module (without module-info.java) every thing works well.

Now when I add a module-info.java without requiring other modules, I get the following error message:
package javax.enterprise.context is not visible (package javax.enterprise.context is declared in the unnamed module, but module javax.enterprise.context does not read it)

Until now everything is OK. This message makes sens since I didn't require the CDI module.

To fix this I add requires cdi.api; to my module-info.java, only to get the following error:
module not found: cdi.api

My understanding is that the CDI library should take an automatic module name inspired by the jar file's name. When I run maven with -X directive I see cdi-api-2.0.jar in my classpath. I believe, correct if I'm wrong, this should translate to cdi.api automatic module name. But still this doesn't work.

Here is my minimal example:

pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.acme</groupId>
  <artifactId>test.java.cdi</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

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

</project>

src/main/java/module-info.java:

module com.acme.test.cid {
    requires cdi.api;
}

src/main/java/com/acme/Main.java

package com.acme;

import javax.enterprise.context.*;

class Main {}

Any insights are highly appreciated.

Upvotes: 2

Views: 1651

Answers (1)

Naman
Naman

Reputation: 31978

When I run maven with -X directive I see cdi-api-2.0.jar in my classpath. I believe, correct if I'm wrong, this should translate to cdi.api automatic module name. But still this doesn't work.

No, the modules resulting into the classpath are translated into the unnamed module.

module not found: cdi.api

Indicates that the cdp.api module was not found on the modulepath.


I tried reproducing the same, yet the same reproducible code worked fine for me, but notice my logs read :

[DEBUG] Classpath:
[DEBUG] Modulepath:
[DEBUG]  .../Desktop/cdipi/target/classes
[DEBUG]  .../.m2/repository/javax/enterprise/cdi-api/2.0/cdi-api-2.0.jar
[DEBUG]  .../.m2/repository/javax/el/javax.el-api/3.0.0/javax.el-api-3.0.0.jar
[DEBUG]  .../.m2/repository/javax/interceptor/javax.interceptor-api/1.2/javax.interceptor-api-1.2.jar
[DEBUG]  .../.m2/repository/javax/inject/javax.inject/1/javax.inject-1.jar
[DEBUG] Source roots:
[DEBUG]  .../Desktop/cdipi/src/main/java
[DEBUG]  .../Desktop/cdipi/target/generated-sources/annotations

Just make sure the maven-compiler-plugin in use if 3.6.0 or above to support the modulepath added in Java9 and above. You can do it as specified in this answer.

Upvotes: 2

Related Questions