目录

一、前言

二、一团糟

三、如何利用父pom

四、后话


一、前言


 


事情是这样的:最近条线内部在搞“避免重复造轮子”的整改活动。其中发生了一个事情,之前条线内部的A团队已经尝鲜使用了XXL-job,后面考虑到避免重复造轮子,就要求B团队新建的系统也统一使用XXL-job,然后通过执行器进行权限管理,最后才发现原来A团队使用的那个版本还没有支持权限管理。从这里,我发现到一个问题:我们的maven管理确实很混乱,依赖版本管理必须得统一管理起来。


 


二、一团糟


 


实际上,日常工作中还有其他问题的:


 


“天啊,投产包为什么会是SNAPSHOT版本?”“哪位潇洒的大侠居然引用了一个快照版的三方包?坑爹啊”“我去,生产爆了个大bug,为什么你们系统没有?噢,原来我们用的版本不一样,你真幸运。”


 


以上的问题如何解决呢?其中一个答案就是:


 


统一我们的父pom【根】,然后要求所有团队的项目直接使用这个【根】或者再基于这个【根】进行继承成自己项目的二级父pom,通过这个二级父pom进行版本管理。


 


三、如何利用父pom


 


1、对于某些基础包进行统一版本管理。这样的话,当子pom引用的使用就只需要groupId和artifactId即可,且当父pom的版本一改,所有子pom就会统一自动继承。


<properties>
   <java.version>1.8</java.version>
   <maven.version>3.3.7</maven.version>
   <mybatis.version>2.1.2</mybatis.version>
   <enforcer.version>1.4.1</enforcer.version>
</properties>

<dependencyManagement>
<dependencies>
   <dependency>
      <groupId>org.mybatis.spring.boot</groupId>
      <artifactId>mybatis-spring-boot-starter</artifactId>
      <version>${mybatis.version}</version>
   </dependency>
</dependencies>


 


2、在父pom加入maven-enforcer-plugin进行规则校验。


 


之前在DevOps meetup上面京东数科DevOps落地实践的线上分享中提过他们的流水线上也会用到maven-enforcer-plugin。后面做了简单的试验并结合团队的实际情况,建议我们主要用以下几个校验规则。


•  
   requireMavenVersion - enforces the Maven version.   
  
•  
   requireJavaVersion - enforces the JDK version.           
  
•  
   requireReleaseVersion - enforces that the artifact is not a snapshot. 
  
•  
   banDuplicatePomDependencyVersions - enforces that the project doesn't have duplicate declared dependencies. 
  
•  
   requireReleaseDeps - enforces that no snapshots are included as dependencies. 
  
•  
   bannedDependencies - enforces that excluded dependencies aren't included.

 


这里以我的其中一个项目父pom作为例子,里面存着以上头4个问题,然后我们跑一下mvn validate看会报什么错误。


 


