使用 Project Lombok 安全吗?

新手上路,请多包涵

如果您不知道 Project Lombok 可以帮助解决 Java 的一些烦恼,例如 使用注释生成 getter 和 setter, 甚至是 简单的 JavaBean,例如使用 @Data 生成。它真的可以帮助我,尤其是在 50 个不同的事件对象中,你有多达 7 个不同的字段需要用 getter 构造和隐藏。我可以用它删除近一千行代码。

但是,我担心从长远来看,这会是一个遗憾的决定。当我提到它时,将在 ##Java Freenode 频道中爆发 flamewars,提供代码片段会使可能的帮助者感到困惑, 人们会抱怨缺少 JavaDoc ,而未来的提交者可能只是将其全部删除。我真的很喜欢积极的一面,但我担心消极的一面。

那么:在任何项目(无论大小)中使用 Lombok 是否安全?正面影响值得负面影响吗?

原文由 TheLQ 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 821
2 个回答

听起来您似乎已经决定 Project Lombok 为您提议的新项目提供显着的技术优势。 (从一开始就明确,我对龙目岛项目没有任何特别的看法,不管怎样。)

在某些项目(开源或其他方式)中使用 Project Lombok(或任何其他改变游戏规则的技术)之前,您需要确保项目利益相关者同意这一点。这包括开发人员和任何重要用户(例如正式或非正式赞助商)。

你提到了这些潜在的问题:

一提到它,##Java Freenode 频道就会爆发 Flamewars,

简单的。忽略/不参与 flamewars,或者干脆避免提及龙目岛。

提供代码片段会使可能的帮助者感到困惑,

如果项目策略是使用 Lombok,那么可能的帮助者将需要习惯它。

人们会抱怨缺少 JavaDoc,

那是他们的问题。头脑正常的人不会试图将他们组织的源代码/文档规则严格应用于第三方开源软件。项目团队应该可以自由设置适合所用技术的项目源代码/文档标准。

跟进- Lombok 开发人员认识到,不为合成的 getter 和 setter 方法生成 javadoc 注释是一个问题。如果这是您项目的主要问题,那么一种替代方法是创建并提交 Lombok 补丁来解决这个问题。 )

无论如何,未来的提交者可能只是将其全部删除。

那没开!如果商定的项目策略是使用 Lombok,那么无故取消 Lombok 代码的提交者应该受到惩罚,并在必要时撤销他们的提交权。

当然,这是假设您已经获得了利益相关者的支持……包括开发人员。它假设你准备好为你的事业辩护,并适当地处理不可避免的反对声音。

原文由 Stephen C 发布,翻译遵循 CC BY-SA 3.0 许可协议

TL;博士:

是的,使用起来非常安全,我建议使用它。 (2022 年 5 月)


原始答案

今天刚开始使用龙目岛。到目前为止我喜欢它,但我没有看到提到的一个缺点是重构支持。

如果您有一个用 @Data 注释的类,它将根据字段名称为您生成 getter 和 setter。如果您在另一个类中使用这些 getter 之一,然后确定该字段命名不当,它将找不到这些 getter 和 setter 的用法并将旧名称替换为新名称。

我想这必须通过 IDE 插件而不是 Lombok 来完成。

更新(2013 年 1 月 22 日)

使用 Lombok 3 个月后,我仍然推荐它用于大多数项目。但是,我确实发现了另一个类似于上面列出的缺点。

If you have a class, say MyCompoundObject.java that has 2 members, both annotated with @Delegate , say myWidgets and myGadgets , when you call myCompoundObject.getThingies() 来自另一个类,不可能知道它是委托给 Widget 还是 Gadget 因为你不能再在 IDE 中跳转。

使用 Eclipse“Generate Delegate Methods…”可为您提供相同的功能,同样快速并提供源代码跳转。缺点是它会用样板代码使您的源代码变得混乱,从而使您无法集中精力处理重要的事情。

更新 2(2013 年 2 月 26 日)

5 个月后,我们仍在使用 Lombok,但我有一些其他烦恼。当您尝试熟悉新代码时,缺少已声明的 getter 和 setter 有时会很烦人。

