使用Project Lombok是否安全?

时间:2010-10-04 00:10:19

标签: java lombok

如果您不知道Project Lombok帮助解决Java的一些烦恼,例如generating getters and setters with annotations甚至simple JavaBean like generation with @Data。它可以真正帮助我,特别是在50个不同的事件对象中,你有多达7个不同的字段需要构建和使用getter隐藏。我可以删除近千行代码。

然而,我担心从长远来看,这将是一个遗憾的决定。当我提到它时,Flamewars会在##Java Freenode频道中爆发,提供代码片段会使可能的帮助者感到困惑,people will complain about missing JavaDoc,未来的委托人可能会将其删除。我真的很喜欢积极的,但我担心的是消极的。

那么:对任何小型或大型项目使用Lombok是否安全?积极影响是否值得消极?

15 个答案:

答案 0 :(得分:768)

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

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

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

更新(1月22日和13日)
使用Lombok 3个月后,我仍然推荐它用于大多数项目。但是,我确实发现了另一个与上面列出的相似的缺点。

如果您有课程,请说MyCompoundObject.java,其中有2位成员,同时注明@Delegate,说myWidgetsmyGadgets,当您拨打myCompoundObject.getThingies()时从另一个类中,不可能知道它是否委托给WidgetGadget,因为你不能再在IDE中跳转到源代码。

使用Eclipse"生成委托方法......"为您提供相同的功能,同样快速并提供源跳跃。缺点是它使用样板代码使您的源变得混乱,重点放在重要的东西上。

更新2(2月26日&13; 13)
5个月后,我们还在使用龙目岛,但我还有其他一些烦恼。缺乏宣布的吸气剂和当你试图熟悉新代码时,setter有时会很烦人。

例如,如果我看到一个名为getDynamicCols()的方法,但我不知道它的含义,我还有一些额外的障碍要跳过来确定这种方法的目的。一些障碍是龙目岛,一些是缺乏Lombok智能插件。障碍包括:

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

更新3(3月7日和13日)
我想在Eclipse中学习使用各种方法做事。实际上,您可以在Lombok生成的方法上设置条件断点(BP)。使用Outline视图,您可以右键单击方法Toggle Method Breakpoint。然后,当您点击BP时,您可以使用调试Variables视图来查看生成的方法命名参数(通常与字段名称相同),最后使用Breakpoints视图右键 - 单击BP并选择Breakpoint Properties...以添加条件。好的。

更新4(8月16日和13日)
当您在Maven pom中更新Lombok依赖项时,Netbeans不喜欢它。该项目仍在编译,但文件因编译错误而被标记,因为它无法看到Lombok正在创建的方法。清除Netbeans缓存可以解决问题。不确定是否有"清洁项目"像Eclipse这样的选项。小问题,但想让它知道。

更新5(1月17日和14日)
龙目岛并不总是与Groovy,或至少groovy-eclipse-compiler一起玩得很好。您可能必须降级编译器的版本。 Maven Groovy and Java + Lombok

更新6(6月26日和14日)
一句警告。龙目岛有点上瘾,如果你在一个你不能出于某种原因使用它的项目上工作,它会惹恼你的烦恼。你最好永远不要使用它。

更新7(7月23日及14日)
这是一个有趣的更新,因为它直接解决了OP询问的采用Lombok的安全

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

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

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

据我所知,Delombok doesn't have an option to remove a subset of annotations;它至少对于单个文件的上下文来说是全有或全无。我用Delombok旗帜开了a ticket to request this feature,但我不会在不久的将来期待它。

