我一直在使用Lombok,我对它非常满意,这让我的懒惰可以避免编写样板代码.但关于龙目岛有一些令人担忧的信息,比如:

  1. 我读了here篇文章,说Lombok完全依赖于JDK中的一个漏洞,一个非法的非公共API,如果关闭它,在某个时候将导致Lombok停止工作.甚至可以看到Lombok开发人员与OpenJDK开发人员争论,让JDK非公共API保持打开,或者保留一个选项,使他们能够在它关闭时将其撬开(--add-open--illegal-access标志).但到目前为止,龙目鱼甚至可以用v1.18.26处理Java 19.

  2. 许多人说,如果你出于任何原因决定放弃龙目岛,那么你可以很容易地使用De-Lombok.然而,有an article个人描述De-Lombok可能不是很好.

所以,我的问题是:

  1. 龙目岛会停止工作吗?或者Java还没有堵住那些漏洞的非公共API吗?

  2. 使用另一个批注处理器会如何导致Lombok失败?

推荐答案

龙目岛的作者.

龙目岛会停止工作吗?

不太可能.

我们在IntelliJ IDEA中是一个插件,在Eclipse中或多或少是一个插件;这些路由不能关闭,也不是Oracle/OpenJDK的目标.即使他们想这样做,他们也根本不经营这些项目.另外,"非法"指的是一个国家的刑法.无论Oracle/Team OpenJDK喜欢说什么,"非法"都不是合适的术语.这是一条团队OpenJDK不正式支持的API访问路由.这里没有任何许可违规,所以我们在措辞上要小心.同时,Lombok在Java版本6到21上运行;很少有库能达到这种程度.

我们总能分出javac块钱.它是开源的.我们知道如何做到这一点,如果真的到了那一步,我们会这样做.然而,作为用户,您的体验将是恼人的.它还会 destruct 这样一种观点,即javac不是您自己调用的工具;通常其他工具调用它,并且往往不允许您轻松地配置javac所在的位置,这使得Forking 更难使用.然而,在实践中,我们可以列举您可能遇到的工具,特别是因为javac虽然是开源的,但并没有得到非常许可的许可,而且任何试图使用javac作为更大工具的一部分的try 都会受到与javac(作为API)相同的好战锁定处理:不支持try 与它深度纠缠,所以您真正能做的就是将其称为命令行工具,真的.

这使得为这些工具编写插件变得非常简单.我们只需要添加大约--add-opens行代码,否则就可以逐字运行javac,或者只需将Lombok混合到它的模块中并发布即可.

具体地说,我们可以命名所有与javac的互动的99%:

  • Maven
  • Gradle
  • 您的IDE(但我们已经需要并拥有这些插件)
  • javac美元,但很少.

基本上,就是这样.大多数LinterTools和其他基于AST的分析器实际上在幕后使用ecj(Eclipse的编译器),而不是javac.例如,Visual Studio代码使用Eclipse作为语言服务器.可能是因为ecj的速度要快得多.可能是因为它更有许可证(MIT-style款,而不是GPL款).

因此,如果团队OpenJDK堵住我们现在使用的每一个漏洞,Lombok真正需要做的就是为Gradle和Maven编写插件.这不是问题:这两个工具基本上都已经是基于插件的,编写这些插件只需要一周的工作.一旦存在这样的插件,OpenJDK就没有表示有任何兴趣关闭这条路由.如果他们改变主意并try 这样做,他们将不得不change the licensing first,我认为这不太可能发生,但你必须自己决定.当然,如果OpenJDK改变它的许可,那么[A]它的名字将是一个Jest ,[B]这将对生态系统产生非常重大的影响.事实上,如果发生这种极端的步骤,Lombok可能不应该把它的许可问题列为首要关注的问题,[C]社区肯定会immediately分出最后的开放源码版本,找到一个新的名称(Oracle拥有‘Java’和‘OpenJDK’商标),社区在某种程度上可能会同意这个项目,在这一点上完全抛弃Oracle/OpenJDK.你可能会有不同的评价,但我要说的是,很明显,这不是一个在这个时间点上现实的应急措施.

关于Delombok的那篇文章

我感觉受到了攻击.天哪,这是一篇写得很糟糕的文章.他们提出的第一点,也就是本文的一半,是关于一个奇异的错误(即,枚举上的@ToString做了错误的事情,这很奇怪,因为枚举已经有了可行的tostring.是的,这是一个漏洞),不知何故,将其转化为某种类型的‘看到了吗?这是奇怪的和糟糕的’.我不知道你是怎么想的,但如果我是按照这样的原则来编程的:如果我遇到一个a single bug依赖项,我就会immediately抛弃那个依赖项,并写一篇关于它的讨厌的博客文章.在这一点上,我会把我自己的电脑焊接在一起.

然而,生成的文件非常难看,并且没有遵循任何样式

