我一直在挣扎如何接近地狱。我有一个Maven IntelliJ Scala项目,它使用了一些aws sdk。最近添加了kinesis sdk,引入了不兼容的Jackson版本。
我的问题是:我如何系统地处理Jar地狱的问题?
我了解类加载器以及maven如何在重复的JAR之间进行选择,但我仍然不知道解决这个问题的实际步骤。
我目前的尝试是基于尝试和错误,我在这里用杰克逊的例子来概述:
最后,在比较了树输出之后,我尝试在POM中显式添加Jackson的最新工作版本,以触发maven依赖解析链中的优先级。如果最新版本不起作用,我将添加下一个最新版本,以此类推。
整个过程极其乏味。除了我问的具体问题,我还对其他人对这个问题的系统性方法感到好奇。有人有他们使用的资源吗?
根据我的经验,我没有发现任何完全自动化的方法,但我发现以下方法非常系统化,对我自己很有用:
首先,我试图有一个清晰的项目结构图,项目之间的关系,我通常使用Eclipse图形依赖视图,它告诉我,例如,如果一个依赖项与另一个冲突而被省略。此外,它告诉你项目已解决的依赖项。我真诚地不使用IntelliJ IDEA,但我相信它有类似的功能。
通常我会尝试将非常常见的依赖关系放在结构中更高的位置,并利用
在这篇Maven-Manage Dependencies博客文章中,你可以找到一个关于依赖关系管理的好教程。
当向我的项目中添加新的依赖项时,就像您的情况一样,我会注意它在我的项目结构中添加的位置,并做出相应的更改,但在大多数情况下,依赖项管理机制能够处理这个问题。
在这篇Maven Best Practices博客文章中,你可以找到:
Maven的dependencyManagement部分允许使用父pom。xml来定义可能在子项目中重用的依赖项。这避免了重复;如果没有dependencyManagement部分,每个子项目都必须定义自己的依赖项,并复制依赖项的版本、范围和类型。
显然,如果您需要项目依赖项的特定版本,您总是可以在层次结构的深层本地指定所需的版本。
我同意你的观点,这可能会很乏味,但依赖关系管理可以给你一个很好的帮助。
使用Maven助手插件通过排除旧版本的依赖项轻松解决所有冲突。
然后我查看Jackson文档,查看该方法是何时添加或删除的。这通常非常乏味,因为我手动检查每个版本的api文档(问题1:有更好的方法吗?)
为了检查API(中断)兼容性,有几个工具可以自动分析jars并为您提供正确的信息。从这篇Stack Overflow帖子中,有一些很好的提示,可以找到一些方便的工具。
JAPICC看起来相当不错。
然后,我使用mvn dependency:tree
来确定我实际使用的是哪个版本的Jackson(问题2:有没有一种自动的方法来询问maven使用的是哪个版本的jar,而不是梳理树输出?)
maven依赖关系树
无疑是一条可行之路,但您可以从一开始就筛选出范围,并使用其includes
选项,仅获取您真正想要的内容,如下所示:
mvn dependency:tree -Dincludes=<groupId>
注意:您还可以以group Id: artifactId: type: version
的形式向包括
选项提供更多信息,或者使用通配符,如*: artifactId
。
这似乎是一个小提示,但是在有许多依赖项的大型项目中,缩小其输出是非常有帮助的。通常,只要group Id
就足以作为过滤器,但是如果您正在寻找特定的依赖项,*: artifactId
可能是最快的。
如果您对按字母顺序排列的依赖项列表(而不是树)感兴趣(在许多情况下非常方便),那么以下内容也可能会有所帮助:
mvn dependency:list -Dsort=true -DincludeGroupIds=groupId
问题3:当依赖解析发生时,maven如何使用阴影罐中的库?和其他任何一样?
阴影罐子的意思可能是:
有人有他们使用的资源吗?
总的来说,你应该很好地理解Maven如何处理依赖关系和使用它提供的资源(它的工具和机制)。下面是一些要点:
dependencyManagement
无疑是本主题的切入点:在这里,您可以处理Maven依赖项中介,影响其对可传递依赖项、其版本和范围的决策。重要的一点是:添加到依赖项管理中的内容不会自动添加为依赖项dependencyManagement
只在项目的某个依赖项(如pom.xml
文件或通过可传递依赖项声明的)与其中一个条目匹配时才被考虑,否则它将被忽略。它是pom的重要组成部分。xml
因为它有助于管理依赖项及其可传递图,这就是为什么在父POM中经常使用xml的原因:您只想以集中的方式处理一个版本,例如,log4j
您想在所有Maven项目中使用哪个版本,您可以在公共/共享父pom及其依赖项管理
中声明它,并确保它将被如此使用。集中化意味着更好的治理和更好的维护
下面的示例将确保没有人(你、你的团队成员、你未来的自己)能够在编译
范围内添加一个众所周知的测试库:构建将失败。它确保jUnit
永远不会到达PROD(与你的war
打包,例如)
<plugin>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4.1<.version>
<executions>
<execution>
<id>enforce-test-scope</id>
<phase>validate</phase>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<bannedDependencies>
<excludes>
<exclude>junit:junit:*:*:compile</exclude>
<exclude>org.mockito:mockito-*:*:*:compile</exclude>
<exclude>org.easymock:easymock*:*:*:compile</exclude>
<exclude>org.powermock:powermock-*:*:*:compile</exclude>
<exclude>org.seleniumhq.selenium:selenium-*:*:*:compile</exclude>
<exclude>org.springframework:spring-test:*:*:compile</exclude>
<exclude>org.hamcrest:hamcrest-all:*:*:compile</exclude>
</excludes>
<message>Test dependencies should be in test scope!</message>
</bannedDependencies>
</rules>
<fail>true</fail>
</configuration>
</execution>
</executions>
</plugin>
看看这个插件提供的其他标准规则:在错误的情况下,许多规则可能有助于中断构建:
同样,一个公共的父pom可以包括这些机制中的一个以上(dependencyManagement
、enforcer插件、dependency族的属性),并确保遵守某些规则。你可能没有涵盖所有可能的场景,但它肯定会降低你感知和体验地狱的程度。
使用 我修改了以包含导入语句。因此,maven无法找到我试图使用并将其与项目链接的jar。 我向pom.xml文件添加了一个依赖项,如下所示:
如何将这个插件添加为依赖项和插件?我如何将此用作依赖项? 谢谢
我使用的是与Android Studio捆绑的Gradle构建系统。到目前为止,我能够使用存储在项目结构中的依赖关系构建多项目设置。我现在想使用maven依赖,但没有用。我写了一个非常简单的构建。总是失败的gradle文件: 显示以下消息: 到目前为止,我尝试过的任何产品都会发生这种情况。你知道怎么了吗? 谢谢
问题内容: 我正在运行一个依赖groovy 1.7-beta-1的项目。gmaven插件使用groovy 1.6版作为依赖项。在pom中,我在依赖性管理部分中将grooyv-all版本指定为: 但是,当我在调试模式下运行maven时,我看到groovy 1.6被用于对gmaven插件的依赖。我以为我的依赖项管理部分会重写此设置,因此它们都使用1.7-beta-1,但是由于常规版本不同,我遇到了错误
maven允许您在pom文件中定义: (A) - (B) /- 如果我把错误/未知的工件放在A类-maven肯定会失败。 如果我将错误/未知工件放在类别B上-maven只会在它影响类别A时失败(例如,A在上定义dep,B在
问题内容: 我有一个依赖关系如下: 当我部署一切正常时,这将拉下另一个引发ClassDefNotFound的依赖项。 我添加了两个依赖项,如下所示: 并且仍然面临着同样的问题,即:MVN带来下来不 我该如何解决? 编辑: 添加; 问题答案: 您可能有一个传递依赖项,另一个依赖项取决于您不需要的版本。 要获得所有直接和传递依赖关系的概述,请尝试: mvn依赖项:树 如果您发现同一依赖项的不同版本之间