我正试图克服众所周知的maven问题,在各种SO问题中都有描述,例如:
在此之前,我熟悉以下解决办法:
mvn install -这正是我想要避免的<skip>/<properties>/<profiles>的极其全面的项目配置maven-dependency-plugin将依赖项复制到模块文件夹中,同时打包和安装classpath从我的角度来看,所有这些解决方案看起来都很糟糕。
今天我读到了关于根-反应堆感知子文件夹生成 in maven-4的文章,但是maven-4还没有发布,我很有兴趣为maven-3找到一个解决方案。我进行了一些研究,并在maven-3中找到了几个有用的扩展点。
if ( workspace != null )
{
File file = workspace.findArtifact( artifact );
if ( file != null )
{
artifact = artifact.setFile( file );
result.setArtifact( artifact );
result.setRepository( workspace.getRepository() );
artifactResolved( session, trace, artifact, result.getRepository(), null );
continue;
}
}DefaultProjectDependenciesResolver.java
for ( RepositorySessionDecorator decorator : decorators )
{
RepositorySystemSession decorated = decorator.decorate( project, session );
if ( decorated != null )
{
session = decorated;
}
}最后,我实现了一个非常简单的maven扩展(github上的完整源代码):
@Component(role = RepositorySessionDecorator.class)
public class FakeRepositorySessionDecorator implements RepositorySessionDecorator {
@Requirement
protected ArtifactHandlerManager artifactHandlerManager;
@Override
public RepositorySystemSession decorate(MavenProject project, RepositorySystemSession session) {
String enabled = session.getUserProperties().get("fakerepo");
if (!"true".equalsIgnoreCase(enabled)) {
return null;
}
MavenProject root = project;
while (root != null && !root.isExecutionRoot()) {
root = root.getParent();
}
if (root != null) {
WorkspaceReader workspaceReader = session.getWorkspaceReader();
workspaceReader = new FakeWorkspaceReader(workspaceReader, root, artifactHandlerManager);
return new DefaultRepositorySystemSession(session)
.setWorkspaceReader(workspaceReader);
}
return null;
}
}这样做的想法是,如果开发人员在执行maven插件目标时指定了-Dfakeroot,那么我的扩展将workspace范围从single module扩展到project root,并且当请求新的扩展工作区时,尝试在子模块文件夹中查找打包的工件,因此命令的顺序如下:
mvn clean package
mvn exec:exec -pl submodule -Dfakeroot引导开发人员达到预期的结果。
问题是:如果我删除了指定-Dfakerepo的要求并在默认情况下启用了上述行为(即为所有maven目标和生命周期阶段应用新行为),我可以刹车什么?在我看来,在子模块文件夹中查找打包的工件总是比在本地存储库中更合理。还是我漏掉了什么?
UPD。
当我的扩展可能不像“预期”那样工作时,我发现了以下假设情况:
A和B,B依赖于A。A并发布了类似于mvn -am test -pl B的内容。在这种情况下,如果A是以前打包的,那么我的扩展强制maven使用陈旧的工件,但是默认实现会使用A/target/classes作为类路径条目,另一方面,A/target/classes可能包含陈旧的类(我们没有发出clean),因此在这种情况下,“默认实现”的行为也是不理想的。
UPD2。
似乎有必要解释一下为什么这个问题困扰着我。实际上,有几种“典型的”情况:
dev子模块中有一个特殊的dev目标,它执行DB迁移:<dependencies>
<dependency>
<groupId>tld.project</groupId>
<artifactId>another-submodule</artifactId>
</dependency>
</dependencies>
<execution>
<id>liquibase-update-primary</id>
<phase>install</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>java</executable>
<arguments>
<argument>-classpath</argument>
<!-- expecting to get module dependencies there -->
<classpath/>
<!-- main class -->
<argument>liquibase.integration.commandline.Main</argument>
<!-- covered by project properties -->
<argument>--changeLogFile=${primary.changeLogFile}</argument>
<!-- covered by profile properties -->
<argument>--url=${jdbc.url}</argument>
<argument>--driver=${jdbc.driver}</argument>
<argument>--username=${jdbc.username}</argument>
<argument>--password=${jdbc.password}</argument>
<argument>--logLevel=info</argument>
<argument>update</argument>
</arguments>
</configuration>
</execution>这在maven-3中显然不起作用,因为它希望在本地存储库中找到tld.project-another-submodule工件,但是可以使用maven-dependency-plugin执行以下技巧
<execution>
<id>liquibase-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<!--
now we may tell liquibase to load extra jars
from ${project.build.directory}/liquibase
-->
<groupId>tld.project</groupId>
<artifactId>another-submodule</artifactId>
<type>jar</type>
<destFileName>another-submodule.jar</destFileName>
<outputDirectory>${project.build.directory}/liquibase</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>mvn verify -pl it-submodule的内容,这从开发人员和CI的角度都是有用的:- Developers and DevOps may perform infrastructure-related steps somewhere between `package` and `verify` phases
- CI may run `verify` multiple times (yep, someone may think about how is it possible to reiterate failed tests in CI pipeline, however our goal is to run `verify` phase multiple times in a row to make sure there are no flapping tests)发布于 2022-08-14 21:15:05
最后,我得出以下结论:
local repository,并且执行mvn install现在是“安全的”。-Dimh.repository系统属性启用此模式maven-4一样,将反应堆工作空间扩展到整个项目,但也要注意补充工件,在这种情况下不需要mvn install,mvn package就足够了。-Dimh.workspace系统属性启用此模式下面的示例基于MNG-7527项目
-Dimh.repository模式:
% mvn clean install -Dimh.repository| grep Installing
[INFO] Installing MNG-7527/pom.xml to /Users/apanfilov/.m2/repository/../../work/gh/MNG-7527/target/local-repo/tel/panfilov/maven/mng7527/0.0.1-SNAPSHOT/mng7527-0.0.1-SNAPSHOT.pom
[INFO] Installing MNG-7527/mng7527-war/target/mng7527-war-0.0.1-SNAPSHOT.war to /Users/apanfilov/.m2/repository/../../work/gh/MNG-7527/target/local-repo/tel/panfilov/maven/mng7527-war/0.0.1-SNAPSHOT/mng7527-war-0.0.1-SNAPSHOT.war
[INFO] Installing MNG-7527/mng7527-war/pom.xml to /Users/apanfilov/.m2/repository/../../work/gh/MNG-7527/target/local-repo/tel/panfilov/maven/mng7527-war/0.0.1-SNAPSHOT/mng7527-war-0.0.1-SNAPSHOT.pom
[INFO] Installing MNG-7527/mng7527-war/target/mng7527-war-0.0.1-SNAPSHOT-classes.jar to /Users/apanfilov/.m2/repository/../../work/gh/MNG-7527/target/local-repo/tel/panfilov/maven/mng7527-war/0.0.1-SNAPSHOT/mng7527-war-0.0.1-SNAPSHOT-classes.jar
[INFO] Installing MNG-7527/mng7527-dep1/target/mng7527-dep1-0.0.1-SNAPSHOT.jar to /Users/apanfilov/.m2/repository/../../work/gh/MNG-7527/target/local-repo/tel/panfilov/maven/mng7527-dep1/0.0.1-SNAPSHOT/mng7527-dep1-0.0.1-SNAPSHOT.jar
[INFO] Installing MNG-7527/mng7527-dep1/pom.xml to /Users/apanfilov/.m2/repository/../../work/gh/MNG-7527/target/local-repo/tel/panfilov/maven/mng7527-dep1/0.0.1-SNAPSHOT/mng7527-dep1-0.0.1-SNAPSHOT.pom
[INFO] Installing MNG-7527/mng7527-dep2/target/mng7527-dep2-0.0.1-SNAPSHOT.jar to /Users/apanfilov/.m2/repository/../../work/gh/MNG-7527/target/local-repo/tel/panfilov/maven/mng7527-dep2/0.0.1-SNAPSHOT/mng7527-dep2-0.0.1-SNAPSHOT.jar
[INFO] Installing MNG-7527/mng7527-dep2/pom.xml to /Users/apanfilov/.m2/repository/../../work/gh/MNG-7527/target/local-repo/tel/panfilov/maven/mng7527-dep2/0.0.1-SNAPSHOT/mng7527-dep2-0.0.1-SNAPSHOT.pom
% mvn clean package -f mng7527-dep1 -Dimh.repository
[INFO] [IMH] workspace extension disabled
[INFO] [IMH] setting up overlay repository
[INFO] [IMH] using root project target folder as overlay repository: MNG-7527/target/local-repo
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------< tel.panfilov.maven:mng7527-dep1 >-------------------
[INFO] Building mng7527-dep1 0.0.1-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ mng7527-dep1 ---
[INFO] Deleting MNG-7527/mng7527-dep1/target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ mng7527-dep1 ---
[INFO] skip non existing resourceDirectory MNG-7527/mng7527-dep1/src/main/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ mng7527-dep1 ---
[INFO] No sources to compile
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ mng7527-dep1 ---
[INFO] skip non existing resourceDirectory MNG-7527/mng7527-dep1/src/test/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ mng7527-dep1 ---
[INFO] No sources to compile
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ mng7527-dep1 ---
[INFO] No tests to run.
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ mng7527-dep1 ---
[INFO] Building jar: MNG-7527/mng7527-dep1/target/mng7527-dep1-0.0.1-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] -------------------------------------------------------------------------Dimh.workspace模式:
% mvn clean package -f mng7527-dep1 -Dimh.workspace
[INFO] [IMH] repository extension disabled
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------< tel.panfilov.maven:mng7527-dep1 >-------------------
[INFO] Building mng7527-dep1 0.0.1-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ mng7527-dep1 ---
[INFO] Deleting MNG-7527/mng7527-dep1/target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ mng7527-dep1 ---
[INFO] skip non existing resourceDirectory MNG-7527/mng7527-dep1/src/main/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ mng7527-dep1 ---
[INFO] No sources to compile
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ mng7527-dep1 ---
[INFO] skip non existing resourceDirectory MNG-7527/mng7527-dep1/src/test/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ mng7527-dep1 ---
[INFO] No sources to compile
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ mng7527-dep1 ---
[INFO] No tests to run.
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ mng7527-dep1 ---
[INFO] Building jar: MNG-7527/mng7527-dep1/target/mng7527-dep1-0.0.1-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------发布于 2022-08-07 01:27:23
井,
我查看了这是如何实现的在maven-4中的内容,并得出了一个结论,即它不能像预期的那样工作:
-f还是-pl --与我所做的完全相同。target/classes中打包工件和类的修改日期,但与源代码无关)--这实际上是我Q的答案。maven-4试图获取主工件,而不管指定了什么分类器,如果失败,则返回到~/.m2/repository - filed MNG-7527。target/classes或target/test-classes -在大多数情况下导致异常的情况下,“Arti实物尚未打包。当用于反应堆工件时,应在打包后执行副本:请参阅MDEP-187”。https://stackoverflow.com/questions/73255826
复制相似问题