在推动项目开发人员编写单元测试的时候,需要在项目中加入jacoco插件以便统计单元测试的覆盖率,从而更直观的体现单元测试的工作量和成果。在此过程中,在持续集成机器上运行mvn test以及在本地运行都可以正确的加载,然而一到omad平台自动部署的时候就发现构建失败。难题来了,如果想统计覆盖率就必须加jacoco插件,如果加了插件omad构建不通过则无法自动更新部署线下线上环境。因此必须解决这个问题才能鱼与熊掌兼得。
首先看一下项目的pom.xml文件中是如何添加jacoco插件的。 在想统计覆盖率的子mvn工程中添加相应的配置如下:
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.2.201409121644</version>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<destFile>
${project.build.directory}/jacoco.exec
</destFile>
<propertyName>surefireArgLine</propertyName>
</configuration>
</execution>
<execution>
<id>default-report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<dataFile>${project.build.directory}/jacoco.exec</dataFile>
<outputDirectory>${project.reporting.outputDirectory}/jacoco</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>${argLine}</argLine>
</configuration>
<executions>
<execution>
<id>default-test</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<argLine>${surefireArgLine}</argLine>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
可以看到在plugins中配置了两个插件,一个是maven-surefire-plugin,之前我写过一些这个插件的介绍在下面的两篇博文中: maven-surefire-plugin插件,你真的会用吗?maven-surefire-plugin插件,你真的会用吗?-------续篇之深入挖掘高级用法 第二个就是今天的重头戏:jacoco插件,对于jacoco的介绍在本文不做过多阐述,这方面的资料也比较多。 当配置添加ok以后,分别在持续集成服务器和omad的构建服务上运行命令如下:mvn clean test 单元测试执行完毕后,持续集成服务器上的对应子工程下target目录下生成jacoco.exec这里面就是覆盖率的描述文件。 而omad的构建服务器上直接构建失败,关键错误日志如下:
[exec] [ERROR] Plugin jacoco-maven-plugin:jacoco-maven-plugin:0.7.2.201409121644 or one of its dependencies could not be resolved: Could not find artifact jacoco-maven-plugin:jacoco-maven-plugin:jar:0.7.2.201409121644 in central (http://repo.maven.apache.org/maven2) -> [Help 1]
比较明显的可以看出来在下载jacoco插件包的时候去中央仓库获取了,而且没找到这个版本的。然后首先想到的就是排查omad的构建服务器的mvn 配置文件是否添加了公司仓库地址。 查看omad构建服务器配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<settings xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd" xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<profiles>
<profile>
<id>profile-netease</id>
<repositories>
<repository>
<snapshots><enabled>false</enabled></snapshots>
<releases><enabled>true</enabled></releases>
<id>libs-releases</id>
<url>http://mvn.hz.netease.com/artifactory/libs-releases</url>
</repository>
<repository>
<snapshots><enabled>true</enabled></snapshots>
<releases><enabled>false</enabled></releases>
<id>libs-snapshots</id>
<url>http://mvn.hz.netease.com/artifactory/libs-snapshots</url>
</repository>
<repository>
<snapshots><enabled>false</enabled></snapshots>
<releases><enabled>true</enabled></releases>
<id>Server Name</id>
<url>http://mvn.hz.netease.com/artifactory/bj-mvn/</url>
</repository>
<repository>
<snapshots><enabled>false</enabled></snapshots>
<releases><enabled>true</enabled></releases>
<id>repo</id>
<url>http://mvn.hz.netease.com/artifactory/repo</url>
</repository>
</repositories>
</profile>
<profile>
<id>nexus</id>
<repositories>
<repository>
<snapshots>
<enabled>true</enabled>
<!--<updatePolicy>always</updatePolicy>-->
</snapshots>
<id>hz_repo</id>
<name>hz_repo</name>
<url>http://mvn.hz.netease.com/artifactory/repo</url>
</repository>
</repositories>
发现已经配置了公司仓库路径,默认会首先去公司仓库去下载包,如果找不到则再去中央仓库。 这条路排查完了,环境问题既然解决不了,就只能从工程的pom配置中想想办法。
pom中有一个配置可以指定依赖包下载的来源仓库,然后就尝试配置了一下。
<repositories>
<repository>
<snapshots><enabled>false</enabled></snapshots>
<releases><enabled>true</enabled></releases>
<id>hz_repo</id>
<url>http://mvn.hz.netease.com/artifactory/repo</url>
</repository>
</repositories>
再次执行编译,发现仍然下载失败,错误信息跟之前一样。这就奇怪了,难道这个repositories设置也不生效?这时查了下资料,发现maven中repositories是代表存储工件的仓库描述。工件实际上就是指的pom中的一些依赖的包。例如下面的testng包就是一个工件。
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.5.1</version>
</dependency>
但是我们现在需求是将插件plugin中配置的jacoco的下载地址给改掉。再查一下资料,发现有另外一个仓库的配置叫pluginRepositories。下面来进一步了解这个配置的作用。
如上所述,repositores指定了依赖包的下载地址,而pluginRepositores是做什么用的呢,其实正如这个配置的名字一样明显,它是用来指定下载插件仓库的地址的。使用方法也跟repositores的设置类似。尝试设置如下:
<pluginRepositories>
<pluginRepository>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>hz_repo</id>
<name>repo</name>
<url>http://mvn.hz.netease.com/artifactory/repo</url>
</pluginRepository>
</pluginRepositories>
再尝试编译,成功的下载到相应的插件包。最终BUILD SUCCESS。 查看构建服务器上的.m2目录下也下载到对应版本的jacoco插件包。
[exec] [INFO] --- jacoco-maven-plugin:0.7.2.201409121644:prepare-agent (default-prepare-agent) @ nce-commons ---
[exec] [INFO] surefireArgLine set to -javaagent:/home/omad/.m2/repository/org/jacoco/org.jacoco.agent/0.7.3.201502191951/org.jacoco.agent-0.7.3.201502191951-runtime.jar=destfile=/srv/nbs/0/omad/build_nce2_yq/nce-web/yq-ci-base/git/nce-commons/target/jacoco.exec
....
[exec] [INFO] BUILD SUCCESS
[exec] [INFO] ------------------------------------------------------------------------
[exec] [INFO] Total time: 2.940 s
[exec] [INFO] Finished at: 2017-02-20T17:38:56+08:00
[exec] [INFO] Final Memory: 17M/457M
[exec] [INFO] ------------------------------------------------------------------------
一个小小的下载不到包的错误的解决,让自己了解到maven中还有一个pluginRepositories配置的存在,虽然花了大半天的时间,也是值得的。在此跟大家分享,如果有类似的坑可以直接用这个配置项来解决了。
本文来自网易实践者社区,经作者崔晓晴授权发布。