当fork选项用于maven-compiler-plugin

时间:2016-04-22 19:04:51

标签: maven 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)。

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

1 个答案:

答案 0 :(得分:4)

更新(2016年6月25日)plexus-compiler的{​​{3}}已修复,问题中的给定代码将从2.8版开始生效。

阅读完源代码后,这是This issue 2.7的错误,它是maven-compiler-plugin 3.5.1内部用来编译Java源代码的库。

在代码中它是这样的:maven-compiler-plugin填充一个名为plexus-compiler的对象,并根据POM中给定的配置元素设置其CompilerConfigurationforkverbose元素verbose

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

然后,有一个开关is correctly read and added to the compiler arguments

如果我们不是,我们最终会转到调用javac及其输出depending on whether we're forking or not的代码:

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

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

最后is stored in the compilation result

return new CompilerResult( success, messages );

到目前为止,maven-compiler-plugin将围绕这些消息并将它们输出到控制台。由于设置了verbose参数,我们将收到所有消息。

如果是,则检索可执行文件(默认为PATH中的javac)并returned with

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

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

[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

然后,这就是错误。标准输出将存储在the compiler arguments are correctly set变量

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

正确用作编译方法的参数out

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

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

请注意,稍后将形成插件输出内容的消息仅填充错误而不是标准输出。简而言之:标准输出在详细模式下正确设置,但忽略它并且不会转换为正确的编译结果。

我没有看到解决方法(除非分叉)。我在他们的GitHub中创建了but completely ignored afterwards来跟踪它。