例如,如果我看到一个名为 getDynamicCols() 的方法,但我不知道它是关于什么的,我有一些额外的障碍需要跳过以确定这个方法的目的。有些障碍是 Lombok,有些是缺少 Lombok 智能插件。障碍包括:

  • 缺少 JavaDocs。如果我对该字段进行 javadoc,我希望 getter 和 setter 将通过 Lombok 编译步骤继承该 javadoc。
  • 跳转到方法定义会将我跳转到类,但不会跳转到生成 getter 的属性。这是一个插件问题。
  • 显然,除非您生成或编写方法,否则您无法在 getter/setter 中设置断点。
  • 注意:这个参考搜索并不是我最初认为的问题。不过,您确实需要使用启用大纲视图的透视图。对于大多数开发人员来说不是问题。我的问题是我正在使用 Mylyn,它正在过滤我的 Outline 视图,所以我没有看到这些方法。 缺乏参考搜索。如果我想查看谁在调用 getDynamicCols(args...) ,我必须生成或编码 setter 才能搜索引用。

更新 3(2013 年 3 月 7 日)

我想学习使用 Eclipse 中的各种方式做事。您实际上可以在 Lombok 生成的方法上设置条件断点 (BP)。使用 Outline 视图,您可以右键单击方法 Toggle Method Breakpoint 。然后打BP的时候可以使用调试 Variables 查看生成的方法命名的参数是什么(一般和字段名一样)最后使用 Breakpoints 查看右键单击 BP 并选择 Breakpoint Properties... 添加条件。好的。

更新 4(2013 年 8 月 16 日)

当您在 Maven pom 中更新 Lombok 依赖项时,Netbeans 不喜欢它。该项目仍在编译,但文件被标记为存在编译错误,因为它看不到 Lombok 正在创建的方法。清除 Netbeans 缓存可解决该问题。不确定是否有像 Eclipse 中那样的“清理项目”选项。小问题,但想让它为人所知。

更新 5(2014 年 1 月 17 日)

Lombok 并不总是与 Groovy 兼容,或者至少 groovy-eclipse-compiler 。您可能必须降级您的编译器版本。 Maven Groovy 和 Java + Lombok

更新 6(14 年 6 月 26 日)

一句警告。 Lombok 有点让人上瘾,如果你从事的项目由于某种原因不能使用它,它会惹恼你。根本不使用它可能会更好。

更新 7(2014 年 7 月 23 日)

这是一个有点有趣的更新,因为它直接解决了 OP 询问的采用 Lombok 的 安全性 问题。

从 v1.14 开始, @Delegate 注释已降级为实验状态。详细信息记录在他们的网站上( Lombok Delegate Docs )。

问题是,如果您使用此功能,您的退出选项将受到限制。我看到的选项是:

  • 手动删除 @Delegate 注释并生成/手动编码委托代码。如果您在注释中使用属性,这会有点困难。
  • Delombok 具有 @Delegate 注释的文件,并可能添加回您想要的注释。
  • 永远不要更新 Lombok 或维护分叉(或使用体验功能)。
  • Delombok 你的整个项目并停止使用 Lombok。

据我所知, Delombok 没有删除注释子集的选项;至少对于单个文件的上下文而言,它是全有或全无。我打开 了一张票以请求带有 Delombok 标志的此功能,但我不希望在不久的将来出现。

更新 8(14 年 10 月 20 日)

如果它适合您,Groovy 提供了与 Lombok 相同的大部分优点,以及大量其他功能,包括 @Delegate 。如果您认为很难将想法推销给当权者,请查看 @CompileStatic@TypeChecked 注释,看看是否可以帮助您的事业。事实上, Groovy 2.0 版本的主要焦点是静态安全

更新 9(2015 年 9 月 1 日)

Lombok 仍在 积极维护和增强,这预示着采用的安全级别。 @Builder 注释是我最喜欢的新特性之一。

更新 10(2015 年 11 月 17 日)

这似乎与 OP 的问题没有直接关系,但值得分享。如果您正在寻找工具来帮助您减少所编写的样板代码的数量,您还可以查看 Google Auto - 特别是 AutoValue 。如果您查看他们的 幻灯片,就会将 Lombok 列为他们试图解决的问题的可能解决方案。他们为 Lombok 列出的缺点是:

  • 插入的代码是不可见的(你不能“看到”它生成的方法)[编辑注意 - 实际上你可以,但它只需要一个反编译器]
  • 编译器黑客是非标准和脆弱的
  • “在我们看来,您的代码不再是真正的 Java”

