良い機会は、私は女性の同僚Mavenの解決の競合を助けたいです

いずれかの最も重要な原因の物語

いずれかのジョブは、女の子は絶対的な優位性を持っています。プログラムはそれの世話、間違いなく肉とジャガイモであることを女性の猿がある場合部門で、IT業界は言うまでもありません。

1時前に、妹が最初に来た、スタイルが急に上の写真になり、そしてその周りに集まったが、最終結果は理想的ではない、私はまだ(ここで少し自慢を)行動に行かなければならない問題が発生しました。

エラーが表示され、にjava.lang.ClassNotFoundExceptionまたはJARパッケージが欠落している、または競合です:妹が問題ジャーパッケージの競合が発生し、エラーメッセージが原因です。

実際には、多くの場合など、この競合の作業で問題が発生しますによって引き起こさ:、java.lang.NoSuchMethodErrorの例外情報は、紛争の結果であるが、競合を解決したいがどこ(がらくたのような)紛争を知っている必要があります。

それらのほとんどは、この記事では、Mavenのもたらすに依存し、競合を解決する方法を説明している今日、依存Jarファイルを管理するためにMavenを使用しています。


MavenのREADME

MavenはJavaプロジェクトを構築し、管理するためのツールです。Javaの、Mavenのほぼすべてのアクセスおよび使用の方向のために。もちろん、このようなAntとのGradleなどの代わりにMavenの他のツールは、あります。

それはGradleの依存関係の管理を使用することで行うように、前のGrailsビルドのJava Webプロジェクトとの接触を持っています。ちょうどAntはまた、いくつかの古いプロジェクトで作業しているときのためと見られてきた、背中を見たことはほとんどありません。

Mavenのドキュメント住所:https://maven.apache.org [1]

Mavenを使用すると、私たちはすぐに新しいプロジェクトを構築することができ、そして複数の三者の枠組みを統合して管理することが容易です。我々はフレームワークを必要とする場合は、このフレームワークの情報を検索するために行くことができ、その後、プロジェクトにconfigureがすることができます。

住所をサーチします:https://mvnrepository.com [2]

たとえば、私たちは、ドキュメントの依存春のバージョンを取得するに加えて、春ブーツを、使用したい、あなたは下に示すように、対応するバージョンを選択し、検索するために所有することができます:

あなたはMavenのは、依存的であるデフォルトを見ることができ、簡単にすることができ、プロジェクトにpom.xmlファイルに全体のコンテンツの依存関係をコピーします。右側の依存などのGradleや上のように他の多くの方法が、あります。


Mavenは転送を依存しています

ジャーパッケージの競合が理解し、基本的な知識の下の最初の前に解決するとき行うことを問題Mavenの依存関係の管理を解決する方法今日のメインスピーカーの下で。

図に示す変速機のMavenの依存性は、最初のアイテムは春とB依存グアバ二つのフレームです。プロジェクトはその後、順番に、項目Bに依存して、項目Aは、したがって、春とグアバに2つのフレームを依存します。


ジャーパッケージ選択ロジック依存転送

プロジェクトをリードする従属転送が瓶の他の多くのバージョンに依存し、このような状況のパッケージを選択する方法ジャー?

2つのルールがあります。

  • 過去の優先順位からの距離が異なります

  • 同じ距離、かつての優先順位

以下に示すように、プロジェクト依存アイテムAとアイテムB、A及びBはそれぞれ、依存グアバの、しかしレベルに依存するが、項目Bの浅いレベルは、それがGuava18.0が好ましいです。

場合注文項目Bで同じ嗜好を示すように、上記に定義される距離、プロジェクトAとプロジェクトBのそれぞれと、上記項目AのGuava18.0 Guava15.0依存バージョン、私たちは、Guava15.0バージョンを優先させて頂きます。

推移性に依存することによって、このような図自体に項目Aの下などの問題ジャーパッケージの競合が、プロジェクトAもGuava15に依存しますので、こと、依存Guava18.0内のアイテムB、Guava15.0を頼って、次に項目Bに依存していることが多い原因0.0とGuava18.0。

如果刚好用到了高版本不兼容低版本的方法和类时,就会出现选择错误,因为 Maven 会根据依赖树的深浅来选型浅的依赖,也就是 15.0。


冲突案例

下面就是一个典型的 Jar 包冲突问题,当一个 Jar 有多个版本的时候,就会出现冲突。

错误信息可以看到 com.google.common.collect.FluentIterable.concat 这个方法找不到,目前是从 guava-18.0.jar 中加载的,这种问题我们改怎么解决呢?

