如何从项目级别指定 --add-opens 并确保无论以何种方式运行我的应用程序都将其考虑在内?

Cry*_*ark 19 java intellij-idea maven java-platform-module-system

--add-opens我最近迁移到 Java 17,由于运行应用程序时的一个依赖项,它带来了一些限制,要求我使用。

我需要在java -jar运行命令时添加它。现在我找到了这些解决方案:

  • 我可以将其添加到运行该项目的 Dockerfile 中的命令行参数中
java --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/sun.util.calendar=ALL-UNNAMED -jar my.jar
Run Code Online (Sandbox Code Playgroud)
  • 我可以通过我的 Maven 将它添加到我的 MANIFEST.MF 中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>
Run Code Online (Sandbox Code Playgroud)

显然,两者都适合生产。然而,当通过 IntelliJ 运行我的应用程序时,它没有选择我认为是正常的选项。我必须将它们设置在我的运行配置中(顺便说一下,它也提交给我的项目)作为虚拟机参数。

我正在寻找一种方法来自动确保一致性,而不必在我声明附加打开的两个地方并行维护。

编辑:我想知道 argfiles 是否可行。就像我的项目中有一个 argfile 一样,它将在 jar 中引用,并且可以在 y 运行配置中引用。我还没有找到太多证据,但这就是我目前正在追求的道路。

编辑2:我addopens在项目的根目录添加了一个文件,现在可以从我需要它的各个点引用它。对于测试,我添加了这个,并且它与 IntelliJ 测试和 Maven 测试一起开箱即用:

<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>
Run Code Online (Sandbox Code Playgroud)

我还可以将该addopens文件发送到我的 docker 中以在生产中使用。我仍然需要手动添加到 IntteliJ 中的运行配置@addopens

Mar*_*han 7

我在这里添加我正在使用的当前解决方案。

\n

我的上下文是Spring-Bootorg.springframework.boot:spring-boot-maven-plugin:repackage通过目标在Maven上生成最终的可执行文件

\n

这个想法是在它之前请求执行org.apache.maven.plugins:maven-jar-plugin:jar,其中Add-ExportsAdd-Opens被添加到MANIFEST.MF.

\n
    \n
  • 这必须在Maven期间完成 package阶段
  • \n
  • 该执行的目的id应该是<id>default-jar</id>覆盖它已经执行的 jar 插件的Spring-Boot执行。
    \n否则,Maven会抱怨它位于它认为是第二个 jar 的前面,并会要求您通过分类器重命名它。
  • \n
  • 由于一个神秘的原因,=ALL-UNNAMED结局--add-opens--add-exports命令行中的否则,在执行时将不会考虑它们。
  • \n
\n
<!-- Modifier le MANIFEST.MF pour y ajouter les add-opens, add-exports -->\n<plugin>\n    <groupId>org.apache.maven.plugins</groupId>\n    <artifactId>maven-jar-plugin</artifactId>\n\n    <executions>\n        <execution>\n            <id>default-jar</id>\n            <phase>package</phase>\n\n            <goals>\n                <goal>jar</goal>\n            </goals>\n\n            <configuration>\n                <archive>\n                    <manifestEntries>\n                        <Add-Exports>java.base/sun.nio.ch</Add-Exports>\n                        <Add-Opens>java.base/java.util java.base/java.io java.base/java.nio java.base/java.lang java.base/java.lang.invoke java.base/sun.security.util java.base/sun.security.action</Add-Opens>\n                    </manifestEntries>\n                </archive>\n            </configuration>\n        </execution>\n    </executions>\n</plugin>\n\n<!-- G\xc3\xa9n\xc3\xa9rer l\'application finale (un fat jar) -->\n<plugin>\n    <groupId>org.springframework.boot</groupId>\n    <artifactId>spring-boot-maven-plugin</artifactId>\n\n    <executions>\n        <!-- Cr\xc3\xa9er le fat jar ex\xc3\xa9cutable de l\'application -->\n        <execution>\n            <id>executable-jar</id>\n            <phase>install</phase>\n            \n            <goals>\n                <goal>repackage</goal>\n            </goals>\n            \n            <configuration>\n                <executable>true</executable>\n            </configuration>\n        </execution>\n    </executions>\n</plugin>\n
Run Code Online (Sandbox Code Playgroud)\n

