IDEA 社区版和旗舰版果然还是有-内在区别-的吧

2020-12-23 19:39:30 +08:00
 monetto

在公司开发 Java6 的老项目,团队里有人用了 Lombok,版本是 1.16 。

楼主一直用的社区版+Smart Tomcat 插件开发。奈何动不动就抽风报错,提示找不到符号(1.16 的 Lombok 应该是无法与 IDEA 2020.1 以后的版本配合使用的)。这只是其中一个问题。

还有就是代码本身没问题,然后 IDEA 编译就报错,文件爆红了,结果打开文件,爆红自己一会消失了。无奈。

上面你这两个问题都可以通过使用 Maven 构建解决。但是今天碰到了个问题,SmartTomcat 插件配合 Tomcat8.5 启动一个项目,半天启动不起来,不是报没找到符号,就是报“实际参数列表和形式参数列表长度不同”,JAR 包版本什么都检查过了,最后启动起来了,IDEA 自己又报了个“ModuleUtilCore.findModuleForFile must not be null”,

也启动成功过几次,最后总结就是能不能启动完全看脸...真--迷惑。今天晚上实在启动不起来了,而且身边的同事一直都没这些问题(其他人一直用的旗舰版),遂楼主也试了下旗舰版,一次启动成功...非常轻松....真心跪了。

个人感觉 IDEA 社区版和旗舰版,除了支持 JavaEE 和 Spring 还有 JS 以外...还是有内在区别的...不只是功能上的区别...有了解的大佬吗?

10520 次点击
所在节点    Java
61 条回复
wbprime
2020-12-24 15:38:26 +08:00
Lombok 会在编译阶段修改类的字节码,导致字节码和 Java 源码不一致;开发的时候是面向字节码调用而不是面向源码;如果能接受这种方式,为什么不直接使用 Kotlin 或 Groovy 来与 Java 协同开发呢

AutoValue 则不一样,遵循 APT 规范,只会生成字节码而不修改字节码;开发的时候还是遵循的 Java 的面向接口开发的传统。
yazinnnn
2020-12-24 15:53:26 +08:00
不如拥抱 kotlin,拒绝 java
RedBeanIce
2020-12-24 23:09:14 +08:00
社区版本的 idea,好像无法运行 springboot 项目
lishen226
2020-12-25 04:38:12 +08:00
@RedBeanIce 可以的
jzmws
2020-12-25 09:21:31 +08:00
@young1lin 真的没必要去省个 get/set 方法, 怎么说把代码更多是给人看了 , 用法了 lombok 看不到 get/set 挺奇怪的.
还有就是 lombok 是基于 ide 的这个就很坑了,其他人用就要安装插件.
hangszhang
2020-12-25 10:20:53 +08:00
老子就是要用 lombok, 老子就是喜欢
hantsy
2020-12-25 12:04:35 +08:00
@jzmws 第一次听说 Lombok 基于 IDE 。上面都说,它是利用 JavaC APT,只要有 JavaC,脱离 IDE, 使用 Maven,Gradle 等就可以编译的。

而只有 NetBeans IDE 一开始就是默认启用 APT (同时支持源码处理,Classes 处理),很长一段时间我都是 NetBeans 开发,所有基于 APT 的都是不关心的。比如 JPA Metamodels,QueryDSL models,Lombok 等全部支持。
hantsy
2020-12-25 12:11:41 +08:00
@wbprime Lombok 修改 Classes 这种方式太常见了。

很早以前 AspectJ Compiler 也支持 Classes 层面的 Weaving, 在 Spring 中可以实现一些非 Spring 管理可以用注入(@Inject,@Autowired )。

几乎所有的 JPA 实现,包括 Hibernate,EclipseLink 等,都是可以使用 ByteCode Enchancing 代替 Runtime Proxy,实现颗粒度更细的 Lazy 操作,比如 Hibernate 用 ByteCode Enchaner 可以实现 Property 级别的 Lazy 。
hantsy
2020-12-25 12:18:55 +08:00
整个楼都是歪了。

Lombok 可以带来开发上效率,让代码看起来更简洁,在没有使用 Record 或者切换到 Kotlin 之前,这是个非常不错的方案。

至于抱怨编译错误的,应该多找找自己的原因。如果一个团队,因为某个人没有安装 Lombok Plugin 等产生抱怨,多想想团队管理方面的问题。
hantsy
2020-12-25 12:20:36 +08:00
@RedBeanIce 只要是个 Java IDE 都是可以运行 Java Application main 方法。VSCode Java pack 也可以轻松解决。
另外 ,Command CLI,不管是 Maven 还是用 Gradle 人人都是会用。
jzmws
2020-12-25 16:03:22 +08:00
@hantsy 如果用了 Lombok 其他人用 ide 修改时候就要要安装 Lombok 插件

这个东西我在 18 年时候用过一次, 其他同事上没有 lombok 插件导致都是报错,然后就不用了 ,
对了这个鬼东西在做代码静扫描也是出错的.
jzmws
2020-12-25 16:19:24 +08:00
@hantsy 楼歪了,lombok 这个东西是喜欢的人对他爱不释手,讨厌的人对它恨之入骨;

首先 Lombok 做了什么事情 ,不用写 set/get/toStirng 方法(set/get 用的最多把,其他的功能用到的比较少把),还有就是日志,是解决了一大痛点. 所以有它存在的意义,少了 set/get 日常写的 bug 也清爽干净多了

另外一个是 代码更多时候是给人看的,少了 get/set 修改时候不够直观(这个也算是自己能力不够) ,另外一个是别人要看带 Lombok 注解的代码 就要在 ide 上按照 Lombok 插件(楼上说 idea 2020.3 自带了,企业上用 一般不轻易升级 idea 的,如果用 eclipse 的呢?) 缺少了通用性 . 另外用 ide 上自动生成的 get/set 方法也是很方便.