Description:
An attempt was made to call the method com.google.common.collect.FluentIterable.concat(Ljava/lang/Iterable;Ljava/lang/Iterable;)Lcom/google/common/collect/FluentIterable; but it does not exist. Its class, com.google.common.collect.FluentIterable, is available from the following locations:
    jar:file:/Users/yinjihuan/.m2/repository/com/google/guava/guava/18.0/guava-18.0.jar!/com/google/common/collect/FluentIterable.class
It was loaded from the following location:
    file:/Users/yinjihuan/.m2/repository/com/google/guava/guava/18.0/guava-18.0.jar


Action:
Correct the classpath of your application so that it contains a single, compatible version of com.google.common.collect.FluentIterable


解决思路之悬丝诊脉

找出冲突的 Jar,看看当前项目中依赖了哪几个版本。

  

Eclipse

在 Eclipse 中可以双击 pom 文件,进入 Dependency 视图,输入你要搜索的 jar 名称进行搜索,就可以看出当前项目中哪些框架依赖了你搜索的 jar,什么版本都能知道。

Idea

Idea 中可以安装 maven helper 插件来查看相关依赖信息,默认选中 Conflicts 会展示当前项目存在冲突的依赖,当然我们也可以直接查看树形的依赖关系去分析冲突。


Maven 命令

不用不借助于开发工具的插件,我们可以直接用 Maven 命令来查看当前项目的依赖关系,命令行进入到你要分析的项目目录下,执行下面的命令将分析结果保存到文件中:

mvn dependency:tree > tree.log

执行完之后依赖的信息结构如下:

搜索了下 guava,发现在 smjdbctemplate 中依赖了 18.0 版本,这个框架是我自己基于 jdbctemplate 封装的一个框架。


解决思路之察言观色

其实很明显,错误信息已经告诉我们 18.0 中找不到 concat 方法,所以 18.0 肯定是不能用的,通过前面的分析,找到了直接依赖 guava.18.0.jar 的是 smjdbctemplate,解决办法就是将 smjdbctemplate 中的 guava 排除掉。

<dependency>
  <groupId>com.github.yinjihuan</groupId>
  <artifactId>smjdbctemplate</artifactId>
  <version>1.1</version>
  <exclusions>
    <exclusion>
      <groupId>com.google.guava</groupId>
      <artifactId>guava</artifactId>
    </exclusion>
  </exclusions>
</dependency>

还有就是根据依赖树的深浅度来判断当前项目依赖的是哪个版本,如下图:

18.0 是最浅的,肯定是依赖它,其实在 Eclipse 里面直接查看 Maven Dependencies 就可以指定当前项目依赖哪些框架和版本信息,如下图:

当我们排除掉 18.0 后再来看依赖的版本是 20.0,如下图:

根据依赖树的深浅度,20.0 和 19.0 都是一样的层级,但是 20.0 在 19.0 前面,所以优先选择 20.0 版本。

再来看项目中的 pom 文件,发现 swagger 的声明顺序在 apollo 的前面。

如果我们把顺序调整一下,那么就会依赖 19.0 的版本。


总结

通过我仔细耐心的讲解,妹子终于自己解决了遇到的问题,后面的事你们就猜去吧。????

这种问题其实无法避免,当你依赖的三方框架越多的时候,冲突的可能性就越大。碰到问题的时候沉下心来仔细分析,借助于工具帮助你排查问题。

当然我们在自己项目中去依赖三方的框架,也是要注意版本的问题,特别是对于多模块的项目,每个子模块都去依赖不同的版本,这样很容易出问题,一般建议在父 pom 中 dependencyManagement 来统一管理版本,子模块直接统一使用父 pom 中定义好的版本。

还有就是可以使用 optional 来设置可选依赖,比如说你要封装一个通用的模块 Common,这个模块中有很多通用的功能,项目 A 依赖只需要使用功能 A,项目 B 依赖只需要使用功能 B。

每个功能都依赖了三方的 Jar,这个时候如果你不做任何处理,只要依赖了你这个通用的模块 Common,那么也就会间接依赖这两个功能的第三方 Jar。

这个时候可以通过设置 optional=true 来解决这个问题,我依赖了你的通用模块 Common,如果我要使用 A 功能,那么我必须显示依赖 A 功能需要的三方依赖才可以。

参考资料

[1] maven: https://maven.apache.org/
[2] mvnrepository: https://mvnrepository.com/

有道无术,术可成;有术无道,止于术

欢迎大家关注Java之道公众号

好文章,我在看❤️

发布了94 篇原创文章 · 获赞 4220 · 访问量 78万+

おすすめ

転載: blog.csdn.net/hollis_chuang/article/details/104368185