Search code examples
eclipsemaven-3java-platform-module-systemjava-compiler-apijava-20

Cannot Export/Open Package from Module jdk.compiler to Run/Pass Tests in Maven


Settings

I'm using JDK 22:

openjdk version "22" 2024-03-19
OpenJDK Runtime Environment (build 22+36-2370)
OpenJDK 64-Bit Server VM (build 22+36-2370, mixed mode, sharing)

I'm also using Eclipse 2024-03 with the JDK 22 update:

Version: 2024-03 (4.31.0) Build id: 20240307-1437
Eclipse JDT (Java Development Tools) Patch with Java 22 support for 2024-03 development stream
1.2.300.v20240320-0518_BETA_JAVA22

Finally, I'm using Maven:

Apache Maven 3.9.4 (dfbb324ad4a7c8fb0bf182e6d91b0ae20e3d2dd9)
Maven home: C:\Maven
Java version: 22, vendor: Oracle Corporation, runtime: C:\Program Files\Java\jdk-22
Default locale: en_CA, platform encoding: UTF-8
OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"

Background

I created a simple Maven project in Eclipse with the usual folder hierarchy, one simple main class and one simple test.

public class Main {
    public static void main(final String[] args) {
        final Main main = new Main();
        final JavacTool jt = main.getCompiler();
        System.out.println(jt);
    }

    public JavacTool getCompiler() {
        return JavacTool.create();
    }
}

After setting up the Eclipse project and the Run Configuration correctly, I can compile and run both the main class and the test with expected results.

Problem

I have created a pom.xml file to compile and install my code with Maven:

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>22</source>
                    <target>22</target>
                    <fork>true</fork>
                    <compilerArgs>
                        <arg>
                            --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED</arg>
                        <arg>
                            -J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED</arg>
                        <arg>
                            -J--add-opens=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED</arg>
                    </compilerArgs>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>

    </dependencies>

Despite having read many articles here, here, here, and there (among others) and set the compiler with --add-exports and --add-opens (I also tried to set .mvn/jvm.config.), I can compile the code but the test always fails with the error:

TestMain.test:12 » IllegalAccess class net.ptidej.tutorial.javactool.Main (in unnamed module @0x7f690630) cannot access class com.sun.tools.javac.api.JavacTool (in module jdk.compiler) because module jdk.compiler does not export com.sun.tools.javac.api to unnamed module @0x7f690630

How could I have Maven "see" (or "use"?) the arguments --add-exports and --add-opens?


Solution

  • @howlger pointed to the answer to this problem. Thanks! No matter what the Maven documentation and other posts say, compilerArgs are only for the compiler and not passed to the JVM for the Surefire plugin.

    From:

    <fork>true</fork>
    <compilerArgs>
        <arg>--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED</arg>
        <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED</arg>
        <arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED</arg>
    </compilerArgs>
    

    It must become:

    <compilerArgs>
        <arg>--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED</arg>
    </compilerArgs>
    

    with:

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.19.1</version>
        <configuration>
            <argLine>
                --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
                --add-opens=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED</argLine>
        </configuration>
    </plugin>