有多少人还在用 Maven 构建项目?

14 天前
 diagnostics

最近用 maven 有些槽点(当然也可能是我自己对 maven 的学习也不够深入), 我既写 java 也写 scala, 有人在 scala 帖子诟病的 sbt 难用,相比之下 maven 才是真的“难用”。

我说的难用不是指难安装、简单打包,而是带一些场景:

1. xml 问题

xml 可读性某些层面太差了,过于繁琐,对版本管理,子模块管理全部揉杂在一起

2. 子模块管理问题

我们的项目组开发是一个 framework 的,也就是自身需要维护一大堆依赖,被别人引用的时候也会带上这些依赖的版本。

我们尝试过像 spring 那样用:

但是 IDEA 的识别不够好,总是出现某些子模块的版本找不到( IDEA 无法识别到这些子模块就是我维护的,而不是第三方库,而是反过来,总是去远仓库下载而不是项目的 target 上查找)

后面我们直接用 root 管理所有的 dependenices ,还是有问题,但是遇到问题只能本地 install 一下

3. CICD 编写问题

我们用的是 Gitlab CI/CD ,由于模块太多,一个 mvn test 运行太慢了,等个 CI 的功夫能干很多事情,但是我们尽可能希望快一点验证 commit ,继续做后续的测试,所以我们搞了按模块区分的单测:例如 coreTest 、serverTest 、extensionTest 等。。。

maven 可以用 mvn test -pl core -pl server 这样解决,但是部分 extension 模块是依赖 server 或者 core 的,就只能用 mvn test -pl extension -am also make 依赖,这样的后果就是跑 extension 的时候,把 core 的单测也跑了(这还加速啥,依赖多的项目,很大概率直接跑个完整的 test )。 这个问题,我们后面用 profiles 解决了,但是维护起来太鸡巴蛋疼,太繁琐了(重构的时候)

4. 构建 Task 诊断问题

我改造 CICD 的时候,希望能利用上缓存机制,多个 task 来加速,但是我发现 compile 的时候也会把 validate 阶段的 enforce 插件也给跑了... 问题是,我看了下好像没有命令来看执行 xx 的时候会同时执行什么,只能跑一下 xx 然后看。。。

结论

可能我用 maven 的姿势不太对,但是越深入就越感觉这玩意不适合复杂项目,就适合简单做个:

clean 、test 、package 、install 、deploy

怀念 sbt...(尝试过 gradle 、迁移看了半天,需要考虑点有点多,还没正式打算改过去,改过去也不知道好不好)

ps:写 Java 的人里可能有大神,但是只写 Java ,写久了真的会降智(不思考合理性,不愿意接受其他,是的,我说的是我自己)

7997 次点击
所在节点    Java
126 条回复
cccssss
14 天前
看了评论,发现楼主说的都对。maven 是垃圾
hui9000
14 天前
maven 稳当啊。
mango88
14 天前
@diagnostics #16

我们也是 root + dependencyManagement 的多模块项目

可以在底层模块的 pom 里增加以下属性

```
<properties>
<maven.test.skip>true</maven.test.skip>
</properties>
```
also make 会跳过此依赖模块的 test case

对底层模块进行跑单测时候,在命令行里覆盖掉此参数
```
mvn test -pl xxx -Dmaven.test.skip=false
```
diagnostics
14 天前
@SoloCompany #40 IDEA 需要本地 install 一下就没问题,你觉得是版本没写对的问题?版本都是 1.0-SNAPSHOT 这种格式,只有发版后才会改为 1.1-SNAPSHOT ,maven 执行任何命令都没问题,只有 IDEA 报错。。。我尝试过 IDEA 用 maven 来编译,不好用。不如 sbt 这种能够后台运行的
diagnostics
14 天前
@mango88 #43 和我们做法差不多,不过我为了方便,用 profile 把一类的模块分组到一块了,还是那个问题,maven 的支持不太细
diagnostics
14 天前
@xubeiyou 不好用,必须用 docker 跑,天然比 jenkins 慢一个数量级,不然我也不会搞效率这个问题

除此之外,还有一个问题不支持多个 yml (虽然现在可以 include 了)无法区分 release 的 ci 和 merge request 的 ci
guyeu
14 天前
写 Kotlin 、Scala 和 Java 甚至还带点 C++的混合项目,用了 gradle 已经回不去了

1. 多模块的支持比 maven 好,虽然 maven 有优化这方面的计划,但随意增减模块不用先`mvn install`就可以成功构建体验感会好一些;
2. 增量构建在日常开发中的加速效果明显,如果你不用 IDEA 这么高级的东东,随时修改随时编译随时允许 UT 的体验感 maven 是比不了 gradle 的,如果用了 IDEA 这种高级货,那么 IDEA 的编译和 maven 的编译是基本上是冲突的,IDEA 编译会破坏 maven 的编译,两边就都没办法“增量了”;
3. 项目越花哨,对构建脚本的功能性要求就越强,就势必要自己写一些扩展,这方面 gradle 很容易,简单处理的话直接在 build.gradle{.kts}里写函数就好,但是 maven 就复杂多了,基本上都得新建项目(另外,现在 gradle 支持 Kotlin ,有 Android 开发经验的同学几乎没有上手难度);
4. 依赖的管理,用 maven 的话,有一种操作是在 pom.xml 里定义许许多多版本号的 properties ,然后在各种地方用,但是没办法跨项目用,gradle 有一个更优雅的搞法叫 versionCatalogs ,写一个 TOML 文件之后可以把它导入到各个项目;

