0

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?

8
  • 1
    I guess, in your POM you also need to configure the VM arguments for the maven-surefire-plugin: see the answers here (without the profiles). Commented Apr 15, 2024 at 20:06
  • At minimum, you should also retry this with the current release of Maven: 3.9.6. Commented Apr 15, 2024 at 20:26
  • 1
    @nitind The maven version is unrelated to that... Apart from that you should use JavacToolProvider because JavacTool is not public API (see JavaDoc of the class)... if you use JavacToolProvider all the --add- things are not necessary anymore...and if you like to run a test with it you have to add the exports for the tests as well... Commented Apr 16, 2024 at 7:26
  • 2
    There’s a standard API since Java 6. There is no reason to access this internal implementation class directly; it’s just an implementation of the official API which, as khmarbaise said, you get anyway when using the correct provider mechanism. Which is as simple as a single method call Commented Apr 16, 2024 at 9:59
  • 1
    It’s a weird goal “to dig into its internals” as an end in itself. There is already an API allowing you to perform parsing/lexical analysis and code generation separately and to access all resources, ASTs, etc in-between and to add listeners to learn what the compiler is doing. You might learn more from the official API than from your digging into internals. Commented Apr 17, 2024 at 8:55

1 Answer 1

0

@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>
Sign up to request clarification or add additional context in comments.

1 Comment

Yes that can be working but I wouldn't recommend to do that (see Holger s comment) ... furthermore use most recent versions of the plugins (2.19.1 is really old 2015!! )... maven.apache.org/plugins

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.