<?xml version="1.0" encoding="UTF-8"?>
 
   
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 
   
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
 
   
   <modelVersion>4.0.0</modelVersion>
 
   
    <packaging>pom</packaging>
 
   
    <modules>
 
   
        <module>validation</module>
 
   
      <module>web</module>
 
   
    </modules>
 
   
    <parent>
 
   
      <groupId>org.springframework.boot</groupId>
 
   
      <artifactId>spring-boot-starter-parent</artifactId>
 
   
      <version>2.1.13.RELEASE</version>
 
   
      <relativePath/> <!-- lookup parent from repository -->
 
   
   </parent>
 
   
   <groupId>com.imooc</groupId>
 
   
   <artifactId>demoo</artifactId>
 
   
   <version>0.0.1-SNAPSHOT</version>
 
   
   <name>demoo</name>
 
   
   <description>Demo project for Spring Boot</description>
 
   


        
    

 
   
   <properties>
 
   
      <java.version>1.10</java.version>
 
   
      <maven.version>3.3.10</maven.version>
 
   
      <mybatis.version>2.1.2</mybatis.version>
 
   
      <enforcer.version>1.4.1</enforcer.version>
 
   
   </properties>
 
   


        
    

 
   
   <dependencies>
 
   
      <dependency>
 
   
         <groupId>org.springframework.boot</groupId>
 
   
         <artifactId>spring-boot-starter-web</artifactId>
 
   
      </dependency>
 
   
      <dependency>
 
   
         <groupId>org.mybatis.spring.boot</groupId>
 
   
         <artifactId>mybatis-spring-boot-starter</artifactId>
 
   
         <version>${mybatis.version}</version>
 
   
      </dependency>
 
   
      <dependency>
 
   
         <groupId>org.mybatis.spring.boot</groupId>
 
   
         <artifactId>mybatis-spring-boot-starter</artifactId>
 
   
         <version>${mybatis.version}</version>
 
   
      </dependency>
 
   
      <dependency>
 
   
         <groupId>mysql</groupId>
 
   
         <artifactId>mysql-connector-java</artifactId>
 
   
      </dependency>
 
   
      <dependency>
 
   
         <groupId>org.springframework.boot</groupId>
 
   
         <artifactId>spring-boot-starter-test</artifactId>
 
   
         <scope>test</scope>
 
   
      </dependency>
 
   
      <dependency>
 
   
         <groupId>org.projectlombok</groupId>
 
   
         <artifactId>lombok</artifactId>
 
   
         <optional>true</optional>
 
   
      </dependency>
 
   
      <!--引入JSR303校验-->
 
   
      <dependency>
 
   
         <groupId>org.springframework.boot</groupId>
 
   
         <artifactId>spring-boot-starter-validation</artifactId>
 
   
      </dependency>
 
   
   </dependencies>
 
   


        
    

 
   
   <dependencyManagement>
 
   
      <dependencies>
 
   
         <dependency>
 
   
            <groupId>org.mybatis.spring.boot</groupId>
 
   
            <artifactId>mybatis-spring-boot-starter</artifactId>
 
   
            <version>${mybatis.version}</version>
 
   
         </dependency>
 
   
      </dependencies>
 
   
   </dependencyManagement>
 
   


        
    

 
   
   <build>
 
   
      <plugins>
 
   
         <plugin>
 
   
            <groupId>org.springframework.boot</groupId>
 
   
            <artifactId>spring-boot-maven-plugin</artifactId>
 
   
         </plugin>
 
   
         <plugin>
 
   
            <groupId>org.apache.maven.plugins</groupId>
 
   
            <artifactId>maven-enforcer-plugin</artifactId>
 
   
            <version>${enforcer.version}</version>
 
   
            <executions>
 
   
               <execution>
 
   
                  <id>default-cli</id>
 
   
                  <goals>
 
   
                     <goal>display-info</goal>
 
   
                     <goal>enforce</goal>
 
   
                  </goals>
 
   
                  <phase>validate</phase>
 
   
                  <configuration>
 
   
                     <rules>
 
   
                        <!--Rule #1:检验maven版本-->
 
   
                        <requireMavenVersion>
 
   
                           <message>
 
   
                              <![CDATA[This application requires at least Maven with version ${maven.version}.]]>
 
   
                           </message>
 
   
                           <version>[${maven.version},)</version>
 
   
                        </requireMavenVersion>
 
   
                        <!--Rule #2:校验Java版本-->
 
   
                        <requireJavaVersion>
 
   
                           <message>
 
   
                              <![CDATA[This application requires at least JDK ${java.version}.]]>
 
   
                           </message>
 
   
                           <version>[${java.version}.0,)</version>
 
   
                        </requireJavaVersion>
 
   
                        <!--Rule #3:校验投产的版本不能是snapshot-->
 
   
                        <requireReleaseVersion>
 
   
                           <message>Snapshots version is prohibited.</message>
 
   
                        </requireReleaseVersion>
 
   
                        <!--Rule #4:校验pom文件中有没有重复的依赖(相同的GAV)-->
 
   
                        <banDuplicatePomDependencyVersions/>
 
   
                        <!--Rule #5:校验依赖冲突,如果冲突了会报错,然后在<excludes>进行排除管理即可-->
 
   
                        <bannedDependencies>
 
   
                           <!--校验传递性依赖(间接依赖)-->
 
   
                           <searchTransitive>true</searchTransitive>
 
   
                           <excludes/>
 
   
                        </bannedDependencies>
 
   


        
    

 
   
                        <requireProperty>
 
   
                           <property>project.version</property>
 
   
                           <message>"Project version must be specified."</message>
 
   
                           <regex>.*(\d|-SNAPSHOT)$</regex>
 
   
                           <regexMessage>"Project version must end in a number or -SNAPSHOT."</regexMessage>
 
   
                        </requireProperty>
 
   
                     </rules>
 
   
                  </configuration>
 
   
               </execution>
 
   
            </executions>
 
   
         </plugin>
 
   
      </plugins>
 
   
   </build>
 
   


        
    

 
   
</project>

 


当我们跑了mvn validate后,请大家对照以上pom文件看以下截图,你可以发现上面的头4个错误基本可以在构建环节直接识别,这样的话就可以在技术上有效的约束工作规范,这样是不是更好的体现“约定优于配置”呢?


 


当然,具体maven-enforcer-plugin还有更多的校验规则,或者你也可以基于它的规范开发你特有的校验规则。具体可以参考阿帕奇http://maven.apache.org/enforcer/maven-enforcer-plugin/index.html


 




统信maven配置the java_home environment variable is not defined correctly_工程规约


 


 


四、后话


 


实际上这个就是我自己构想中的DevOps持续构建流水线上的关于质量关卡的其中一个小环节。诚然,在工程规约这个大命题下面,实际我们还有更多的事情需要做,后面再慢慢摸索,定期更新完善这个DevOps流水线。