我的看法是 lombok 你可以用,但是不能用在工作项目上, 所有工作的要以稳为先, 新的技术也要大胆学习使用.
jzmws
2020-12-25 16:23:51 +08:00
@hantsy

@Hurriance 说的入侵时值别人再编译这份代码的时候把
wbprime
2020-12-25 17:46:19 +08:00
@hantsy 感觉你在混淆概念。

Lombok 是在编译期修改 AST 的方式修改字节码,这种行为是非预期的不具有可移植性的。而且由于 getter setter constructor logger 等都是在编译期生成的,导致的一个现象就是开发者在开发时面向想象编程的(就算在 IDE 插件的帮助下能自动提示)。正经的 APT 类的工具是生成新的类,使用的时候一般是通过接口或父类来使用,这个是符合 Java 开发实践的。

而你所说的 weaving,是在运行期的。这个行为也是标准的,跨 JDK 兼容的。而且这种运行时也大部分是生成字节码而不是修改字节码,通过 DI 来 intercept 对象创建过程。少量的修改字节码的工具,一般用在测试中。

我之所以不喜欢在 Java 项目中使用 Lombok,是因为其使用了非标准化的私有的 API,相当于自己实现了一个 JAVM based language 的编译器,导致代码不纯洁;至于 IDE 什么的倒是次要的。Lombok 想要解决的问题确实存在,但是也都有其他替代方案:Getter/Setter/Builder 考虑 AutoValue & FreeBuilder ; Log support 考虑使用 Google Flogger ; var 考虑 JDK 11 ;等等。

以上 _^_^_。

补充,lombok 不仅仅是使用了 APT 技术,APT 没有提供修改 AST 的方法,lombok 使用了 OpenJDK/Oracle JDK javac 私有的 API,而这些 API 不保证兼容性,see <https://notatube.blogspot.com/2010/11/project-lombok-trick-explained.html>。虽然当前的主流 JDK 都是 OpenJDK based,Lombok 也对 OpenJ9 做了适配,但是技术的发展是难以预计的,没准几年内有另外一个 Anti-OpenJDK 的新 JDK 发行版面世且获得了巨大成功呢(这并非不可能的,想想 GraalVM 。。。)
hantsy
2020-12-25 20:13:52 +08:00
@wbprime AspectJ 编译时处理,这个我以前的用法,https://github.com/hantsy/angularjs-springmvc-sample/blob/master/pom.xml#L513

这是运行时?

以前 Spring 官方的 Spring Roo (强依赖 AspectJ 编译器),如果用过就知道什么叫编译时处理了。这种修改 Classes 的 Bytecode Enchaner 技术太常见了。比如,ByteMan,Javaassit 等项目。

Lombok 内部使用了 APT,还做 ByteCode 修改,我一点也不关心,因为到现在为止,这么多年的使用,仅遇到一次兼容性问题(而且 Google 下,早就有答案)。对我的项目,我只关心代码简洁了很多。在你项目没上 Java 15 以上,没用上 Record 前,你还需要这类的辅助工具来清理代码。setter,getters 很多时候都是满足一些 JavaBean 规范的需要。而在开发我更多的是使用生成的 Builder,用 RequiredArgsConstructor 去掉 Constructor,生成静态工厂 of, Value 只读( Dto ) 等。它实实在在的简化我的代码。AutoValue 能高明一些?
hantsy
2020-12-25 20:24:01 +08:00
开始用这类工具的时候,做了很多对比,除了 AutoValue, 有好几个类似的,
比如 Immutables,https://immutables.github.io/

Lombok 功能最全。
wbprime
2020-12-28 10:14:01 +08:00
@hantsy 我没有说 Lombok 不好用,人家开发者的技术比我高出了不知几万倍,全世界有很多人都在用它。

我想表达的观点是这个东西干了什么你一定要清楚,它使用的是非 Java 的方式来提升了开发效率;如果想要代码写的爽,除了 Lombok 之外,使用其他的 JVM based Language 与 Java 混合开发是一个更好的选择,一是全能全面,一是标准化。如果不需要很复杂的语言层面增强,只需要 Getter Setter 之类的,我更加推荐 AutoValue 。

以上。
hantsy
2020-12-28 11:00:19 +08:00
@wbprime 看了上面这么多,难道这么多用 Lombok 或者不使用 Lombok 都是只认为它只是生成 setters/getters ?
hantsy
2020-12-28 11:11:41 +08:00
那我说一下我的使用场景。

1,项目中,我觉得最有意义的可能是 @RequiredArgsConstructor 。Spring4 开始支持在只一个 Constructuor 的组件中,其参数是自动 Inject 的,不需要额外的 @Inject 或者 Autowired 。如:
https://github.com/hantsy/spring-reactive-jwt-sample/blob/master/src/main/java/com/example/demo/web/PostController.java#L26
2,Sfl4j 的使用,Spring Boot 默认使用 Logback,包括了 Sfl4j 接口。Sfl4j 也是我在工作中使用了上十年的 Log API 。大大简化我的工作。
3,@SneakyThrows 去掉 一些 Checkedexception 处理,Spring 不是从头到尾都是支持 Runtime Exception 吗?
4, @Builder POJO 最简单操作方式,不管是写测试准备数据,还是在代码做数据填充,Builder 非常方便。

至于 @Value,@Data @NoArgsConstructor 等,很多时候是满足规范需要,这些是所有的类似工具都是可以解决的问题。
hantsy
2020-12-28 11:14:23 +08:00
@Geekerstar 说 Lombok 坑的,不是什么菜,说白了,懒,就是我常常说的一些公司的巨婴。

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

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

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

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

© 2021 V2EX