这会产生这个MANIFEST.MF

\n
Manifest-Version: 1.0\nCreated-By: Maven JAR Plugin 3.2.2\nBuild-Jdk-Spec: 17\nImplementation-Title: Application-Backend m\xc3\xa9tier : Services d\'enrichiss\n ement Open Data\nImplementation-Version: 0.0.12-SNAPSHOT\nAdd-Exports: java.base/sun.nio.ch\nAdd-Opens: java.base/java.util java.base/java.io java.base/java.nio java\n .base/java.lang java.base/java.lang.invoke java.base/sun.security.util \n java.base/sun.security.action\nMain-Class: org.springframework.boot.loader.JarLauncher\nStart-Class: fr.ecoemploi.run.Application\nSpring-Boot-Version: 2.7.9\nSpring-Boot-Classes: BOOT-INF/classes/\nSpring-Boot-Lib: BOOT-INF/lib/\nSpring-Boot-Classpath-Index: BOOT-INF/classpath.idx\nSpring-Boot-Layers-Index: BOOT-INF/layers.idx\n
Run Code Online (Sandbox Code Playgroud)\n

我现在可以替代

\n
Manifest-Version: 1.0\nCreated-By: Maven JAR Plugin 3.2.2\nBuild-Jdk-Spec: 17\nImplementation-Title: Application-Backend m\xc3\xa9tier : Services d\'enrichiss\n ement Open Data\nImplementation-Version: 0.0.12-SNAPSHOT\nAdd-Exports: java.base/sun.nio.ch\nAdd-Opens: java.base/java.util java.base/java.io java.base/java.nio java\n .base/java.lang java.base/java.lang.invoke java.base/sun.security.util \n java.base/sun.security.action\nMain-Class: org.springframework.boot.loader.JarLauncher\nStart-Class: fr.ecoemploi.run.Application\nSpring-Boot-Version: 2.7.9\nSpring-Boot-Classes: BOOT-INF/classes/\nSpring-Boot-Lib: BOOT-INF/lib/\nSpring-Boot-Classpath-Index: BOOT-INF/classpath.idx\nSpring-Boot-Layers-Index: BOOT-INF/layers.idx\n
Run Code Online (Sandbox Code Playgroud)\n

通过:

\n
java --add-exports java.base/sun.nio.ch=ALL-UNNAMED \\\n   --add-opens java.base/java.util=ALL-UNNAMED \\\n   --add-opens java.base/java.io=ALL-UNNAMED \\\n   --add-opens java.base/java.nio=ALL-UNNAMED \\\n   --add-opens java.base/java.lang=ALL-UNNAMED \\\n   --add-opens java.base/java.lang.invoke=ALL-UNNAMED \\\n   --add-opens java.base/sun.security.util=ALL-UNNAMED \\\n   --add-opens java.base/sun.security.action=ALL-UNNAMED \\\n   -jar target/application-metier-et-gestion.jar\n
Run Code Online (Sandbox Code Playgroud)\n

这对于分发给最终用户来说要方便得多,并且将避免他们更改所有命令行、服务来运行 java jar。

\n


小智 3

您可以使用该选项在 Maven 插件(例如 Surefire 插件)中添加 JDK 参数。

       <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>
Run Code Online (Sandbox Code Playgroud)

我已经针对 IntelliJ IDE 和 Java 17 (Temurin-17.0.1) 尝试了上述方法。java -jar它在通过命令运行以及通过 IDE 运行应用程序时运行良好。

如果您要添加多个此类 JVM 选项,请尝试保留分配给属性的选项并在 argLine 中使用该属性。