更新8(10月20日' 14)
如果它是您的选择,Groovy提供了龙目岛的大部分相同优势,以及其他功能的船载,包括@Delegate。如果您认为自己很难将这个想法卖给所有权力,请查看@CompileStatic@TypeChecked注释,看看这是否有助于您的事业。实际上,the primary focus of the Groovy 2.0 release was static safety

更新9(9月1日和15日)
龙目岛仍然是actively maintained and enhanced,这预示着采用的安全水平。 @Builder注释是我最喜欢的新功能之一。

更新10(11月17日&15; 15)
这似乎与OP的问题没有直接关系,但值得分享。如果您正在寻找工具来帮助您减少所编写的样板代码的数量,您还可以查看Google Auto - 特别是AutoValue。如果您查看他们的slide deck,列表Lombok可能是他们试图解决的问题的解决方案。他们为龙目岛列出的缺点是:

  • 插入的代码是不可见的(你可以'"参见"它生成的方法)[编号 - 实际上你可以,但它只需要一个反编译器]
  • 编译器黑客是非标准且脆弱的
  • "在我们看来,您的代码不再是Java"

我不确定我对他们的评价有多赞同。鉴于幻灯片中记录的AutoValue的缺点,我将坚持使用Lombok(如果Groovy不是一个选项)。

更新11(2月8日和16日)
我发现Spring Roo有一些similar annotations。我有点惊讶地发现Roo仍然是一个东西,找到注释的文档有点粗糙。去除也不像de-lombok那么容易。龙目岛似乎是更安全的选择。

更新12(2月17日和16日)
在尝试为我目前正在进行的项目带来龙目岛安全的原因时,我找到了一块金牌,其中添加了v1.14 - {{{ 3}}!这意味着您可以配置项目以禁止您的团队认为不安全或不合需要的某些功能。更好的是,它还可以使用不同的设置创建特定于目录的配置。这太棒了。

更新13(10月4日和16日)
如果这种事情对您很重要,Configuration System认为Oliver Gierke是安全的。

更新14(9月26日及17日)
正如add Lombok to Spring Data Rest在对OP问题的评论中所指出的,@gavenkoa(问题#985)。这听起来似乎不会让Lombok团队轻松解决。

更新15(3月26日和18日)
Lombok更改日志表示自v1.16.20" JDK9 compiler support isn't yet available"即使Compiling lombok on JDK1.9 is now possible仍然开放。

但是,为适应JDK9而进行的更改需要进行一些重大改变;所有与配置默认值的更改隔离。关于他们引入了重大改变,这有点令人担忧,但这个版本只是碰撞了#34;增量"版本号(从v1.16.18到v1.16.20)。由于这篇文章是关于安全性的,如果你有一个yarn/npm类似的构建系统自动升级到最新的增量版本,你可能会陷入一种粗鲁的觉醒。

更新16(1月9日和19日)

似乎#985和Lombok与JDK10一起工作,甚至JDK11也是如此。

我注意到的一件事是安全方面的问题是从v1.18.2到v1.18.4的更改日志列出了BREAKING CHANGE两个项目!我不确定在一个semver"补丁"中是如何发生突破性变化的?更新。如果您使用自动更新修补程序版本的工具,则可能会出现问题。

答案 1 :(得分:172)

听起来您已经确定Project Lombok为您提出的新项目带来了显着的技术优势。 (从一开始就要清楚,我对Lombok项目没有特别的看法,无论如何。)

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

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

  

当我提到它时,## Java Freenode频道会发生Flamewars,

易。忽略/不参加火焰战争,或者干脆提及龙目岛。

  

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

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

  

人们会抱怨缺少JavaDoc,

这是他们的问题。没有人在正确的思想中试图将他们组织的源代码/文档规则严格地应用于第三方开源软件。项目团队应该可以自由设置适合所用技术的项目源代码/文档标准。

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

  无论如何,未来的通勤者可能会将其删除。

那不是!如果商定的项目策略是使用Lombok,那么那些无偿地删除代码的委员应该受到惩罚,并在必要时撤回其提交权。

当然,这假设您已获得利益相关者的支持......包括开发人员。它假设你准备好争辩你的事业,并妥善处理不可避免的不同意见。

答案 2 :(得分:113)

继续使用Lombok,您可以在必要时“删除”您的代码http://projectlombok.org/features/delombok.html

答案 3 :(得分:73)

个人(因此主观上)我发现使用Lombok使我的代码更能表达我想要实现的内容,而不是IDE /自己的复杂方法实现,例如hashcode&等于

使用时

@EqualsAndHashCode(callSuper = false, of = { "field1", "field2", "field3" })

保持Equals&更容易与任何IDE /自己的实现相比,HashCode一致并跟踪评估哪些字段。当你还在定期添加/删除字段时尤其如此。

同样适用于@ToString注释及其参数,这些注释清楚地传达了有关包含/排除字段,getter或字段访问的使用以及是否调用super.toString()的所需行为。

再次通过使用@Getter@Setter(AccessLevel.NONE)注释整个类(并且可选地覆盖任何不同的方法),可以立即清楚哪些方法可用于这些字段。

好处还在继续......

在我看来,这不是关于减少代码,而是关于清楚地传达你想要实现的东西,而不是必须从Javadoc或实现中弄清楚它。简化代码只是更容易发现任何发散方法实现。

答案 4 :(得分:20)

龙目岛很棒,但是......

Lombok打破了注释处理的规则,因为它不会生成新的源文件。这意味着如果他们期望getter / setter或其他任何东西存在,它就不能与另一个注释处理器一起使用。

注释处理以一系列轮次运行。在每一轮中,每一轮都会轮到跑。如果在回合完成后找到任何新的java文件,则开始另一轮。这样,如果注释处理器仅生成新文件,则它们的顺序无关紧要。由于lombok不会生成任何新文件,因此不会启动新轮次,因此某些依赖于lombok代码的AP无法按预期运行。使用mapstruct时,这对我来说是一个巨大的痛苦来源,并且删除它不是一个有用的选项,因为它会破坏日志中的行号。

我最终破解了构建脚本以使用lombok和mapstruct。但我想放弃lombok,因为它至少是hacky - 至少在这个项目中。我总是在其他东西中使用lombok。

答案 5 :(得分:17)

还存在长期维护风险。首先,我建议阅读龙目岛实际上是如何工作的,例如:其开发人员here的一些答案。

官方网站还包含list of downsides,包括来自Reinier Zwitserloot的引用:

  

这完全是黑客攻击。使用非公共API。放肆的铸造(知道   在javac中运行的注释处理器将获得一个实例   JavacAnnotationProcessor,它是内部实现的   AnnotationProcessor(一个接口),碰巧有一对   用于获得实时AST的额外方法。

     

在eclipse上,它可能更糟(并且更强大) - 一个java代理   用于将代码注入eclipse语法和解析器类,   这当然完全是非公开API,完全不受限制。

     

如果你可以做lombok用标准API做的事情,我会做的   就这样,但你做不到。不过,为了它的价值,我开发了它   eclipse v3.5的eclipse插件在java 1.6上运行,没有   在java 1.5上运行的eclipse v3.4上进行任何更改   好吧,所以它并不是完全脆弱。

总结一下,虽然Lombok可能会为您节省一些开发时间,但如果存在非向后兼容的javac更新(例如,漏洞缓解),Lombok可能会让您遇到旧版Java,而开发人员则需要更新他们的使用那些内部API。这是否是一个严重的风险显然取决于项目。

答案 6 :(得分:15)

我在几乎所有项目中都使用了龙目岛一年,但不幸的是将其删除了。一开始它是一种非常干净的开发方式,但为新团队成员建立开发环境并不容易和直截了当。当它变得头疼我刚刚删除它。但这是一项很好的工作,需要更简单的设置。

答案 7 :(得分:14)

我知道我迟到了,但我无法抗拒诱惑:任何喜欢龙目岛的人都应该看看Scala。您在Lombok找到的许多好主意都是Scala语言的一部分。

关于你的问题:让开发人员尝试使用Lombok比使用Scala更容易。尝试一下,如果他们喜欢,请尝试Scala。

正如免责声明:我也喜欢Java!

答案 8 :(得分:13)

我读了一些关于龙目岛的意见,实际上我在一些项目中使用它。

嗯,在与龙目岛的第一次接触中,我的印象很糟糕。几周后,我开始喜欢它了。但几个月后我发现了很多使用它的小问题。所以,我对龙目岛的最终印象并不那么积极。

我以这种方式思考的理由:

  • IDE插件依赖。 IDE对Lombok的支持是通过插件实现的。即使在大多数情况下工作良好,您仍然是这些插件的人质,以便在未来版本的IDE和even the language version中进行维护(Java 10+将加速语言的开发)。每个例子,我试图从Intellij IDE 2017.3更新到2018.1,我不能这样做,因为实际的lombok插件版本存在一些问题,我需要等待插件更新...这也是一个问题,如果你我想使用一个没有任何Lombok插件支持的替代IDE。
  • '查找用法问题。。使用Lombok,您看不到生成的getter,setter,构造函数,构建器方法等。因此,如果您计划通过IDE了解项目中正在使用的这些方法,则不能只执行此操作寻找拥有这种隐藏方法的类。
  • 开发人员无需打破封装这么容易。我知道龙目岛并不是一个真正的问题。但是我看到开发人员更不愿意再控制哪些方法需要显示与否。因此,很多时候他们只是在不考虑类真正需要暴露的方法的情况下复制和粘贴@Getter @Setter @Builder @AllArgsConstructor @NoArgsConstructor注释。
  • 构建器Obssession ©。我发明了这个名字(下车,Martin Fowler)。除了笑话之外,Builder很容易创建,即使一个类只有两个参数,开发人员更喜欢使用@Builder而不是构造函数或静态构造函数方法。有时他们甚至尝试在lombok Builder中创建一个Builder,创建奇怪的情况,如MyClass.builder().name("Name").build().create()
  • 重构时的障碍。如果您正在使用@AllArgsConstructor并且需要在构造函数上添加一个参数,则IDE无法帮助您在实例化类的所有位置(主要是测试)中添加此额外参数
  • 将龙目岛与具体方法混合。您不能在所有场景中使用Lombok来创建getter / setter / etc.因此,您将在代码中看到这两种方法混合在一起。你会在一段时间后习惯这种情况,但感觉就像是对语言的破解。

就像另一个回答所说的那样,如果你对Java的冗长感到愤怒并使用龙目岛来处理它,请尝试Kotlin。

答案 9 :(得分:10)

当我向我的团队展示项目时,热情很高,所以我认为你不应该害怕团队的反应。

  • 就投资回报率而言,它很容易整合,并且不需要更改其基本形式的代码。 (只需在您的班级中添加一个注释)

  • 最后,如果你改变主意,你可以运行unlombok,或让你的IDE创建这些setter,getters和ctors,(我认为一旦他们看到你的pojo有多清楚,就没有人会要求变)

答案 10 :(得分:10)

想要使用lombok的@ToString但很快就会遇到Intellij IDEA中项目重建的随机编译错误。在增量编译成功完成之前,不得不多次编译。

使用Intellij IDEA 12.1.6和13.0尝试了lombok 1.12.2和0.9.3,在jdk 1.6.0_39和1.6.0_45下没有任何lombok插件。

必须从delomboked source手动复制生成的方法,并将lombok保留到更好的时间。

<强>更新

仅在启用并行编译时才会出现问题。

提起问题: https://github.com/rzwitserloot/lombok/issues/648

<强>更新

  

mplushnikov于2016年1月30日发表评论:

     

更新版的Intellij   没有这样的问题了。我想它可以在这里关闭。

<强>更新

我强烈建议尽可能从Java + Lombok切换到Kotlin。 因为它已经彻底解决了Lombok试图解决的所有Java问题。

答案 11 :(得分:8)

我对Lombok的看法是,它只是提供了编写bolilerplate Java代码的快捷方式 当使用快捷方式编写bolilerplate Java代码时,我会依赖IDE提供的这些功能 - 就像在Eclipse中一样,我们可以转到菜单Source&gt;生成Getters和Setter以生成getter和setter 我不会依赖像龙目岛这样的图书馆:

  1. 它使用替代语法的间接层(阅读@Getter@Setter等注释)污染您的代码。我不会学习Java的替代语法,而是切换到本机提供Lombok语言的任何其他语言。
  2. Lombok需要使用支持Lombok的IDE来处理您的代码。这种依赖性为任何非平凡的项目带来了相当大的风险。开源Lombok项目是否有足够的资源来继续为各种可用的Java IDE提供支持?
  3. 开源Lombok项目是否有足够的资源来继续为将来出现的Java新版本提供支持?
  4. 我也感到紧张,Lombok可能会在广泛使用的框架/库(如Spring,Hibernate,Jackson,JUnit,Mockito)中引入与运行时字节代码一起使用的兼容性问题。
  5. 总而言之,我不喜欢&#34;加强&#34;我的Java与龙目岛。

答案 12 :(得分:6)

我遇到了 Lombok Jackson CSV 的问题,当我将我的对象(java bean)编组为CSV文件,列重复时,我删除了Lombok& #39; s @Data注释和marshalizing工作得很好。

答案 13 :(得分:1)

我不推荐它。我以前习惯使用它,但是当我使用NetBeans 7.4时,它会弄乱我的代码。我要删除项目中所有文件中的lombok。有delombok,但我怎么能确定它不会搞砸我的代码。我必须花几天时间才能删除lombok并回到普通的Java样式。我太辣了......

答案 14 :(得分:0)

我还没有尝试过使用龙目岛 - 它是我的列表中的下一个,但听起来好像Java 8已经造成了很大的问题,并且补救工作在一周前仍在进行中。我的来源是https://code.google.com/p/projectlombok/issues/detail?id=451