文章目录
- 1. 前言
- 2. 一些有用的链接,稍后学习
- 3. 干货来了,使用中遇到的真实问题。
- 3.1 版本的注意事项
- 3.2 下载及配置
- 3.3 指定本地仓库位置
- 3.4 项目中指定中央仓库位置
- 3.5 项目下使用maven命令行更新package:
- 3.6 检查Maven执行错误
- 3.6.1 The JAVA_HOME environment variable is not defined correctly
- 3.6.2 Could not find artifact xxxx
- 3.6.3 Could not find artifact xxxx
- 3.6.4 Could not resolve dependencies for project xxx
- 3.6.5 Could not transfer artifact xxx from/to
- 3.6.6 Maven版本问题 requires Maven version x.x.x
- 3.6.7 'build.plugins.plugin.version' for xxxxx is missing
- 3.6.8 OutOfMemoryError, GC overhead limit exceeded
- 3.6.9 com.mysql.cj.jdbc.Driver VS com.mysql.jdbc.Driver
- 3.6.10 终极查找,应对任何ClassNotFoundException
- 3.6.11
- 4. Pom文件说明
1. 前言
和其他文章一样,记录使用过程中学习的心得,及遇到的坑。
2. 一些有用的链接,稍后学习
maven内部运行原理解析(一)
maven内部运行原理解析(二)
Maven总结
3. 干货来了,使用中遇到的真实问题。
3.1 版本的注意事项
不同的Maven版本,需要对应的JDK版本才能正常工作的,不然会有各种各样的问题。笔者就是在一个项目中,使用了JDK1.8(java8),然后用了Maven 3.6.3。结果在使用Maven import老项目时,部分依赖包总是无法自动下载下来(不是所有的都下不下来,而是部分的下不下来,并且有些是能下doc,能下sources.jar,但不能下载class的jar)。见下图,但明明到nexus是可以看到版本有效的。
后来问了同事,知道Maven和JDK版本有冲突,然后上Maven官网一看,果然这个是写的明明白白的。见Maven官网的 Maven VS JDK对应图
以下摘抄简短对比
Mave版本 | JDK版本 |
---|---|
3.3.1 到 3.6.3(当前最新版本) | Java 7 |
3.2.1 到 3.2.5 | java 6 |
2.2.0 到 3.1.1 | java 5 |
2.0 到 2.2.1 | Java 1.4 |
但是,可但是,但可是,然并卵,上述版本对应并不是一定起作用,即使使用了所描述的Maven+JDK版本,还是有可能遇到部分JDK没下载成功的情况。所以还是要多换几个maven+jdk版本尝试。使用mvn -v可以看到当前使用的maven和JDK版本。如果没下成功的比较少的话,直接到中央仓库手动拿jar包即可。
C:\Windows\system32>mvn -v
Apache Maven 3.0.5 (r01de14724cdef164cd33c7c8c2fe155faf9602da; 2013-02-19 21:51:28+0800)
Maven home: D:\Tools\apache-maven-3.0.5\bin\..
Java version: 1.8.0_251, vendor: Oracle Corporation
Java home: D:\Program Files\Java\jdk1.8.0_251\jre
Default locale: zh_CN, platform encoding: GBK
OS name: "windows 10", version: "10.0", arch: "amd64", family: "dos"
3.2 下载及配置
-
直接从Maven的官网下载: Maven官网
-
在官网选择Binary zip archive,Link那一列,这个就是需要下载的zip文件
-
自行解压后放到一个路径下,比如:D:\Tools\apache-maven-3.6.3\
-
设置环境变量:MAVEN_HOME = D:\Tools\apache-maven-3.6.3
-
加入Path: %MAVEN_HOME%\bin
-
打开命令行窗口,输入 mvn -v ,出现以下信息,说明Maven配置成功,嗯,就和前一个版本注意事项一样
C:\Windows\system32>mvn -v
Apache Maven 3.0.5 (r01de14724cdef164cd33c7c8c2fe155faf9602da; 2013-02-19 21:51:28+0800)
Maven home: D:\Tools\apache-maven-3.0.5\bin\..
Java version: 1.8.0_251, vendor: Oracle Corporation
Java home: D:\Program Files\Java\jdk1.8.0_251\jre
Default locale: zh_CN, platform encoding: GBK
OS name: "windows 10", version: "10.0", arch: "amd64", family: "dos"
3.3 指定本地仓库位置
指定本地仓库位置,是在Maven的配置文件中,如果不指定本地仓库位置,默认会把依赖包下载到如下目录,这样显然不利于管理,所以要改变本地的路径,
C:\Users\86185.m2\repository\
变更本地仓库路径的文件是:{自己的Maven安装路径}\conf\settings.xml
打开这个文件,发现setting下所有的子节点都被注释掉了,其实都没用到。指定本地仓库位置,并不是用到被注释的节点,而是在setting下增加一个节点,直接复制即可(当然要换成自己喜欢的路径)
<localRepository>D:\Tools\MavenStore</localRepository>
在Intellj中,settings.xml的设置无效
3.4 项目中指定中央仓库位置
项目中指定中央仓库位置,不是在Maven中,到项目路径下,根目录一定有一个pom.xml。没有这个文件,那说明你的不是maven项目,别看这片文章了。
POM中指定仓库的位置,都包含在repositories 节点下,具体如下。查找顺序还没来得及看,先记录下来。
如下的xml结构,不过xml节点和真实链接有一点点不同,列举如下:
XML节点 | 对应链接 |
---|---|
http://121.201.35.8:9081/nexus/repository/maven-public/ | http://121.201.35.8:9081/nexus/#browse/browse:maven-public |
但实际中,应该是访问http://121.201.35.8:9081/nexus/,然后点击左边的browse,在选择maven-public
<repositories>
<repository>
<id>nexus</id>
<name>nexus repository</name>
<url>http://121.201.35.8:9081/nexus/repository/maven-public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>snapshots</id>
<name>nexus repository</name>
<url>http://121.201.35.8:9081/nexus/repository/maven-snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>releases</id>
<name>nexus repository</name>
<url>http://121.201.35.8:9081/nexus/repository/maven-releases/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
3.5 项目下使用maven命令行更新package:
无论使用eclipse还是Intellij IDEA,里面的自动关联maven更新可能都有些问题,哦,也可能是笔者配置的不好导致,所以可能需要在项目命令行下直接使用maven,看下载依赖包的错误。下面是拿来即用的命令。
mvn clean package -e -U -X -Dmaven.test.skip=true >myMavenLog.log
参数 | 用途 |
---|---|
clean | 清除target目录下的之前打好的jar包或者是war包 |
-e | 详细异常 |
-U | 强制更新 |
-X | 打印错误信息(这个一定要,看是出了啥错误) |
-Dmaven.test.skip=true | 据说加这个会比较快 |
>myMavenLog.log | 这个实际上是MS DOS的命令,把输出结果放到myMavenLog.log 这个文件中 |
##3.6 项目中使用maven下载dependances
在maven 的窗口,点击maven install
3.6 检查Maven执行错误
使用命令行,并将输出结果放到myMavenLog.log文件中之后,就比较容易检查错误了。以下列出实际使用中笔者所遇到的错误:
3.6.1 The JAVA_HOME environment variable is not defined correctly
当运行任何Maven命令,如mvn -v时,出现以下信息,说明JDK还没安装,或者配置不正确,需要配置JAVA_HOME,详情见笔者另外一篇文章
该错误的log如下:
C:\Users\Administrator>mvn -v
The JAVA_HOME environment variable is not defined correctly
This environment variable is needed to run this program
NB: JAVA_HOME should point to a JDK not a JRE
3.6.2 Could not find artifact xxxx
该错误的log如下:
at org.apache.maven.repository.internal.DefaultModelResolver.resolveModel(DefaultModelResolver.java:122)
... 33 more
Caused by: org.sonatype.aether.transfer.ArtifactNotFoundException: Could not find artifact com.xuebangsoft:xb-jigsaw-projects:pom:0.1.3-SNAPSHOT in nexus (http://121.201.35.8:9081/nexus/repository/maven-public/)
at org.sonatype.aether.connector.wagon.WagonRepositoryConnector$4.wrap(WagonRepositoryConnector.java:947)
关键信息:Could not find artifact
com.xuebangsoft:xb-jigsaw-projects:pom:0.1.3-SNAPSHOT in nexus
到Nexus中查看,确实没有这个包的存在,应该是漏了放上去
有2个解决方案:
- 让同事把0.1.3-SNAPSHOT版本的放到nexus里
- 自己手动改POM,拿其他版本的jar。
如果手动改pom,需要知道是哪个pom引用了这个jar,查找很容易,在本地的maven仓库中查找xb-jigsaw-projects,或者超找0.1.3-SNAPSHOT,都可以找到引用的包。
在本地仓库中找到2个文件的引用:
D:\Tools\MavenStore\com\xuebangsoft\xb-jigsaw-distributed-lock-api\0.1.2\xb-jigsaw-distributed-lock-api-0.1.2.pom
D:\Tools\MavenStore\com\xuebangsoft\xb-jigsaw-distributed-lock-zk-impl\0.1.9\xb-jigsaw-distributed-lock-zk-impl-0.1.9.pom
手动改pom拿其他版本的,看到nexus上有0.1.8,就拿这个最新的吧。
把
<parent>
<groupId>com.xuebangsoft</groupId>
<artifactId>xb-jigsaw-projects</artifactId>
<version>0.1.3-SNAPSHOT</version>
</parent>
改成
<parent>
<groupId>com.xuebangsoft</groupId>
<artifactId>xb-jigsaw-projects</artifactId>
<version>0.1.8</version>
</parent>
3.6.3 Could not find artifact xxxx
同样是could not find artifact,但这是Maven的文件
Could not find artifact org.glassfish:javax.el:pom:3.0.1-b06-SNAPSHOT in nexus
maven-metadata-jvnet-nexus-snapshots.xml 中引用如下。
<metadata>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
<versioning>
<versions>
<version>3.0.1-b06-SNAPSHOT</version>
<version>3.0.1-b07-SNAPSHOT</version>
<version>3.0.1-b08-SNAPSHOT</version>
<version>3.0.1-b11-SNAPSHOT</version>
</versions>
<lastUpdated>20180604075339</lastUpdated>
</versioning>
</metadata>
造成这个原因,是因为Maven版本众多,不同版本的maven,对依赖的版本也不尽相同,但自己的nexus仓库,总不能把所有的版本都囊括进来。
解决方案一:找到pom文件中的版本,放到自己的nexus仓库
解决方案二:自己看看中央仓库的javax.el有什么版本,替换掉pom中的版本号
笔者使用方案二可以解决问题。
3.6.4 Could not resolve dependencies for project xxx
这个其实后面也会指到错误 Could not find artifact
解决方案同上
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
Caused by: org.apache.maven.project.DependencyResolutionException: Could not resolve dependencies for project com.eduboss:eduboss:war:1.2.8-SNAPSHOT: Could not find artifact xb-mq-event:xb-mq-event:jar:DASHAN-UAT-SNAPSHOT in nexus (http://121.201.35.8:9081/nexus/repository/maven-public/)
at org.apache.maven.project.DefaultProjectDependenciesResolver.resolve(DefaultProjectDependenciesResolver.java:189)
3.6.5 Could not transfer artifact xxx from/to
Could not transfer artifact org.sonarsource.scanner.maven:sonar-maven-plugin:pom:3.6.0.1398 from/to oooo-public (http://nexus.myrepo.com/repository/oooo-public): Transfer failed for http://nexus.myrepo.com/repository/oooo-public/org/sonarsource/scanner/maven/sonar-maven-plugin/3.6.0.1398/sonar-maven-plugin-3.6.0.1398.pom
如遇到上述错误,按照以下方法查找:
- 首先打开远程仓库,确认路径下(包括版本)所指定的pom是否存在。
- 确定存在了,到本地路径下,把所有.lastUpdated的删掉,再拉一次。
3.6.6 Maven版本问题 requires Maven version x.x.x
如下,requires Maven version,需要换更高级的maven版本,好在Maven是使用环境变量配置的,在环境变量中将MAVEN_HOME指到对应的maven版本即可,随时可以再改回来
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 57.306s
[INFO] Finished at: Fri Jun 19 17:44:26 CST 2020
[INFO] Final Memory: 17M/135M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal com.github.eirslett:frontend-maven-plugin:1.4:install-node-and-npm (install-node-and-npm) on project eduboss: The plugin com.github.eirslett:frontend-maven-plugin:1.4 requires Maven version 3.1.0 -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal com.github.eirslett:frontend-maven-plugin:1.4:install-node-and-npm (install-node-and-npm) on project eduboss: The plugin com.github.eirslett:frontend-maven-plugin:1.4 requires Maven version 3.1.0
3.6.7 ‘build.plugins.plugin.version’ for xxxxx is missing
Some problems were encountered while building the effective model for com.lls.proj.asset:proj-asset-api:jar:1.0.0-SNAPSHOT
'build.plugins.plugin.version' for org.apache.maven.plugins:maven-source-plugin is missing. @ line 54, column 15
It is highly recommended to fix these problems because they threaten the stability of your build.
For this reason, future Maven versions might no longer support building such malformed projects.
发生以上问题,是因为pom中没有指定版本而导致的。如上述错误,找到proj-asset-api里面的pom文件,查找maven-source-plugin,会发现没指定版本:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
解决方法:
- 到远程仓库,查看仓库上有哪个版本的资料,补充上版本好重新运行mavin下载。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.0</version>
3.6.8 OutOfMemoryError, GC overhead limit exceeded
很熟悉的字眼,out of memory,只要加大内存就好
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 14:39 min
[INFO] Finished at: 2020-06-19T18:13:44+08:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.2:compile (default-compile) on project eduboss: Fatal error compiling: java.lang.OutOfMemoryError: RegularFileObject[E:\com\code\Java\Study1\Dashan2\src\main\java\com\eduboss\modules\others\service\impl\RealTimeReportServiceImpl.java]@pos37220: RegularFileObject[E:\com\code\Java\Study1\Dashan2\src\main\java\com\eduboss\modules\others\service\impl\RealTimeReportServiceImpl.java]@pos37235: RegularFileObject[E:\com\code\Java\Study1\Dashan2\src\main\java\com\eduboss\modules\others\service\impl\RealTimeReportServiceImpl.java]@pos37265: RegularFileObject[E:\com\code\Java\Study1\Dashan2\src\main\java\com\eduboss\modules\others\service\impl\RealTimeReportServiceImpl.java]@pos37260: GC overhead limit exceeded -> [Help 1]
在Maven的安装路径:%MAVEN_HOME%\bin下,找 mvn.bat 或 mvn.cmd 文件(不同版本的Maven文件名不同,但必定为二者之一)。
加入以下语句,
set MAVEN_OPTS = -Xms128m -Xmx512m
想要更大的运行内存空间可以设到:(笔者就是设了上面的,不够用,干脆一次性搞大)
set MAVEN_OPTS = -Xms1024m -Xmx2048m
3.6.9 com.mysql.cj.jdbc.Driver VS com.mysql.jdbc.Driver
在设置好项目,首次运行时,有可能会见到以下错误之一(只会见到其中一个,因为一个项目,只会用其中一种jdbc driver)
- java.lang.ClassNotFoundException: com.mysql.cj.jdbc.Driver
- java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
这是因为,两个不同的jdbc Driver,是不同mysql-connector-java版本下的。
com.mysql.jdbc.Driver 是版本5.0的
com.mysql.cj.jdbc.Driver 是版本8.0的
见下图配置,应该使用的是com.mysql.jdbc.Driver
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
<scope>runtime</scope>
</dependency>
而下图配置,应该使用的是com.mysql.cj.jdbc.Driver
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
<scope>runtime</scope>
</dependency>
用反了,就会出现class not found的问题。
3.6.10 终极查找,应对任何ClassNotFoundException
如果出现了某个查不到的class,而网上又找不到对应依赖的情况下,可以访问maven网站:
https://search.maven.org/
在search一栏,输入:fc:查找的包名。
如下图例。
如果报错是com.mysql.jdbc.Driver
那么就输入fc:com.mysql.jdbc.Driver
3.6.11
4. Pom文件说明
4.1 project/properties
自定义属性,可类比成自定义变量,以便后面的任意地方使用。
比如,下面的语句定义了一个用来统一版本的属性:
<properties>
<my.version>1.0.0-SNAPSHOT</my.version>
</properties>
后面任何地方,通过引用${my.version}即可,如下两个例子。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.myproj.workorder</groupId>
<artifactId>work-order-service-api</artifactId>
<version>${my.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${my.version}</version>
</plugin>
</plugins>
</build>
备注:
- 如果整个pom里都没引用到某个property,就相当于声明了变量没用,有代码强迫症的我是会主动删掉的。
- 如果配置jdbc的信息也可以在property里定义,不同的环境就在property中修改,后面引用的部分不变化。
4.2 project/dependencyManagement
DependencyManagement是声明jar包统一管理,顾名思义,是用来管理后面dependencies节点的统一引用的,一般关于版本信息,引用类型,范围,都尽量在Management里面定义,后面各个子项目的dependencies,只需要引用即可。
备注:
- DependencyManagement中所有的信息都只是声明,而不是引用,所以如果只在DependencyManagement中写了某个依赖,运行maven是不会下载的。只有在dependencies中引用了,才会下载
4.3 project/dependencies
这是最主要的属性了,该节点下放置所有的依赖。没什么好说的。
<dependencies>
<dependency>
<groupId>com.myproj.framework</groupId>
<artifactId>myproj-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
备注:
- 结合dependencyManagement来看,如果dependencyManagement中声明了一些信息,dependencies中可以不声明版本号,不声明则从Management中继承,如果需要另一个版本号,则在dependencies中声明。dependencies中声明的信息优先级高于父类的