然而 maven 这种完全声明式的构建机制是最简单,人类读起来也最没有心智负担的,如果项目的复杂度没有到一定程度,maven 就是最棒的(虽然 gradle 也在发明自己的声明式 DSL )
guyeu
14 天前
@diagnostics #46 gitlab 的 cicd 并不是必须用 docker 跑,gitlab-runner 支持很多种环境,而且允许用户自己注册自己的 runner 。docker 跑也不见得天然比 Jenkins 慢一个数量级。。。

release 的 ci 和 merge request 的 ci 可以用 rules 区分,rules 支持的规则就很多了,分支、事件源等等。。。这方面 Jenkins 使用的 webhook api 是很难和 gitlab 本身比的。
diagnostics
14 天前
@guyeu #47 遇到大佬了

1. 最让我烦的就是增减模块的问题,3.6 比 3.5 多增加一个模块特性,就在哪里报错,但是日常开发有时候又需要去看 3.5 甚至 3.4 用户的 bug
2. 用了 sbt 的 增量就回不去了,IDEA 可以的构建可以用 maven 代替,但是实在兼容不好,不知道谁的问题
3. 暂不评价
4. 学习了
diagnostics
14 天前
@guyeu #48 不用 docekr ,我理解不同 job 任务之间没法隔离吧? ci 也都是从一个 image 开始,runner 的话,我记得我 4 年前看得文档是只能用 docekr 启动,宿主机直接安装 runner 好像当时觉得不干净没搞,后面都是公司 devops 在维护,只能说速度一言难尽,也可能是我们这边的问题,我们目前的 ci 没用到 gitlab 的 cache artifact
monkeyk
14 天前
我们企业级应用,一直用 maven ,熟悉,可控
nothingistrue
14 天前
感觉你不像是写 Java 的,Java 只能 Maven Gradle 二选一,一个 XML ,一个 Groovy ,都不能自洽,但没有第三个选择。

XML 比 Java 更通用,还是静态、对象语言,虽然是另一种语言,但比 Java 还更母语,只要 XML 能干,它永远都是作为 Java 的辅助配置的第一语言。于是 Maven 自然在大多数时候都能让 Gradle 靠边站——并不需要 gradle 有什么不好。

至于你的问题,一般人用不到,一般公司也遇不到。不过 Spring 是遇到了,它换了 Gradle 。
guyeu
14 天前
@diagnostics #50 默认情况下一个 runner 同时只会执行一个任务,所以不会出现任务之间互相影响的情况。速度的话,Linux 上的 docker 和 Mac/Windows 上的 docker 不是一个物种,具体情况还是要具体分析。
diagnostics
14 天前
@nothingistrue 我是写 Java ,所以才觉得这么久了,竟然只有 Java 和 Gradle 出来(更老的 ANT 就不说了)这两感觉都没有其他语言的构建工具好用
diagnostics
14 天前
@nothingistrue 对了还有我提到的 Bazel: https://bazel.build/community/users?hl=zh-cn
afeiche
14 天前
maven 比较适合固定的,变化不大的项目,一般配置好了,开发人员都不用去关注构建配置;你要是经常变,个性化需要比较多的,还是用 gradle 更灵活
unco020511
14 天前
gradle 好用
javaisthebest
14 天前
1. 你说 xml 可读性差 ? json 可读性倒是比 xml 强一点 但是配置一多又不支持注释 你在复杂项目里面再找一个比 xml 的语言更好的出来?


2. 多去接触其他几种语言再说这种话吧 go 就没有包管理工具 依赖管理 go get 在 maven 面前简直就是烧火棍 c++也和原始人的武器差不多 js 的包管理 可以这么说前端那群人和黄狗撒尿一样到处标记 到处建轮子包管理工具


最后
年轻人爱追逐新东西是好事 但是有的时候多出去走走接触下

发现还是特么 maven 简单好用傻瓜式操作
layxy
14 天前
我觉得 maven 还好吧,起码大家大版本一样只需要配置一次就可以了, gradle 下载开源项目,一个 gradle 版本下载一次,而且又大又慢,真不如 maven 方便,虽然配置方式比 maven 好点,公司 cicd 后端目前只支持 maven,不支持 gradle
Leon777
14 天前
看场景选工具,一种新工具被开发出来并流行必然是为了解决某个实际问题,如果你的项目没有遇到此类问题那没有必要强行跟风

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1050791

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX