Tomcat で動いている Java アプリケーションを少し調査のために触る機会があって、Eclipse のセットアップが面倒だったので簡単にローカルで実行できないかなと調べた。

環境

 mvn --version
Apache Maven 3.9.6 (bc0240f3c744dd6b6ec2920b3cd08dcc295161ae)
Maven home: /opt/homebrew/Cellar/maven/3.9.6/libexec
Java version: 17.0.8, vendor: Amazon.com Inc., runtime: /Library/Java/JavaVirtualMachines/amazon-corretto-17.jdk/Contents/Home

Mavenプラグイン

tomcat7-maven-plugin というのが Tomcat 9でも使えるらしいが、cargo-maven3-plugin の方が最近は使われていそうなのでこちらにしてみた。 以下で実行できる。

mvn org.codehaus.cargo:cargo-maven3-plugin:run

ただ問題があって一発では起動しなかった。

module java.base does not "opens java.lang" to unnamed module というエラー

java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module というエラーでJettyが起動しなかった。

JDK17では JEP 403: Strongly Encapsulate JDK Internals という仕様が追加されていて、ローレベルなAPIを叩いていると例外が発生するらしい。 これを回避するには、Javaのオプションで --add-opens=java.base/java.lang=ALL-UNNAMED といった指定をするとよい。

どこでこのCLIオプションを設定するのかわかりにくかったが、configuration.properties."cargo.jvmargs" で良さそうだ https://codehaus-cargo.atlassian.net/wiki/spaces/CARGO/pages/491563/Configuration+properties

    <build>
        <plugins>
            <plugin>
              <groupId>org.codehaus.cargo</groupId>
              <artifactId>cargo-maven3-plugin</artifactId>
              <version>1.10.12</version>
              <configuration>
                <configuration>
                  <properties>
                    <cargo.jvmargs>-Xmx2048m --add-opens=java.base/java.lang=ALL-UNNAMED</cargo.jvmargs>
                  </properties>
                </configuration>
              </configuration>
            </plugin>
        </plugins>
    </build>

参考