maven如何决定何时使用目标文件夹作为类路径
How does maven decide when to use the target folder for classpath
我有一个关于 Maven 在构建过程中如何计算 class 路径的问题。具体来说,是什么控制何时使用 "target/classes" 以及何时使用存储库 (local/remote) 中的 "jar"。
我有一个版本为 1.0.0-SNAPSHOT 的项目,其中的工件 installed/deployed 所以在某些存储库(远程或本地)中没有 "jar" 来解决它们。我想 运行 "generate-sources" 不在本地安装(没有 'mvn install
' 运行)。
结构如下所示:
parent-prj
parent-prj/sub-prj
parent-prj/gen-src-prj <--- This depends on 'sub-prj'
当我 运行 “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]
使用调试输出并添加 "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]
我注意到的有趣的事情是 运行编译目标工作正常!这使用 sub-prj/target/classes
(如 dependency:build-classpath 所示)并且生成源代码甚至编译它们都没有问题:“mvn -am -pl parent-prj/gen-src-prj compile
”
所以这里是我想了解的要点:
- 为什么编译目标有效但生成源无效?
- maven 在什么时候决定使用 reactor classpath 上以前项目的输出文件夹而不是寻找 jar?
- 有没有办法让生成源直接运行,即使没有解决它的依赖关系?
关于 (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>
该工具读取 src/main/resources 中的一些 XML 并生成 Java 文件并且在其 class 路径中不需要任何内容(因此不需要 maven解决它)。
另请注意,即使提供了 (3) 的解决方案,我也有兴趣了解 (1) 和 (2)。
编辑:根据评论请求,添加完整示例
parent-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>
parent-prj/sub-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>
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>
编辑:根据答案中的知识,我想出了这个解决方法,可以实现所需的行为。我在默认情况下处于活动状态的配置文件中列出依赖项,然后使用另一个配置文件 运行 generate-sources with no dependencies active,如下所示:
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>
要生成上面的源代码,请使用:mvn -PexcludeDependency generate-sources
此问题与一个开放的 maven 错误有关:
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 年的主要开放错误...
Maven 只能引用当前会话中生成的输出(在当前执行 shell 命令期间)。它用最“成熟”的地方去寻找“输出”:
- 如果
compile
是 运行 - 类 最终出现在 target/classes
目录中,因此其他模块可以引用
- 如果
package
是 运行 - 那么 target/*.jar
被创建并且这个 jar 文件最终出现在类路径中
- 如果
install
是 运行 - 那么 jar 文件最终会出现在本地存储库中 - 这就是最终出现在类路径中的内容
所以有 3 个因素阻碍了您的任务:
- maven-exec-plugin 需要依赖解析(正如@mondaka 所指出的)
- 您的模块 1 引用了模块 2
generate-sources
编译前是运行。因此 module2 尚未准备好用作依赖项。
因此,如果您想按照自己的方式进行操作 - 每次使用默认生命周期中的任何内容时,您都必须 运行 至少 compile
阶段。或者您可以编写自己的不需要依赖项解析的插件。
我有一个关于 Maven 在构建过程中如何计算 class 路径的问题。具体来说,是什么控制何时使用 "target/classes" 以及何时使用存储库 (local/remote) 中的 "jar"。
我有一个版本为 1.0.0-SNAPSHOT 的项目,其中的工件 installed/deployed 所以在某些存储库(远程或本地)中没有 "jar" 来解决它们。我想 运行 "generate-sources" 不在本地安装(没有 'mvn install
' 运行)。
结构如下所示:
parent-prj
parent-prj/sub-prj
parent-prj/gen-src-prj <--- This depends on 'sub-prj'
当我 运行 “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]
使用调试输出并添加 "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]
我注意到的有趣的事情是 运行编译目标工作正常!这使用 sub-prj/target/classes
(如 dependency:build-classpath 所示)并且生成源代码甚至编译它们都没有问题:“mvn -am -pl parent-prj/gen-src-prj compile
”
所以这里是我想了解的要点:
- 为什么编译目标有效但生成源无效?
- maven 在什么时候决定使用 reactor classpath 上以前项目的输出文件夹而不是寻找 jar?
- 有没有办法让生成源直接运行,即使没有解决它的依赖关系?
关于 (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>
该工具读取 src/main/resources 中的一些 XML 并生成 Java 文件并且在其 class 路径中不需要任何内容(因此不需要 maven解决它)。
另请注意,即使提供了 (3) 的解决方案,我也有兴趣了解 (1) 和 (2)。
编辑:根据评论请求,添加完整示例
parent-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>
parent-prj/sub-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>
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>
编辑:根据答案中的知识,我想出了这个解决方法,可以实现所需的行为。我在默认情况下处于活动状态的配置文件中列出依赖项,然后使用另一个配置文件 运行 generate-sources with no dependencies active,如下所示:
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>
要生成上面的源代码,请使用:mvn -PexcludeDependency generate-sources
此问题与一个开放的 maven 错误有关:
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 年的主要开放错误...
Maven 只能引用当前会话中生成的输出(在当前执行 shell 命令期间)。它用最“成熟”的地方去寻找“输出”:
- 如果
compile
是 运行 - 类 最终出现在target/classes
目录中,因此其他模块可以引用 - 如果
package
是 运行 - 那么target/*.jar
被创建并且这个 jar 文件最终出现在类路径中 - 如果
install
是 运行 - 那么 jar 文件最终会出现在本地存储库中 - 这就是最终出现在类路径中的内容
所以有 3 个因素阻碍了您的任务:
- maven-exec-plugin 需要依赖解析(正如@mondaka 所指出的)
- 您的模块 1 引用了模块 2
generate-sources
编译前是运行。因此 module2 尚未准备好用作依赖项。
因此,如果您想按照自己的方式进行操作 - 每次使用默认生命周期中的任何内容时,您都必须 运行 至少 compile
阶段。或者您可以编写自己的不需要依赖项解析的插件。