Surefire Maven 插件:"Corrupted STDOUT by directly writing to native stream in forked JVM"

Surefire Maven plugin: "Corrupted STDOUT by directly writing to native stream in forked JVM"

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

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

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

Corrupted STDOUT by directly writing to native stream in forked JVM

If your tests use native library which prints to STDOUT this warning message appears because the library corrupted the channel used by the plugin in order to transmit events with test status back to Maven process. It would be even worse if you override the Java stream by System.setOut because the stream is also supposed to be corrupted but the Maven will never see the tests finished and build may hang.

This warning message appears if you use FileDescriptor.out or JVM prints GC summary.

In that case the warning is printed "Corrupted STDOUT by directly writing to native stream in forked JVM", and a dump file can be found in Reports directory.

If debug level is enabled then messages of corrupted stream appear in the console.

它指的是一些本机库直接打印到 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 发行版)。

我是 运行 来自 Eclipse 的 Maven,使用 pom.xml 文件上的“运行 As...”上下文菜单选项,但在 [=43] 时获得相同的结果=] 它在控制台上。

在对这个问题发表第一条评论之前,我从未听说过 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>

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

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

对我来说,它是将故障保护插件从 2.22.0 更新到 2.22.2

为我解决的是将 maven surefire 插件升级到 2.22.2

较新的 Surefire 插件版本完全是错误和损坏的。 对我来说(一直测试到 Java 12)唯一的解决办法是坚持使用 2.20

也不要使用 2.20.1,它因 NPE 而失败,尽管它可能特定于特定测试,但我没有时间研究它。

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

According to the Jira issue 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 而不是标准 output/error 来获取测试中引发的事件。配置更改如下:

在我的 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>

当 运行 在 Intelij Idea 中构建 Maven 时,我遇到了这个错误。我在单独的 windows 中打开了几个项目,并且在不同的项目中出现了其他奇怪的错误。

通过关闭所有 Intellij Idea windows 并重新打开项目解决了我的问题。没有更改依赖项版本。

对我来说是将 org.testng 升级到最新版本 (7.3.0)

None 列出的答案对我们的案例有所帮助。在我们从 Java 8 升级到 Java 11.

后问题开始了

注意:在我们的案例中无法更新 Surefire 插件,因为它破坏了我们项目中测试所依赖的某些机制 - 检查问题花费的时间太长,因此我们开始在 Jacoco 中找出该行为的根本原因。

经过一些调试和 JVM 转储后,我们找到了原因:在我们的例子中,我们在 class 路径上有 JavaFX 依赖项,这些依赖项由解析器实用程序自动加载。在启用 jacoco 的情况下加载这些 classes 导致 JVM 崩溃(没有 jacoco - 在我们的例子中封装在配置文件“coverage”中 - 运行 没问题)。从 JavaFX 库中排除 classes 的加载(在我们的例子中不需要)解决了这个问题。测试现在 运行 正常,没有 JVM 崩溃。

在我们的案例中,导致 JVM 崩溃(或至少是之前加载的最后一次)的确切 class 是:com.sun.javafx.logging.jfr.JFRPulsePhaseEvent 罐子:javafx-base-12-win.jar

提示:在许多 IDE 中,您可以使用特定配置文件调试 Maven 构建并检查到底发生了什么。

使用 Jacoco 0.8.6 和 Surefire 插件 2.22.2

如果您无法升级到最新的 JaCoCo 版本,我也可以通过将 forkCount 设置为 0 来为我的项目修复此问题:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.22.0</version>
  <configuration>
    <forkCount>0</forkCount>
  </configuration>
</plugin>

我也偶遇这个问题

我正在使用

IntelliJ IDEA 2020 (Community Edition)
Surefire plugin (3.0.0-M5)
Maven 3.3.9
AdoptOpenJDK 11

通常发生时 Windows 10 分钟后显示 美丽的死亡蓝屏。

然后重启后一切恢复正常

在我的例子中,我将我的开发转移到了一台新 PC 上,并且我的 Maven-repo 中还没有我们所有的公司库依赖项。所以当 Maven 运行 缺少这样一个库时,我不得不用 mvn install:install-file ....

安装它

因此,阅读最新的 surefire-logs 很重要,因为它暗示了这些事情。

不知道,为什么 surefire-plugin 不只是将 STDOUT 上的冲突行打印到控制台,所以不到一秒钟就会很明显。

我们正在使用 log4j 后端,也可以使用 follow 设置为 true 来修复它。

<Appenders>
    <Console name="Console" target="SYSTEM_OUT">
        <PatternLayout pattern="${messagePattern}" />
        <follow>true</follow>
    </Console>
</Appenders>

(我们有相同的错误消息,但没有涉及 jacoco。但我可以确认将 maven-surefire-plugin 中的 forkNode 设置为 TCP 也确实有效。)