6

I've recently moved to Java 17 and with it came a couple restrictions requiring me to use --add-opens because of one dependency when running my application.

I need to add this when the java -jar command is ran. For now I found these solutions:

  • I can add it to the command line argument in my Dockerfile that runs the project
java --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/sun.util.calendar=ALL-UNNAMED -jar my.jar
  • I can add it in my MANIFEST.MF through my maven pom.xml
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <archive>
            <manifestEntries>
                <Add-Opens>java.base/sun.util.calendar java.base/java.util</Add-Opens>
            </manifestEntries>
        </archive>
    </configuration>
</plugin>

Both work fine for production apparently. However when running my app through IntelliJ, it's not picking up the options which is normal I guess. I have to set them in my run configuration (which is also committed to my project by the way) as VM arguments.

I'm looking for a way to ensure consistency automatically and not have to maintain in parallel two places where I declare my add-opens.

EDIT: I'm wondering if something is doable with argfiles. Like have an argfile inside my project that would be referenced in the jar and that could be referenced in an y run configuration. I haven't found much evidence yet but that's the path I'm currently pursuing.

EDIT 2: I added an addopens file at the root of my project and can now reference this from the various points where I need it. For tests, I added this and it worked out of the box with IntelliJ tests AND maven tests together:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
        <!-- This adds the options contained in the addopens file to the test JVM arguments -->
        <argLine>@addopens @{argLine}</argLine>
    </configuration>
</plugin>

I also can ship that addopens file in my docker to use in production. I still need to add to my Run configuration in IntteliJ the @addopens manually.

Crystark
  • 3,383
  • 3
  • 35
  • 55
  • 1
    If you use argfiles, you still need a JVM argument each time but you could try to tell your IDE to use that JVM argument for every invocation and add it to the `maven-exec-plugin` and similar (if used). – dan1st Dec 02 '21 at 10:54
  • Are you running it via the Java main class in IDE? Check the https://stackoverflow.com/a/9846103/2000323 for the `exec-maven-plugin` example and how you can pass arguments to the Java Main class. – Andrey Dec 02 '21 at 11:44
  • It is a spring boot app so I'm running it in IntelliJ with the classic "Application" configuration type. The exec-maven-plugin doesn't do much apparently regarding this. I had this working with the surfire plugin though. See the EDIT 2 i added for my latest findings – Crystark Dec 02 '21 at 15:50
  • You can add `jvmArguments` into `spring-boot-maven-plugin`, see https://stackoverflow.com/a/67696568/2000323 and launch `spring-boot:run` Maven task from Maven tool window. But Spring Boot Application run configuration will not pick up these arguments automatically. Feel free to file a request for this: https://youtrack.jetbrains.com/issues/IDEA – Andrey Dec 07 '21 at 12:41

1 Answers1

0

You can use the option to add the JDK parameters in the maven plugins like surefire plugin.

       <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <configuration>
                    <argLine>
                        --add-opens java.base/java.time=ALL-UNNAMED
                        ${surefireArgLine}
                    </argLine>
            </configuration>
       </plugin>

I have tried the above approach for IntelliJ IDE and Java 17 (Temurin-17.0.1). It works fine on running via java -jar command, as well as on running the app via IDE.

If you have multiple such JVM options to add, try keeping those assigned to a property and use that property here in the argLine.