当 fork 选项用于 maven-compiler-plugin 时没有详细输出

No verbose output when fork option is used for maven-compiler-plugin

如果我想查看编译器输出,通常我会为 maven-compiler-plugin 启用 verbose 选项。

但是,当它与fork选项一起使用时,这将不起作用。 编译是在另一个进程中运行,似乎maven没有将输出重定向到控制台。

我的代码示例如下所示

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.5.1</version>
            <configuration>
                <fork>true</fork>
                <verbose>true</verbose>
            </configuration>
        </plugin>
    </plugins>
</build>

有谁知道我怎样才能看到编译过程中发生了什么?

在此 link 中,我看到鼓励同时使用这两个选项(fork 和 verbose)。

但是,正如我已经提到的,实际上这两个选项在使用时效果不佳 在一起。

更新(25/06/2016)plexus-compilerThis issue 已修复,问题中的给定代码将从版本开始运行2.8.


阅读源代码后,这是 plexus-compiler 2.7 的一个错误,它是 maven-compiler-plugin 3.5.1 内部用于编译 Java 源代码的库.

所以它在代码中是这样的:maven-compiler-plugin 填充一个名为 CompilerConfiguration and sets its fork and verbose according to the given configuration element in the POM. The verbose element is correctly read and added to the compiler arguments:

的对象
if ( config.isVerbose() )
{
    args.add( "-verbose" );
}

然后,有一个开关depending on whether we're forking or not


如果不是,我们最终会归结为调用 javac 的代码及其输出 is stored in the compilation result:

ok = (Integer) compile.invoke( null, new Object[]{ args, new PrintWriter( out ) } );

messages = parseModernStream( ok.intValue(), new BufferedReader( new StringReader( out.toString() ) ) );

终于returned with:

return new CompilerResult( success, messages );

到目前为止一切顺利,maven-compiler-plugin 将循环处理这些消息并将它们输出到控制台。由于设置了 verbose 参数,我们将收到所有消息。


如果是,则检索可执行文件(默认为 PATH 中的 javac)并 the compiler arguments are correctly set:

for ( String key : config.getCustomCompilerArgumentsAsMap().keySet() )
{
    if ( StringUtils.isNotEmpty( key ) && key.startsWith( "-J" ) )
    {
        cli.addArguments( new String[]{ key } );
    }
}

我们可以通过 运行 Maven 在调试模式下使用 -X 确认这一点,我们将看到消息:

[DEBUG] Excutable: 
[DEBUG]  "C:\Program Files\Java\jdk1.8.0_74\bin\javac.exe"
[DEBUG] Command line options:
[DEBUG] -d ... -classpath ... -sourcepath ... -s ... -g -target 1.8 -source 1.8 -verbose

注意最后的 -verbose

然后,这就是错误。标准输出将存储在 out 变量

CommandLineUtils.StringStreamConsumer out = new CommandLineUtils.StringStreamConsumer();

正确用作编译方法的参数,but completely ignored afterwards:

returnCode = CommandLineUtils.executeCommandLine( cli, out, err );

messages = parseModernStream( returnCode, new BufferedReader( new StringReader( err.getOutput() ) ) );

注意稍后将形成插件输出的消息是如何只填充错误而不是标准输出的。简单地说:标准输出在详细模式下被正确设置,但它被忽略并且没有被翻译成正确的编译结果。


我没有看到解决方法(除了不分叉)。我在他们的 GitHub 中创建了 issue 20 来跟踪这个。