enforcer-plugin 良好的依赖管理

# maven-enforcer-plugin (opens new window)

中文描述是Maven增强插件, 主要功能是编译的时候对一些"规则"进行检测, 命中就会拦截抛错, 当然排除依赖还是依赖mvn dependency:tree -Dverbose定位到去哪里排除

看起来是给自己添麻烦, 其实是一个管理整个project质量的很好工具, 特别是在引入二方包的时候

# 基本用法

如代码, 展示了

  • 禁用插件
  • 指定maven最低版本
  • 指定java最低版本
  • 指定操作系统

而一般最常用的应该是通过enforce进行[直接引入/传递引入]的依赖的禁用

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-enforcer-plugin</artifactId>
    <version>3.0.0-M3</version>
    <executions>
        <execution>
            <id>enforce-versions</id>
            <goals>
                <goal>enforce</goal>
            </goals>
            <configuration>
                <rules>
                    <bannedPlugins>
                        <!-- will only display a warning but does not fail the build. -->
                        <level>WARN</level>
                        <excludes>
                            <exclude>org.apache.maven.plugins:maven-verifier-plugin</exclude>
                        </excludes>
                        <message>Please consider using the maven-invoker-plugin (http://maven.apache.org/plugins/maven-invoker-plugin/)!</message>
                    </bannedPlugins>
                    <requireMavenVersion>
                        <version>2.0.6</version>
                    </requireMavenVersion>
                    <requireJavaVersion>
                        <version>1.5</version>
                    </requireJavaVersion>
                    <requireOS>
                        <family>unix</family>
                    </requireOS>
                </rules>
            </configuration>
        </execution>
    </executions>
</plugin>

# 配置案例

这里做了几个配置, 从而避免二方包"强健"自己应用, 不过对于在Pandora Sar 容器的中间件无效, 那些也不需要管

  1. 要求了Java version, 这里是对项目编译本身要求
  2. 禁止lomok进入编译和runtime. 把编译期这几MB的包引入runtime, 99.9%的应用没有应用场景
  3. 禁止log4J1 & log4J2引入, 这里用了Spring boot默认logback
  4. 禁止slf4j-log4j12引入, 避免引入把slf4j重定向到log4j, 这里用了Spring boot默认logback, 避免LoggerFactory冲突
  5. 禁止org.apache.logging.log4j整个组的引入, 避免引入把log4j重定向到slf4j, 没有用了. 如果二方包写死了log4j这种请用阿里巴巴开发规约 (opens new window)去怼他...
  6. 禁止TestNG, 用了Junit 4 & 5. 看情况, 只是举例子, Pandora Boot Junit5 强依赖 Junit4
  7. 禁止JUnit 3/4/5 引入到compile & runtime. 把单测框架引到runtime好刺激
<plugin>
    <artifactId>maven-enforcer-plugin</artifactId>
    <executions>
        <execution>
            <id>default-cli</id>
            <goals>
                <goal>enforce</goal>
            </goals>
            <phase>validate</phase>
            <configuration>
                <rules>
                    <requireJavaVersion>
                        <message>
                            <![CDATA[You are running an older version of Java. This application requires at least JDK ${java.version}.]]>
                        </message>
                        <version>[${java.version}.0,)</version>
                    </requireJavaVersion>
                    <!-- 不要把 lombok 引入到runtime -->
                    <bannedDependencies>
                        <searchTransitive>true</searchTransitive>
                        <excludes>
                            <exclude>org.projectlombok:lombok:*:jar:compile</exclude>
                            <exclude>org.projectlombok:lombok:*:jar:runtime</exclude>
                        </excludes>
                        <message>
                            <![CDATA[Lombok must not to be included into runtime]]>
                        </message>
                    </bannedDependencies>
                    <!-- logger -->
                    <bannedDependencies>
                        <searchTransitive>true</searchTransitive>
                        <excludes>
                            <exclude>org.apache.log4j</exclude>
                        </excludes>
                        <message><![CDATA[Don't use log4j2]]></message>
                    </bannedDependencies>
                    <bannedDependencies>
                        <searchTransitive>true</searchTransitive>
                        <excludes>
                            <exclude>org.apache.logging.log4j</exclude>
                        </excludes>
                        <message>
                            <![CDATA[Since log4j2 is not allow to use, you don't need [org.apache.logging.log4j]]]>
                        </message>
                    </bannedDependencies>
                    <bannedDependencies>
                        <searchTransitive>true</searchTransitive>
                        <excludes>
                            <exclude>log4j</exclude>
                        </excludes>
                        <message><![CDATA[Don't use log4j]]></message>
                    </bannedDependencies>
                    <bannedDependencies>
                        <searchTransitive>true</searchTransitive>
                        <excludes>
                            <exclude>org.slf4j:slf4j-log4j12</exclude>
                        </excludes>
                        <message><![CDATA[Don't use log4j binding]]></message>
                    </bannedDependencies>
                    <!-- unit test  -->
                    <bannedDependencies>
                        <searchTransitive>true</searchTransitive>
                        <excludes>
                            <exclude>org.test</exclude>
                        </excludes>
                        <message><![CDATA[Don't use TestNG]]></message>
                    </bannedDependencies>
                    <bannedDependencies>
                        <searchTransitive>true</searchTransitive>
                        <excludes>
                            <exclude>junit:*:*:jar:compile</exclude>
                            <exclude>junit:*:*:jar:runtime</exclude>
                        </excludes>
                        <message><![CDATA[Don't include Junit4 in runtime]]></message>
                    </bannedDependencies>
                    <bannedDependencies>
                        <searchTransitive>true</searchTransitive>BannedDependencies
                        <excludes>
                            <exclude>org.junit.jupiter:*:*:jar:compile</exclude>
                            <exclude>org.junit.jupiter:*:*:jar:runtime</exclude>
                        </excludes>
                        <message><![CDATA[Don't include Junit5 in runtime]]></message>
                    </bannedDependencies>
                </rules>
            </configuration>
        </execution>
    </executions>
</plugin>