mvn test を実行したら SurefireBooterForkException が発生した

最近、JavaでLeetCodeを解いている。と言ってもEasyレベルのものばかりだけれど。 

leetcode.com

 

問題を解く途中でエラーに遭遇したので、顛末をメモしておく。

 

 

[Mavenプロジェクトの構成]

利用している環境は以下の通り。

$ mvn -version
Apache Maven 3.6.2 (40f52333136460af0dc0d7232c0dc0bcf0d9e117; 2019-08-28T00:06:16+09:00)
Maven home: /usr/local/Cellar/maven/3.6.2/libexec
Java version: 13.0.1, vendor: Oracle Corporation, runtime: /Library/Java/JavaVirtualMachines/openjdk-13.0.1.jdk/Contents/Home
Default locale: ja_JP, platform encoding: UTF-8
OS name: "mac os x", version: "10.15.6", arch: "x86_64", family: "mac"

 

Mavenプロジェクトの構成は至ってシンプル。App.javaAppTest.javaの中身は今回あまり本筋とは関係ないので省略。

$ tree
.
├── pom.xml
└── src
    ├── main
    │   └── java
    │       └── com
    │           └── kdnakt
    │               └── simple
    │                   └── App.java
    └── test
        └── java
            └── com
                └── kdnakt
                    └── simple
                        └── AppTest.java

 

pom.xmlの中身はおよそ以下の通り。

<!--?xml version="1.0" encoding="UTF-8"?-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <groupid>com.kdnakt.simple</groupid>
  <artifactid>simple-project</artifactid>
  <properties>
    <project.build.sourceencoding>UTF-8</project.build.sourceencoding>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
  </properties>
(略)
  <build>
    <pluginmanagement>
      <plugins>
      (略)
        <plugin>
          <artifactid>maven-surefire-plugin</artifactid>
          <version>2.22.1</version>
        </plugin>
      </plugins>
    </pluginmanagement>
  </build>

(略)
</project>

 

ここで指定されているmaven-surefire-pluginは、テストを実行しレポートを生成してくれるおなじみのMavenプラグインである。

maven.apache.org

 

[発生した例外]

テスト駆動開発よろしく失敗するテストを書き終えたので、mvn testコマンドでテストを実行しようとしたら、次のようにエラーログが出た。

$ mvn test
[INFO] Scanning for projects...
[INFO] 
[INFO] ------------------< com.kdnakt.simple:simple-project >------------------
[INFO] Building simple-project 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-resources-plugin:3.0.2:resources (default-resources) @ simple-project ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /Users/akito/Develop/kdnakt/java-sandbox/simple'project/src/main/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.0:compile (default-compile) @ simple-project ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /Users/akito/Develop/kdnakt/java-sandbox/simple'project/target/classes
[INFO] 
[INFO] --- maven-resources-plugin:3.0.2:testResources (default-testResources) @ simple-project ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /Users/akito/Develop/kdnakt/java-sandbox/simple'project/src/test/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.0:testCompile (default-testCompile) @ simple-project ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /Users/akito/Develop/kdnakt/java-sandbox/simple'project/target/test-classes
[INFO] 
[INFO] --- maven-surefire-plugin:2.22.1:test (default-test) @ simple-project ---
[INFO] 
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] 
[INFO] Results:
[INFO] 
[INFO] Tests run: 0, Failures: 0, Errors: 0, Skipped: 0
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  2.300 s
[INFO] Finished at: 2020-09-26T23:12:12+09:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.22.1:test (default-test) on project simple-project: There are test failures.
[ERROR] 
[ERROR] Please refer to /Users/akito/Develop/kdnakt/java-sandbox/simple'project/target/surefire-reports for the individual test results.
[ERROR] Please refer to dump files (if any exist) [date].dump, [date]-jvmRun[N].dump and [date].dumpstream.
[ERROR] The forked VM terminated without properly saying goodbye. VM crash or System.exit called?
[ERROR] Command was /bin/sh -c cd /Users/akito/Develop/kdnakt/java-sandbox/simple\'project && /Library/Java/JavaVirtualMachines/openjdk-13.0.1.jdk/Contents/Home/bin/java -jar '/Users/akito/Develop/kdnakt/java-sandbox/simple\'project/target/surefire/surefirebooter10150023550494437618.jar' '/Users/akito/Develop/kdnakt/java-sandbox/simple\'project/target/surefire' 2020-09-26T23-12-11_891-jvmRun1 surefire10720448871917931959tmp surefire_011591187786512401885tmp
[ERROR] Error occurred in starting fork, check output in log
[ERROR] Process Exit Code: 2
[ERROR] org.apache.maven.surefire.booter.SurefireBooterForkException: The forked VM terminated without properly saying goodbye. VM crash or System.exit called?
[ERROR] Command was /bin/sh -c cd /Users/akito/Develop/kdnakt/java-sandbox/simple\'project && /Library/Java/JavaVirtualMachines/openjdk-13.0.1.jdk/Contents/Home/bin/java -jar '/Users/akito/Develop/kdnakt/java-sandbox/simple\'project/target/surefire/surefirebooter10150023550494437618.jar' '/Users/akito/Develop/kdnakt/java-sandbox/simple\'project/target/surefire' 2020-09-26T23-12-11_891-jvmRun1 surefire10720448871917931959tmp surefire_011591187786512401885tmp
[ERROR] Error occurred in starting fork, check output in log
[ERROR] Process Exit Code: 2
[ERROR]         at org.apache.maven.plugin.surefire.booterclient.ForkStarter.fork(ForkStarter.java:669)
[ERROR]         at org.apache.maven.plugin.surefire.booterclient.ForkStarter.run(ForkStarter.java:282)
[ERROR]         at org.apache.maven.plugin.surefire.booterclient.ForkStarter.run(ForkStarter.java:245)
[ERROR]         at org.apache.maven.plugin.surefire.AbstractSurefireMojo.executeProvider(AbstractSurefireMojo.java:1183)
[ERROR]         at org.apache.maven.plugin.surefire.AbstractSurefireMojo.executeAfterPreconditionsChecked(AbstractSurefireMojo.java:1011)
[ERROR]         at org.apache.maven.plugin.surefire.AbstractSurefireMojo.execute(AbstractSurefireMojo.java:857)
[ERROR]         at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:137)
[ERROR]         at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:210)
[ERROR]         at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:156)
[ERROR]         at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:148)
[ERROR]         at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:117)
[ERROR]         at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:81)
[ERROR]         at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:56)
[ERROR]         at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
[ERROR]         at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:305)
[ERROR]         at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:192)
[ERROR]         at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:105)
[ERROR]         at org.apache.maven.cli.MavenCli.execute(MavenCli.java:956)
[ERROR]         at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:288)
[ERROR]         at org.apache.maven.cli.MavenCli.main(MavenCli.java:192)
[ERROR]         at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[ERROR]         at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[ERROR]         at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[ERROR]         at java.base/java.lang.reflect.Method.invoke(Method.java:567)
[ERROR]         at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:282)
[ERROR]         at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:225)
[ERROR]         at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:406)
[ERROR]         at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:347)
[ERROR] 
[ERROR] -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

 