我不确定我在多大程度上同意他们的评价。考虑到幻灯片中记录的 AutoValue 的缺点,我将坚持使用 Lombok(如果 Groovy 不是一个选项)。

更新 11(16 年 2 月 8 日)

我发现 Spring Roo 有一些 类似的注释。我有点惊讶地发现 Roo 仍然存在并且查找注释文档有点粗糙。删除也不像 de-lombok 那样容易。龙目岛似乎是更安全的选择。

更新 12(2016 年 2 月 17 日)

在尝试为我目前正在从事的项目引入 Lombok 的安全性的理由时,我发现了一块黄金,其中添加了 v1.14 配置系统!这意味着您可以配置项目以禁止您的团队认为不安全或不需要的某些功能。更好的是,它还可以创建具有不同设置的目录特定配置。这太棒了。

更新 13(16 年 10 月 4 日)

如果这种事情对你很重要, Oliver Gierke 认为 将 Lombok 添加到 Spring Data Rest 是安全的。

更新 14(2017 年 9 月 26 日)

正如 @gavenkoa 在对 OP 问题的评论中指出的那样, JDK9 编译器支持尚不可用(问题 #985)。听起来这对 Lombok 团队来说也不是一个容易解决的问题。

更新 15(2018 年 3 月 26 日)

Lombok 变更日志表明从 v1.16.20 开始“ 现在可以在 JDK1.9 上编译 lombok ”,即使 #985 仍然打开。

然而,为适应 JDK9 而进行的更改需要一些重大更改;所有都与配置默认值的更改隔离。有点担心他们引入了重大更改,但该版本仅增加了“增量”版本号(从 v1.16.18 到 v1.16.20)。由于这篇文章是关于安全性的,如果你有一个自动升级到最新增量版本的 yarn/npm 类的构建系统,你可能会惊醒。

更新 16(2019 年 1 月 9 日)

似乎 JDK9 问题已经解决,据我所知,Lombok 可与 JDK10 甚至 JDK11 一起使用。

尽管从安全方面考虑,我注意到的一件事是,从 v1.18.2 到 v1.18.4 的更改日志列出了两项 BREAKING CHANGE !?我不确定 semver“补丁”更新中的重大变化是如何发生的。如果您使用自动更新补丁版本的工具,可能会出现问题。

更新 17(2021 年 3 月 17 日)

Lombok 开发人员和 OpenJDK 开发人员之间围绕 JDK 16 发生了一些戏剧性事件 。JDK 开发人员争辩说,Lombok 正在通过 JDK 团队想要关闭的漏洞利用未发布的 JDK 内部结构,但出于各种原因故意保持开放状态。

他们表达了他们的担忧(关于龙目岛的安全):

所有对内部的访问都将像以前一样保持可用,前提是客户端应用程序明确允许它,并承认它有意承担可能需要的任何维护(或安全)问题。

虽然 Lombok 可能认为他们在欺骗 OpenJDK,但他们所做的只是宣布他们有意欺骗自己的用户。

可能很快就会有一天,Lombok 将无法围绕 JDK 的安全限制找到任何更有创意的解决方案。即使他们这样做,在您的项目中使用 Lombok 的安全性也可能存在问题。

更新 18(22 年 5 月 11 日)

最近的一条评论要求总结,所以我把它放在最上面。

简短的回答是使用它非常安全,如果我们正在编写 Java 代码,我强烈建议使用它。

鉴于对 JDK 17 的支持已经有一段时间了,并且在 JDK 正式发布后不到一个月就发布了,所以 Lombok 的安全性很高。如果需要,您可以随时取消龙目岛。

作为一名顾问,我看到很多不同的公司是如何编写代码的。在过去的 5 年里,我的每个客户都使用过 Lombok。这些都是财富 1000 强公司。它加快了开发速度并减少了出错的可能性。

也就是说,您仍然需要跟上 JDK 的最新功能。考虑使用 Java record 关键字来使您的对象不可变,而不是使用某些 Lombok 功能。在有意义的地方使用 Lombok。使用 Lombok 配置选项来防止以您不同意的方式使用它。

因此,除非发生重大事件,否则这可能是我对此答案的最后更新。感谢大家的投票。我很高兴它有所帮助。

原文由 Snekse 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题