Maven 问题解决

本文最后更新于:2024年9月8日 晚上

Maven 问题解决

依赖冲突

原因:假设有如下依赖关系:

  • A->B->C->D1(log 15.0):A中包含对B的依赖,B中包含对C的依赖,C中包含对D1的依赖,假设是D1是日志jar包,version为15.0
  • E->F->D2(log 16.0):E中包含对F的依赖,F包含对D2的依赖,假设是D2是同一个日志jar包,version为16.0
  • 当pom.xml文件中引入A,E两个依赖后,根据Maven传递依赖的原则,D1,D2都会被引入,而D1,D2是同一个依赖D的不同版本,当我们在调用D2中的method1()方法,而D1中是15.0版本(method1可能是D升级后增加的方法),可能没有这个方法,这样JVM在加载A中D1依赖的时候,找不到method1方法,就会报NoSuchMethodError的错误,此时就产生了jar包冲突。

解决方法

  • 手动排除:在pom.xml中使用<exclusion>标签去排除冲突的jar包。
1
2
3
4
5
6
7
8
9
10
11
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>1.4.4.RELEASE</version>
<exclusions>
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion>
</exclusions>
</dependency>
  • 版本锁定:一般用在继承项目的父项目中。
    • 正常项目都是多模块的项目,如moduleA和moduleB共同依赖X这个依赖的话,那么可以将X抽取出来,同时设置其版本号,这样X依赖在升级的时候,不需要分别对moduleA和moduleB模块中的依赖X进行升级,避免太多地方引用X依赖的时候忘记升级造成jar包冲突,这也是实际项目开发中比较常见的方法。
  • 首先定义一个父pom.xml,将公共依赖放在该pom.xml中进行声明:
1
2
3
4
5
6
7
8
9
10
11
12
13
<properties>
<spring.version>spring4.2.4</spring.version>
</properties>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.versio}</version>
</dependency>
</dependencies>
</dependencyManagement>
  • 这样如moduleA和moduleB在引用Spring-beans jar包的时候,直接使用父pom.xml中定义的公共依赖就可以:
    moduleA在其pom.xml使用spring-bean的jar包(不用再定义版本):
1
2
3
4
5
6
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
</dependencies>

无法引入jar包

解决方法:重新下载依赖。

1
mvn dependency:purge-local-repository

编译时出现OOM

解决方法:调大初始化内存大小。

Windows

  • %MAVEN_HOME%\bin\mvn.bat
1
2
3
 @REM set MAVEN_OPTS=-Xdebug -Xnoagent -Djava.compiler=NONE...
# 添加在上一行下面
set MAVEN_OPTS=-Xmx512m -XX:MaxPermSize=128m

Unix-like system

1
export MAVEN_OPTS="-Xmx512m -XX:MaxPermSize=128m"

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!