![](/img/trans.png)
[英]How can Maven Shade Plugin relocate multiple versions of a transitive dependency?
[英]How to avoid non fixed versions in any (transitive) dependency
我想知道是否有一個 Maven 強制執行規則或類似的東西來檢查我的項目在項目(傳遞)依賴項中是否有任何“打開”(非固定)版本。
我想用 maven 歸檔一個穩定的可重現構建,但如果我的依賴項例如聲明其依賴項之一的開放式版本范圍,我不能保證這一點。
該傳遞依賴項的新版本將改變我的“否則”未觸及構建的輸出。
我還沒有找到任何符合此要求的財產或執法者規則。
有人知道如何用 maven 完成這樣的要求嗎?
最好的辦法是采用mvn dependency:list
並修復<dependencyManagement>
中的所有這些版本
短篇故事
(仍然)“可能”確定是否存在具有開放版本范圍的傳遞依賴項:
...
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-assertions-generator</artifactId>
<version>2.1.0</version>
</dependency>
...
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<!-- version makes sense -->
<version>2.6</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
...
% mvn -X assembly:single -Dassembly.dryRun=true| grep 'setting version to'
[DEBUG] org.assertj:assertj-core:jar:2.9.1:compile
(setting version to: 2.9.1 from range: [2.1.0,2.99.0])
很長的故事
maven 3
采用了Aether 項目,不幸的是,沒有選項可以攔截或影響依賴解析過程,基本上“項目對象模型”提供了有關直接依賴的信息,但是關於傳遞依賴的詳盡信息隱藏在aether
后面,這就是原因為什么你沒有在 maven 插件中找到想要的功能。
我成功地從maven-assembly-plugin
獲得了一些相關信息,因為它的舊版本仍然與現代 maven 兼容,因此,從技術上講,仍然可以實現具有所需功能的插件,甚至可以利用gmavenplus-plugin
並編寫 groovy腳本:
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<version>1.13.1</version>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<bindAllProjectProperties>true</bindAllProjectProperties>
<scripts>
<script><![CDATA[
def resolver = session.container.lookup(org.apache.maven.artifact.resolver.ArtifactResolver.class)
def artifacts = resolver.resolveTransitively(
project.dependencyArtifacts,
project.artifact,
project.managedVersionMap,
session.getLocalRepository(),
project.remoteArtifactRepositories,
null
).artifacts.findAll {
it.versionRange && it.versionRange.restrictions
&& !it.versionRange.recommendedVersion
&& (it.versionRange.restrictions.size() > 1
|| it.versionRange.restrictions[0].lowerBound
|| it.versionRange.restrictions[0].upperBound
)
}.each {
println "Found bad guy: $it -> $it.versionRange"
}
]]></script>
</scripts>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>3.0.9</version>
<type>pom</type>
<scope>runtime</scope>
</dependency>
</dependencies>
</plugin>
% mvn initialize
[INFO] Scanning for projects...
...
[INFO] Using plugin classloader, includes GMavenPlus and project classpath.
[INFO] Using Groovy 3.0.9 to perform execute.
Found bad guy: org.assertj:assertj-core:jar:2.9.1:compile -> [2.1.0,2.99.0]
要獲得可重現的構建,您可能應該在dependencyManagement
中修復所有直接和間接依賴項的版本。
這將允許:
為了不要忘記在dependencyManagement
中展平所有依賴項,您可以使用maven-enforcer-plugin
中的banTransitiveDependencies
規則。
如果您有很多依賴項,管理起來可能會很痛苦,但也許您可以創建一個腳本來從mvn dependency:list
生成 dependencyManagement 部分
我為此為maven-dependency-plugin
創建了一個新功能請求: https ://issues.apache.org/jira/browse/MDEP-811
(另見: https ://stackoverflow.com/a/35849405/5088764)
上述解決方案有效,但理想情況下我們只想修復以下版本:
您可以為依賴收斂添加規則,但 AFAIK 沒有一種noRangeVersion
規則。
我為此為maven-enforcer-plugin
創建了一個新功能請求: https ://issues.apache.org/jira/browse/MENFORCER-427
但是等待也許這可以創建您自己的規則: https ://maven.apache.org/enforcer/enforcer-api/writing-a-custom-rule.html(或者也許有人已經這樣做了?)
我沒有對此進行測試,但也許dependency-lock-maven-plugin可以幫助解決這個問題。
請參閱: https ://stackoverflow.com/a/54580971/5088764
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.