maven 如何决定何时将目标文件夹用于类路径

Ale*_*ros 5 maven-3 maven exec-maven-plugin

我有一个关于 maven 如何在构建过程中计算类路径的问题。具体来说,什么控制何时使用“目标/类”以及何时使用存储库(本地/远程)中的“jar”。

我在版本 1.0.0-SNAPSHOT 上有一个项目,其中尚未安装/部署工件,因此某些存储库(远程或本地)中没有“jar”来解决它们。我想运行“generate-sources”而不在本地安装(没有' mvn install'运行)。

结构如下所示:

parent-prj
parent-prj/sub-prj
parent-prj/gen-src-prj <--- This depends on 'sub-prj'
Run Code Online (Sandbox Code Playgroud)

当我运行“ mvn -am -pl parent-prj/gen-src-prj generate-sources”以生成一些java文件时,它不起作用:

[ERROR] Failed to execute goal on project gen-src-prj: Could
 not resolve dependencies for project 
mygrp:gen-src-prj:jar:1.0.0-SNAPSHOT: 
Could not find artifact 
mygrp:sub-prj:jar:1.0.0-SNAPSHOT -> [Help 1]
Run Code Online (Sandbox Code Playgroud)

使用调试输出并添加“dependency:build-classpath”,我可以确认 maven 忽略了反应器中“sub-prj”的存在,并在它找不到的地方寻找“jar”。然而,该项目打印在反应堆摘要中:

[INFO] Reactor Summary:
[INFO] 
[INFO] parent-prj ..................................... SUCCESS [  0.625 s]
[INFO] sub-prj ........................................ SUCCESS [  0.018 s]
[INFO] gen-src-prj .................................... FAILURE [  0.040 s]
Run Code Online (Sandbox Code Playgroud)

我注意到的有趣的事情是运行 compile 目标工作正常!这使用sub-prj/target/classes(如dependency:build-classpath所示)并且生成源甚至编译它们都没有问题:“ mvn -am -pl parent-prj/gen-src-prj compile

所以这里是我想了解的要点:

  1. 为什么 compile 目标有效但 generate-sources 无效?
  2. maven 什么时候决定在 reactor 类路径上使用以前项目的输出文件夹而不是寻找 jar?
  3. 有没有办法让 generate-sources 直接运行,即使没有解决它的依赖关系?

关于 (3) 我的生成工具是一个由以下调用的实用程序:

    <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>exec-maven-plugin</artifactId>
        <version>1.6.0</version>
        <executions>
            <execution>
                <phase>generate-sources</phase>
                <goals>
                    <goal>java</goal>
                </goals>
            </execution>
        </executions>
Run Code Online (Sandbox Code Playgroud)

该工具读取 src/main/resources 中的一些 XML 并生成 Java 文件,并且在其类路径中不需要任何内容​​(因此不需要 maven 来解析它)。

另请注意,即使提供了 (3) 的解决方案,我也有兴趣了解 (1) 和 (2)。


编辑:根据评论请求,添加完整示例

父-prj/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>

    <groupId>mygrp</groupId>
    <artifactId>parent-prj</artifactId>
    <version>1.0.0-SNAPSHOT</version>

    <packaging>pom</packaging>

    <modules>
        <module>sub-prj</module>
    <module>gen-src-prj</module>
    </modules>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.3</version>
                    <configuration>
                        <source>1.8</source>
                        <target>1.9</target>
                        <encoding>UTF-8</encoding>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>
Run Code Online (Sandbox Code Playgroud)

父-prj/子-prj/pom.xml

<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
    xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>mygrp</groupId>
        <artifactId>parent-prj</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>

    <artifactId>sub-prj</artifactId>
</project>
Run Code Online (Sandbox Code Playgroud)

