jacoco-maven-plugin被maven enforcer引发的探索

以下内容摘自雪球,在公司内部的docs上的内容总结,部分隐私信息已经处理改动


https://xueqiu.com/

每个公司都会在CI层做一些jar包的规范,本次的问题出现在的pom规范里,maven-enforcer-plugin插件banned了一些有安全隐患的依赖

如下:

<bannedDependencies>
<excludes>
<exclude>apprentice:apprentice-tcommon</exclude>
<exclude>org.jboss.netty:netty</exclude>
<exclude>com.xueqiu.infra:redis-cluster*</exclude>
<exclude>com.twitter:finagle-*</exclude>
<exclude>com.twitter:util-*</exclude>
<exclude>org.slf4j:slf4j-nop</exclude>
<exclude>org.slf4j:slf4j-log4j12</exclude>
<exclude>org.slf4j:slf4j-jdk14</exclude>
<exclude>org.slf4j:slf4j-jcl</exclude>
<exclude>org.slf4j:slf4j-log4j13</exclude>
<exclude>commons-logging:commons-logging</exclude>
<exclude>log4j:log4j</exclude>
<exclude>org.apache.log4j:org.apache.log4j</exclude>
<exclude>c3p0:c3p0</exclude>
<exclude>com.mchange:c3p0</exclude>
<exclude>javax.servlet:servlet-api</exclude>
<exclude>org.mortbay.jetty:servlet-api</exclude>
<exclude>backport-util-concurrent:backport-util-concurrent</exclude>
</excludes>
</bannedDependencies>

源码:jacoco-maven-plugin组件在0.8.3以下版本依赖了

commons-logging和backport-util-concurrent,导致maven打包失败
<exclusion>
 <artifactId>commons-logging</artifactId>
 <groupId>commons-logging</groupId>
</exclusion>
<exclusion>
 <artifactId>backport-util-concurrent</artifactId>
 <groupId>backport-util-concurrent</groupId>
</exclusion>

maven失败信息:

[WARNING] Rule 2: org.apache.maven.plugins.enforcer.BannedDependencies failed with message:
Found Banned Dependency: commons-logging:commons-logging:jar:1.2
Found Banned Dependency: backport-util-concurrent:backport-util-concurrent:jar:3.1
Use 'mvn dependency:tree' to locate the source of the banned dependencies.

扫描二维码关注公众号,回复: 10663252 查看本文章

解决办法:

使用0.8.3及其以上版本,0.8.3及其以上版本官方去除了对backport-util-concurrent包的依赖,但是还是依赖着commons-logging,只需要把commons-logging给exclusion了就行

把commons-logging给exclude掉的依据:xueqiu-parent里面有slf4j的日志门面替换相关知识),exclude掉没影响(xueqiu-parent 5.X的slf4j的日志门面替换需要使用者自己添加)

<dependency>
 <groupId>org.jacoco</groupId>
 <artifactId>jacoco-maven-plugin</artifactId>
 <version>${0.8.3及其以上版本}</version>
 <exclusions>
 <exclusion>
 <artifactId>commons-logging</artifactId>
 <groupId>commons-logging</groupId>
 </exclusion>
 </exclusions>
</dependency>

pom按照如下配置就好:

<jacoco.version>0.8.3及其以上</jacoco.version>

<dependency>

    <groupId>org.jacoco</groupId>

    <artifactId>jacoco-maven-plugin</artifactId>

    <version>${jacoco.version}</version>

    <exclusions>

        <exclusion>

            <artifactId>commons-logging</artifactId>

            <groupId>commons-logging</groupId>

        </exclusion>

    </exclusions>

</dependency>

<plugin>

   <groupId>org.jacoco</groupId>

   <artifactId>jacoco-maven-plugin</artifactId>

   <version>${jacoco.version}</version>

   <configuration>

      <includes>

         <include>这里配置你们需要测试的目录</include>

      </includes>

   </configuration>

   <executions>

      <execution>

         <id>pre-test</id>

         <goals>

            <goal>prepare-agent</goal>

         </goals>

      </execution>

      <execution>

         <id>post-test</id>

         <phase>test</phase>

         <goals>

            <goal>report</goal>

         </goals>

      </execution>

   </executions>

</plugin>

解惑:至于为什么不配置在xueqiu-parent中,这样还省的大家自己设置了,原因是众口难调,而且对于不同的项目可能对于这个组件会有自己的一些配置,但parent里面的更改是个黑盒对于查找原因不利

commons-logging不受欢迎的原因:https://spring.io/blog/2009/12/04/logging-dependencies-in-spring/
slf4j替换原理:

假如你正在开发应用程序所调用的组件当中已经使用了 JCL(之前叫 Jakarta Commons Logging,JCL) 的,还有一些组建可能直接调用了 java.util.logging,这时你需要一个桥接器(名字为 XXX-over-slf4j.jar)把他们的日志输出重定向到 SLF4J,所谓的桥接器就是一个假的日志实现工具,比如当你把 jcl-over-slf4j.jar 放到 CLASS_PATH 时,即使某个组件原本是通过 JCL 输出日志的,现在却会被 jcl-over-slf4j “骗到”SLF4J 里,然后 SLF4J 又会根据绑定器把日志交给具体的日志实现工具。过程如下

Component
|
| log to Apache Commons Logging
|
V
jcl-over-slf4j.jar --- (redirect) ---> SLF4j ---> slf4j-log4j12-version.jar ---> log4j.jar ---> 输出日志

看到上面的流程图可能会发现一个有趣的问题,假如在 CLASS_PATH 里同时放置 log4j-over-slf4j.jar 和 slf4j-log4j12-version.jar 会发生什么情况呢?没错,日志会被踢来踢去,最终进入死循环。

所以使用 SLF4J 的比较典型搭配就是把 slf4j-api、JCL 桥接器、java.util.logging(JUL)桥接器、log4j 绑定器、log4j 这5个 jar 放置在 CLASS_PATH 里。

不过并不是所有APP容器都是使用 log4j 的,比如 Google AppEngine 它使用的是 java.util.logging(JUL),这时应用 SLF4J 的搭配就变成 slf4j-api、JCL桥接器、logj4桥接器、JUL绑定器这4个 jar 放置在 WEB-INF/lib 里。

发布了212 篇原创文章 · 获赞 68 · 访问量 36万+

猜你喜欢

转载自blog.csdn.net/singgel/article/details/103704751
今日推荐