一个 maven 插件打包问题的排查

最近研究 sofa-ark 的插件机制时,发现当执行完 maven clean install -DskipTests 时,打在 target 目录下的 xxx.jar 与安装到本地仓库的 xxx.jar 大小不一致。

  • target 目录下的插件大小

  • .m2 下的插件大小

其实一开始看到这种现象也是懵逼,同一个工程,同一次命令执行,但是得到的两个 jar 包大小差距巨大。那么对于这种问题,我想到的有两点:

  • debug 打包插件执行过程
  • 了解 maven 插件的生命周期

debug 打包插件执行过程

这里需要借助 IDEA 中的远程 debug 能力来完成。目前有两个工程,一个是我们的主工程,工程名为上面截图中的 mq-client-ark-plugin ,另一个是打包插件的源码工程,如下图所示:

那么下面就一步一步来完成远程 debug 的配置。

1、使用 mvnDebug 命令开启 debug 模式

在主工程 mq-client-ark-plugin 的根目录下执行 mvnDebug install(当然除了 install 之外,也可以是 compilepackagetestdeploy 等)。

当执行完 mvnDebug install 后,可以看到这个阻塞监听 8000 端口了。

2、源码工程配置远程 debug

idea 主界面找下下图的工具菜单,选择 Edit Configurations...

打开配置面板之后,左上角 + 选择 Remote

填写相关远程 debug 参数

  • Host : 远程目标主机地址,因为之前 主工程也是本地启动的,所以这里就是 localhost
  • Port : 远程目标主机开启的远程 debug 端口
  • 开启远程 debug 参数:-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000

配置完成之后,执行 debug ,可以看下已经连接到了目标机器:

在来看主工程这里,在源码工程没有执行上面的 debug 按钮之前,一直都是阻塞的,执行之后 maven 执行的生命周期开始了:

如上图,因为在源码工程中打了断点,所以当执行到 sofa-ark-maven-plugin 插件时阻塞了。

从 maven 执行的生命周期找出问题根源

上面已经搞定了对目标插件源码的 debug 模式的开启,那么下面就是对插件代码进行 debug 操作。节省篇幅,这里直接将断点放在目标代码行位置:

分析这段代码

  • 1、获取到项目的 Artifact ,此时 Artifactfile 为:
  • 2、重新设置的 File
  • 3、重新设置了 artifact

如果单从上面 debug 来看,其实很难解释开篇的那个问题。那么这里在回过头来看下 主工程的 maven 执行日志:

如上图中圈红的部分,代表 maven install 所经历的所有阶段。可以看到 sofa-ark-plugin-maven-plugin 是在 maven-install-plugin 后面,那这意味着什么呢?

我们知道在 target 目录下得到的 xxx.jar 是打包阶段的产物,而 .m2 下面的是 install 的产物。

当然这里没有涉及到 deploydeployinstall 之后的操作,比如发布到远程仓库。

现在再来看,因为 sofa-ark-plugin-maven-plugin 在执行 install 插件之前将 目标文件给替换了,所以导致打包生成的 target 目录下的 xxx.jar 和 安装到本地仓库的 xxx.jar 不一致。

小结

本文记录了日常的一个问题排查过程,包括两个小点,一个是如何去 debug maven 的插件,另外一个是简单了解下 maven 打包的生命周期。

关于 maven 打包的生命周期的代码没有具体研究过,不过这里可以大概猜测下,就是 maven 在执行命令时,有个类似于中央控制器的东西,通过解析 maven 命令得到一个 LifeCycle 或者 一个 Pipeline (LifeCycle 或者 Pipeline 实际上就是组装了一系列的插件)。然后 LifeCycle 或者 Pipeline 启动执行,遍历插件,依次执行插件的 execute 方法。

作者

卫恒

发布于

2019-07-23

更新于

2022-04-23

许可协议

评论