Passing Java arguments to the Jetty Maven plugin

395 views Asked by At

I am trying to add support to Java 17 for a project that also supports Java 8 and Java 11. It uses the Maven Jetty plugin for deployments. When running jetty:run I get the following error:

java.lang.reflect.InaccessibleObjectException: Unable to make protected void java.lang.Object.finalize() throws java.lang.Throwable accessible: module java.base does not "opens java.lang" to an unnamed module

I was able to deploy the project without errors by manually adding the --add-opens java.base/java.lang=ALL-UNNAMED Java argument using IntelliJ IDEA. It generated a command similar to this.

java --add-opens java.base/java.lang=ALL-UNNAMED  jetty:run

Is there a way to pass the argument using the POM.xml without having to manually set the Java argument? Any help or insights would be greatly appreciated!

Version numbers:

  • Java: 17
  • Jetty Maven plugin: 9.4.35.v20201120
  • Maven: 3.11.0

Here is the pom file I am working on: https://github.com/openmrs/openmrs-core/blob/458f9417c1d2ab45c37fbdac8b94ec3a854cb7be/webapp/pom.xml#L100-L129

1

There are 1 answers

0
Joakim Erdfelt On

java.lang.reflect.InaccessibleObjectException: Unable to make protected void java.lang.Object.finalize() throws java.lang.Throwable accessible: module java.base does not "opens java.lang" to an unnamed module

You really need to fix your code.

Object.finalize() has been deprecated since JDK 9, and will likely not work as you expect in a future JVM.

https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Object.html#finalize()

Either your code, or one of your dependencies is relying on a feature that is deprecated. (Eg: powermock for the longest time relied on Object.finalize, but was forced to updated their codebase once JDK 16 hit and illegal-access became deny by default on the JVM)

THIS is the proper way to fix this specific issue.


Back to how to make your project limp along on JDK 17 within Jetty ...

Jetty 9.x is now at End of Community Support.

See: https://github.com/jetty/jetty.project/issues/7958

Jetty 9 does NOT support JPMS use on jetty-maven-plugin.

That was first added in Jetty 10, in a fork mode.

See the plugin configuration options deployMode (in FORK mode) and jvmArgs (only available during fork mode)

https://eclipse.dev/jetty/documentation/jetty-10/programming-guide/index.html#deployment-modes

In short, you will either use a proper <configuration> section in your jetty-maven-plugin to specify those options, or use the <properties> section to define the property equivalents of those 2 configurations. (jetty.deployMode and jetty.jvmArgs respectively)

<properties>
  <jetty.deployMode>FORK</jetty.deployMode>
  <jetty.jvmArgs>--add-opens java.base/java.lang=ALL-UNNAMED</jetty.jvmArgs>
</properties>

<plugin>
  <groupId>org.eclipse.jetty.ee8</groupId>
  <artifactId>jetty-ee8-maven-plugin</artifactId>
  <version>12.0.2</version>
  <executions>
    <execution>
      <id>run-jetty</id>
      <phase>process-test-classes</phase>
      <goals>
        <goal>run</goal>
      </goals>
      <configuration>
        <deployMode>${jetty.deployMode}</deployMode>
        <contextXml>${basedir}/src/main/jetty/jetty-context.xml</contextXml>
        <jettyXmls>
          <jettyXml>${basedir}/src/main/jetty/jetty.xml</jettyXml>
        </jettyXmls>
        <stopPort>9898</stopPort>
        <stopKey>DEADBEEF</stopKey>
        <jvmArgs>${jetty.jvmArgs}</jvmArgs>
      </configuration>
    </execution>
  </executions>
</plugin>

The reason for defining both in a <configuration> and a <properties> is so that you can use any of the other jetty-maven-plugin goals on the command line without defining another <execution> or <configuration> section. (it also helps with IT testing)