parent-prj/gen-src-prj/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>

    <parent>
        <groupId>mygrp</groupId>
        <artifactId>parent-prj</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>

    <artifactId>gen-src-prj</artifactId>

    <dependencies>
        <dependency>
            <groupId>mygrp</groupId>
            <artifactId>sub-prj</artifactId>
            <version>${project.version}</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.6.0</version>
                <executions>
                    <execution>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>java</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <includeProjectDependencies>false</includeProjectDependencies>
                    <includePluginDependencies>true</includePluginDependencies>
                    <mainClass>uk.co.real_logic.sbe.SbeTool</mainClass>
                    <systemProperties>
                        <systemProperty>
                            <key>sbe.output.dir</key>
                            <value>${project.build.directory}/generated-sources/java</value>
                        </systemProperty>
                        <systemProperty>
                            <key>sbe.validation.warnings.fatal</key>
                            <value>true</value>
                        </systemProperty>
                    </systemProperties>
                    <arguments>
                        <argument>${project.build.resources[0].directory}/Examples.xml</argument>
                    </arguments>
                    <workingDirectory>${project.build.directory}/generated-sources/java</workingDirectory>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>uk.co.real-logic</groupId>
                        <artifactId>sbe-tool</artifactId>
                        <version>1.7.10</version>
                    </dependency>
                </dependencies>
            </plugin>

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>build-helper-maven-plugin</artifactId>
                <version>3.0.0</version>
                <executions>
                    <execution>
                        <id>add-source</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>add-source</goal>
                        </goals>
                        <configuration>
                            <sources>
                                <source>target/generated-sources/java/</source>
                            </sources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>
Run Code Online (Sandbox Code Playgroud)

编辑:根据答案中的知识,我提出了这种解决方法,可以实现所需的行为。我在默认情况下处于活动状态的配置文件中列出了依赖项,然后使用另一个配置文件来运行没有处于活动状态的依赖项的 generate-sources,如下所示:

parent-prj/gen-src-prj/pom.xml

<profiles>
    <profile>
        <id>default</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <dependencies>
            <dependency>
                <groupId>mygrp</groupId>
                <artifactId>sub-prj</artifactId>
                <version>${project.version}</version>
            </dependency>
        </dependencies>
    </profile>

    <profile>
        <id>excludeDependency</id>
        <dependencies>
        </dependencies>
    </profile>
</profiles>
Run Code Online (Sandbox Code Playgroud)

要使用上述生成源,请使用: mvn -PexcludeDependency generate-sources

Sta*_*sev 5

Maven 只能引用当前会话(当前执行 shell 命令期间)生成的输出。它用最“成熟”的地方来寻找“输出”:

  • 如果compile运行 - 类最终位于目录中target/classes,因此其他模块可以引用它
  • 如果package运行 - 那么target/*.jar就会被创建,并且该 jar 文件最终会出现在类路径中
  • 如果install运行 - 那么 jar 文件最终会出现在本地存储库中 - 这就是最终出现在类路径上的内容

因此,有 3 个因素阻碍了你的任务:

  • maven-exec-plugin 需要依赖解析(正如@mondaka 所指出的)
  • 您的 module1 引用 module2
  • generate-sources在编译之前运行。因此 module2 尚未准备好用作依赖项。

compile因此,如果您想按照自己的方式进行操作 -每次使用默认生命周期中的任何内容时,您都必须至少运行一个阶段。或者您可以编写自己的插件,不需要依赖解析。


mon*_*aka 3

这个问题与一个开放的maven bug有关:

https://issues.apache.org/jira/browse/MNG-3283

该问题说:“只有当插件将自身绑定到生成源阶段并具有@requiresDependencyResolution时,才会出现问题”。

我检查过 exec-maven-plugin Mojo 确实有requiresDependencyResolution = ResolutionScope.TEST. 您可以在https://github.com/mojohaus/exec-maven-plugin/blob/master/src/main/java/org/codehaus/mojo/exec/ExecJavaMojo.java上看到这一点

然后,您唯一的选择是使用编译或处理类阶段。这是 2007 年的一个重大开放错误...