Surefire Maven 插件:“通过直接写入分叉 JVM 中的本机流来损坏 STDOUT”

新手上路,请多包涵

我的 JUnit 测试在通过 Maven 和 Surefire 插件(下面的版本信息)运行时失败了。我看到错误消息:

 Corrupted STDOUT by directly writing to native stream in forked JVM 4. See FAQ web page and the dump file C:\(...)\target\surefire-reports\2019-03-20T18-57-17_082-jvmRun4.dumpstream

FAQ 页面指出了一些可能的原因,但我不知道如何使用这些信息来开始解决这个问题:

通过直接写入分叉 JVM 中的本机流来损坏 STDOUT

如果您的测试使用打印到 STDOUT 的本机库,则会出现此警告消息,因为该库损坏了插件使用的通道,以便将具有测试状态的事件传输回 Maven 进程。如果您通过 System.setOut 覆盖 Java 流,情况会更糟,因为该流也应该已损坏,但 Maven 永远不会看到测试完成并且构建可能会挂起。

如果您使用 FileDescriptor.out 或 JVM 打印 GC 摘要,则会出现此警告消息。

在这种情况下,将打印警告“通过直接写入派生 JVM 中的本机流来损坏 STDOUT”,并且可以在 Reports 目录中找到转储文件。

如果启用调试级别,则损坏流的消息会出现在控制台中。

它指的是一些直接打印到 STDOUT 的本机库,但我如何确定是哪一个,即使我知道,如果我的项目需要该库,我该如何处理这个问题?

它提到“调试级别”,但不清楚这是指 Maven 的调试级别还是 Surefire 插件的调试级别。我启用了 Maven 的调试,但没有看到常见问题解答中提到的控制台输出。而且 Surefire 的调试选项似乎是关于暂停测试并等待调试器连接到进程,而不是简单地在控制台上显示更多信息。

转储文件似乎也不是很有帮助:

 # Created on 2019-03-20T18:42:58.323
Corrupted STDOUT by directly writing to native stream in forked JVM 2. Stream 'FATAL ERROR in native method: processing of -javaagent failed'.
java.lang.IllegalArgumentException: Stream stdin corrupted. Expected comma after third character in command 'FATAL ERROR in native method: processing of -javaagent failed'.
    at org.apache.maven.plugin.surefire.booterclient.output.ForkClient$OperationalData.<init>(ForkClient.java:511)
    at org.apache.maven.plugin.surefire.booterclient.output.ForkClient.processLine(ForkClient.java:209)
    at org.apache.maven.plugin.surefire.booterclient.output.ForkClient.consumeLine(ForkClient.java:176)
    at org.apache.maven.plugin.surefire.booterclient.output.ThreadedStreamConsumer$Pumper.run(ThreadedStreamConsumer.java:88)
    at java.base/java.lang.Thread.run(Thread.java:834)

那么,我该如何解决这个问题呢?

更新:请求以下配置信息。

我在 Windows 10、Maven 3.5.3 和 Surefire 2.21.0(下面的完整配置)上使用 OpenJDK 11(Zulu 发行版)。

我使用 pom.xml 文件上的“Run As…”上下文菜单选项从 Eclipse 运行 Maven,但在控制台上运行它时获得相同的结果。

在对这个问题发表第一条评论之前,我从未听说过 JaCoco,但我看到几条错误消息都提到了它:

 [ERROR] ExecutionException The forked VM terminated without properly saying goodbye. VM crash or System.exit called?
[ERROR] Command was cmd.exe /X /C ""C:\Program Files\Zulu\zulu-11\bin\java" -javaagent:C:\\Users\\E26638\\.m2\\repository\\org\\jacoco\\org.jacoco.agent\\0.8.0\\org.jacoco.agent-0.8.0-runtime.jar=destfile=C:\\Users\\E26638\\git\\aic-expresso\\target\\jacoco.exec -Xms256m -Xmx1028m -jar C:\Users\E26638\AppData\Local\Temp\surefire10089630030045878403\surefirebooter8801585361488929382.jar C:\Users\E26638\AppData\Local\Temp\surefire10089630030045878403 2019-03-21T21-26-04_829-jvmRun12 surefire10858509118810158083tmp surefire_115439010304069944813tmp"
[ERROR] Error occurred in starting fork, check output in log
[ERROR] Process Exit Code: 1

这是 Surefire Maven 插件配置:

     <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.21.0</version>
        <configuration>
            <skipTests>${skipUnitTests}</skipTests>
            <testFailureIgnore>false</testFailureIgnore>
            <forkCount>1.5C</forkCount>
            <reuseForks>true</reuseForks>
            <parallel>methods</parallel>
            <threadCount>4</threadCount>
            <perCoreThreadCount>true</perCoreThreadCount>
            <reportFormat>plain</reportFormat>
            <trimStackTrace>false</trimStackTrace>
            <redirectTestOutputToFile>true</redirectTestOutputToFile>
        </configuration>
    </plugin>

原文由 user118967 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.4k
2 个回答

在将项目从 JAVA 8 迁移到 JAVA 11 时遇到同样的问题,将 jacoco-plugin 从 0.8.1 升级到 0.8.4 完成了这项工作。

分析 maven 依赖关系,查看从何处提取 jacoco,然后修复版本应该可以解决问题。

原文由 Nemesis 发布,翻译遵循 CC BY-SA 4.0 许可协议

我在使用自定义 Runner 运行我的 Junit 测试时遇到了这个问题。如果我在自定义运行程序或测试类中向 System.outSystem.err 输出任何内容,则会显示此确切警告。在我的例子中,问题不是由一些旧的 Jacoco 版本引起的。将 surefire 插件更新到版本 2.22.2 或更新的 3.0.0-M4 并没有解决问题。

根据 Jira 问题 SUREFIRE-1614 ,该问题将在 maven-surefire-plugin 的 3.0.0-M5 版本中修复(截至 2020 年 5 月 21 日未发布)。

更新 Maven Surefire 插件版本 3.0.0-M5 现已发布。在您的 pom.xml 中,您可以执行以下操作:

     <plugin>
      <artifactId>maven-surefire-plugin</artifactId>
      <version>3.0.0-M5</version>
      <configuration>
        <!-- Activate the use of TCP to transmit events to the plugin -->
        <forkNode implementation="org.apache.maven.plugin.surefire.extensions.SurefireForkNodeFactory"/>
      </configuration>
    </plugin>


原答案

如果您等不及 3.0.0-M5 插件的发布,可以使用插件的“SNAPSHOT”版本。它确实为我解决了这个问题。您必须在插件中启用一些特定设置,以便插件使用 TCP 而不是标准输出/错误来获取测试中引发的事件。配置更改如下:

在我的 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">
  <modelVersion>4.0.0</modelVersion>

...
  <!-- Add the repository to download the "SNAPSHOT" of maven-surefire-plugin -->
  <pluginRepositories>
    <pluginRepository>
      <id>apache.snapshots</id>
      <url>https://repository.apache.org/snapshots/</url>
    </pluginRepository>
  </pluginRepositories>

  <build>
    <pluginManagement>
      <plugins>
    ...
    <artifactId>maven-surefire-plugin</artifactId>
      <!-- Use the SNAPSHOT version -->
      <version>3.0.0-SNAPSHOT</version>
      <configuration>
        <!-- Activate the use of TCP to transmit events to the plugin -->
        <forkNode implementation="org.apache.maven.plugin.surefire.extensions.SurefireForkNodeFactory"/>
      </configuration>
    </plugin>

原文由 Patrick 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题