胡说八道.我们试图复制您的Tab键,并遵循标准的编码约定(或多或少,Google风格).我们还煞费苦心地不修改任何我们不需要修改的东西.

而不是像Guava Preditions或来自ApacheCommons的VALIDATE这样的一行解决方案.

您可以告诉Lombok生成这样的东西;我想作者在决定写那篇博客文章之前没有阅读他们使用的工具的文档.当然,我们不会无缘无故地要求更多依赖项.它也根本不是‘很多行’,而且它非常 struct 化,所以如果您出于某种原因真的不需要它们(但是,您添加了@NonNull个注释,它们除了添加那些判断之外什么都不做,所以这是一件奇怪的事情),很容易就把它们写掉.

(目前,Lombok仍面临Java 9-11的问题)

谎言.至少,我没有注意到任何错误,作者也没有说出他们在谈论什么.鉴于他们证明他们没有费心阅读任何文档或try 任何设置,这很可能是另一个试点错误情况.它是几年前编写的;Lombok在9和11上运行得很好.(在Java 9正式发布后,Lombok对Java 9的支持花了几个星期的时间.这种情况时有发生;但是,不确定‘Java 11’从哪里来).

Generally,德隆博克应该没问题.在Lombok为您生成a lot个样板(主要是@Builder个)的地方,生成的代码可能并不完全是您所编写的(比如,它很多),并且可能比您注册的更需要维护.然而,除了@Builder个,其余的都很简单.Lombok故意不喜欢陷入超越其取代样板的使命的错误中,这被定义为:

  1. 这是很常见的
  2. 有一种普遍认可的--或者至少是相当标准的--书写方式

当然,根据这个定义,delombok吐出的东西很可能就是如果Lombok不在的话你会怎么写它.Builder走这条线最多,但它要处理ton个样板,所以我们肯定会保留@Builder个.

Delomboked代码可能不完全遵循您的风格准则.这是相当可配置的,但"首选风格"是一个very广泛的话题.您可以(也许应该!)通过自动格式化程序丢弃您的delomboted代码.如果你通常不会自动格式化你的源文件,并且喜欢以你想要的方式自由地设置它的样式,那么这不是一个选项,但是,对delombok的配置进行任何附加以支持更多样式都是我们容易接受的PR类型.

使用另一个批注处理器会如何导致Lombok失败?

可能存在鸡和蛋的问题:注释处理器A运行(而不是Lombok),并根据它们看到的源代码 struct 锁定某些决策.Then Lombok跑动并增加了一些东西,但A已经向前看了.我们使用注释处理器的循环系统(所有AP,不仅仅是Lombok,都会受到此问题的影响,这就是为什么有循环系统),但Lombok修改了基本Annotation Processor规范所说的在循环之间通常不会改变的内容,因此并不是所有AP都能正确交互.很难说javac以什么顺序运行它们(通常,首先运行Lombok可以解决所有问题).每当发生这种情况时,我们都会try 与相关项目沟通,以确保修复任何问题,很少有AP基于代码 struct 生成代码(大多数基于注释生成!)出现这种情况的一个项目是MapStruct.我们试图与他们合作,以确保事情顺利进行,无论我们中的哪一个先参选.

如果您使用另一个使用源 struct 的AP作为输入,您可能会遇到一些麻烦,是的.无论如何,为您的构建系统编写插件很可能完全解决了这个问题(如果我们这样做了,我们可以强制Lombok首先运行).

Java相关问答推荐

是否有一种格式模式,可以在除0之外的数字前面有正负符号?

Annotation @ Memphier无法正常工作,并表示:class需要一个bean,但找到了2个bean:

RxJava PublishSubject缓冲区元素超时

错误:在Liferay7.4中找不到符号导入com.liferay.portal.kernel.uuid.PortalUUID;";

如何打印本系列的第n项y=-(1)-(1+2)+(1+2+3)+(1+2+3+4)-(1+2+3+4+5)...Java中的(1+2+3+4...+n)

Java 21 struct 化连接货币,需要可预知的子任务异常排序

内存中的H2修剪尾随空格

使用Mockito进行的Junit测试失败

什么是Java原子属性的正确getter和setter

PDFBox未加载内容

当b是一个字节并且在Java中值为-1时,为什么b>;>;>;1总是等于-1?

Java创建带有扩展通配符的抽象处理器

向Java进程发送`kill-11`会引发NullPointerException吗?

在ECLIPSE上的M1 Pro上运行JavaFX的问题

如何制作回文程序?

Java类型推断:为什么要编译它?

Kotlin-仅替换字符串中最后一个给定的字符串

保持标题窗格的箭头可见,即使设置为不可折叠

如何在 WebSphere Application Server 内的托管线程上运行 BatchEE 作业(job)?

为什么 Random() 的行为不符合预期?