[解決方法]

ググると以下のページがヒットした。

 

いくつか解決方法がありそうだったが、フォークしようとした際にエラーが発生しているので、フォークしないように以下の設定をpom.xmlに追加するという方法があった。

         <plugin>
           <artifactId>maven-surefire-plugin</artifactId>
           <version>2.22.1</version>
+          <configuration>
+            <forkCount>0</forkCount>
+          </configuration>
         </plugin>

 

試してみると、以下の通りうまく行った。

$ mvn test
[INFO] Scanning for projects...
[INFO] 
[INFO] ------------------< com.kdnakt.simple:simple-project >------------------
[INFO] Building simple-project 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-resources-plugin:3.0.2:resources (default-resources) @ simple-project ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /Users/akito/Develop/kdnakt/java-sandbox/simple'project/src/main/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.0:compile (default-compile) @ simple-project ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-resources-plugin:3.0.2:testResources (default-testResources) @ simple-project ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /Users/akito/Develop/kdnakt/java-sandbox/simple'project/src/test/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.0:testCompile (default-testCompile) @ simple-project ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-surefire-plugin:2.22.1:test (default-test) @ simple-project ---
[WARNING] useSystemClassloader setting has no effect when not forking
[INFO] Running com.kdnakt.simple.AppTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.096 s - in com.kdnakt.simple.AppTest
[INFO] 
[INFO] Results:
[INFO] 
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  2.301 s
[INFO] Finished at: 2020-09-26T23:44:55+09:00
[INFO] ------------------------------------------------------------------------

 

また、ページの最後には、ブランチ名にダッシュ-)が含まれている場合に同じエラーが発生しており、これを取り除くと問題なく動作したとの書き込みがあった。

今回はgitのmasterブランチで作業しており、ブランチ名には問題がないように思われた。

しかし、エラーメッセージが示しているdumpstreamファイルをみると、以下のように記載されており、`''あたりの記号が問題を引き起こしているようにも見えた。

$ cat target/surefire-reports/2020-09-26T23-43-55_712.dumpstream 
# Created at 2020-09-26T23:43:56.049
/bin/sh: -c: line 0: unexpected EOF while looking for matching `''

# Created at 2020-09-26T23:43:56.049
/bin/sh: -c: line 1: syntax error: unexpected end of file

 

よくよく思い出してみると、プロジェクトを作成したときのディレクトリ名がsimple'projectとシングルクオート(')を含んでいた。これを取り除いた別のディレクトリで、pom.xmlにフォーク数制限を設定する前のソースコードをコピーしてmvn testコマンドを実行すると、やはり問題なく動作した。

 

[まとめ]

  • mvn testコマンド実行時にSurefireBooterForkExceptionが発生した
  • pom.xml上でフォーク数を0にする設定を追加すると問題が解消した
  • 別解として、プロジェクトのパスに含まれていたシングルクオートの記号を取り除いた場合も、問題が解消した
  • 実装したサンプルコードは以下のリポジトリにまとめてある

github.com

 

無駄な記号はファイルパスに含めないにしましょう、というよくある教訓が得られた。もともとはLeetCodeの問題名をディレクトリ名に設定していて、Pascal's Triangleみたいな名前にしていたのがよくなかった、というオチ。