夜天之书 #63 上游优先的故事 3 Maven Shade Plugin

前排提示,本文全文长 1.6w 字,由十个故事组成。出于微信公众号的展示特点,我将其切成若干个部分分开推送。如果想要单页读完全部内容,请点击阅读原文跳转网页,网页展示有目录,可以快速导航。

Maven Shade Plugin

这个案例的起因是我在 Pulsar 社群恰好和其他几个开发者同时发现 Pulsar 的 pom.xml 配置触发了 Maven Shade Plugin[1] 的一个缺陷。

•[Bug] Maven deployment failed on project pulsar-presto-connector-original[2]

一般来说,Java 开发者对于应用代码和库函数是比较熟悉的,而一旦涉及到构建系统比如 Maven 或 Gradle 等,则会天然地产生一种陌生的刻板印象。这对于其他语言生态也是类似的,C++ 开发者哪怕能够写出很复杂的模板代码,也很有可能在调试 CMake 的配置的时候抓瞎。因此,除非专门的构建系统开发者,其他开发者几乎总是优先考虑绕过问题,而不是怀疑构建系统本身有缺陷,或者把构建系统的缺陷都当成需要理解和共处的特性。

我也不例外。不过我折腾构建系统的时间还算有一些,知道 Maven 增量构建问题一堆,所以马上发现了执行 mvn clean 清理构建产物以后再跑构建流程(“重启一下试试”)就可以绕过问题。

然而,一周以后,这个 issue 还是开着,不像有上面的绕过方法就算了的样子。我一时强迫症上来了,就开始搜索同类问题。很快,我就发现 Hadoop 和 Elastic 都有人遇到过类似的问题:

•hadoop-client-minicluster build error creating shaded jar duplicate entry[3]•Maven shade plugin build fails without 'clean' goal[4]

不过,他们的解决方法都不是我想要的。Hadoop 的开发者发现先 clean 就行以后就心满意足的关掉了问题。Elastic 把会导致问题的依赖给重构掉了来绕过这个问题,而 Pulsar 的情形里这个依赖是无法规避的。

几乎确定是上游的问题,我在 Maven Shade Plugin 的问题列表上提交了一份报告。没错,不像之前几个例子马上开始尝试实现,出于上面提到的开发人员的惯性,我还是下意识地规避构建系统的问题,只是提交一个 issue 并期望上游维护者能够帮我解决。

不过,提交问题后不久,机缘巧合之下我开始替换 Pulsar Docker Image 构建的 Maven 插件以支持在 Apple M1 平台上运行:这或许归功于公司给我配备的新机器。这个过程里,我理解了数个构建容器镜像的 Maven 插件具体执行的逻辑,以及为什么在 Apple M1 上会报出相应的错误。这让我对以前认为看也看不懂并敬而远之的 Maven Plugin 生态有了新的看法:好像也不怎么难嘛。

•[refactor][ci] Build the docker image with docker-maven-plugin[5]

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

顺理成章地,半个月后我看到上面 Shade 插件的问题还是杳无音讯,就决定动手调试解决了。

这一次,不像 Spotless 的经历那样有现成可以借鉴的代码,需要我自己定位问题。不过从调试 Maven 插件的经历里,我大致知道了 Mojo 抽象的基本概念和执行路径。从报错信息里定位到相关类以后,我在代码中间加入了一系列日志来打印中间变量。在不好使用 debugger 来劫持执行流程的环境里,直接用 print 输出变量值是最值得依赖的手段。

因为问题的表征是创建 Zip 文件的时候有重复的被压缩的 Service 文件,我重点打印了 Shade 插件里合并 Service 文件时候的文件名,立刻发现被 relocate 的文件没有正确合并,而是重复处理了两次。顺着这个事实回过去看 Shade 插件的代码,很容易发现一个基本的逻辑错误。一开始,Shade 插件没有处理 relocate 规则。后来改了两次,但都没改完全。

•MSHADE-190: Shade does not relocate the contents of META-INF/services files[6] 修复了没有 relocate Service 文件内容中的类名的问题,但是没有 relocate Service 文件自己以类名命名的文件名。•[MSHADE-182] Service file should be relocated.[7] 修复了 Service 文件在压缩成 Zip 文件前没有 relocate 的问题,但是没有考虑到同一个构建里可能出现多个初始名称不同,但是 relocate 以后名称相同的文件,需要提前合并的问题。•[MSHADE-425] Relocate services name before add to serviceEntries[8] 我做的最终改动,简单改变了操作的顺序,修复了上面提到的最后一个问题。

虽然报告问题以后半个月上游没有处理,但是我定位了问题,明确分析出原因和提供了易懂的解法以后,加上从 commit 历史逮捕最近比较活跃的 maintainer at 上,第二天就有两位 reviewer 参与 review 并且最终合并了我的补丁。这改变了我打破了 Maven 社群的刻板印象。

合并以后,这次确实有下游 Pulsar 的用例等着升级版本来修复问题,因为我自己没有权限发布新版本,所以我再次使用上面提到的定型文催促发布:

@rmannibucau @slawekjaranowski I may be a bit in a hurry but I'd like to know whether/when we can have a release for this fix. It resolves one or several downstream use cases and I'm happy to upgrade for this fix.

It's not a request, though.

两位 reviewer 告诉我可以到邮件列表上寻求帮助。我就订阅了 [email protected][9] 邮件列表,直接请问有没有维护者愿意帮我这个忙。

•[DISCUSS] Release maven-shade-plugin 3.3.1?[10]

没想到 Maven 的 PMC Chair Karl Heinz Marbaise 马上回复可以在周末的时候发起新版本发布的投票,最终也确实在当周就发布完成,我也在下游升级到新版本解决了问题。

这段经历给我的启示是,上游优先可以是无处不在的。Hadoop 和 Elastic 社群里报告问题的人没有想过相对陌生的构建系统也可以接受补丁修复问题,而是习惯性把它当做一个外部的依赖,一个自己无法干涉的依赖。但是,或许我们还有更好的方式来解决自己的问题。如果一个问题技术上应该在上游解决,为什么不试着就在上游解决呢?

References

[1] Maven Shade Plugin: https://github.com/apache/maven-shade-plugin
[2] [Bug] Maven deployment failed on project pulsar-presto-connector-original: https://github.com/apache/pulsar/issues/17047
[3] hadoop-client-minicluster build error creating shaded jar duplicate entry: https://issues.apache.org/jira/browse/HADOOP-13941
[4] Maven shade plugin build fails without 'clean' goal: https://github.com/elastic/apm-agent-java/issues/961
[5] [refactor][ci] Build the docker image with docker-maven-plugin: https://github.com/apache/pulsar/pull/17148
[6] MSHADE-190: Shade does not relocate the contents of META-INF/services files: https://github.com/apache/maven-shade-plugin/commit/c334dfedebf142ea07fc967ea31e6c1552a8c13b
[7] [MSHADE-182] Service file should be relocated.: https://github.com/apache/maven-shade-plugin/commit/871910182cf14c4961b996a34c98ee010f798d73
[8] [MSHADE-425] Relocate services name before add to serviceEntries: https://github.com/apache/maven-shade-plugin/pull/150
[9] [email protected]mailto:[email protected]
[10] [DISCUSS] Release maven-shade-plugin 3.3.1?: https://lists.apache.org/thread/owqboz3n11qr3ndvj8m798j4r5gthdq0

猜你喜欢

转载自blog.csdn.net/weixin_44723515/article/details/127255637