扩展名为 .SCL.lombok 的文件

Files with the .SCL.lombok extension

在 Intellij 中打开 lombok jar 文件时,除了注释之外的所有文件都以 .SCL.lombok 结尾(例如 HandleAccessors.SCL.lombok)。我只是想知道这是什么原因以及它是如何处理的。

原因

Lombok 有一个 public API - 你 应该 与之互动的东西。例如,@lombok.Getter 注释。这些只是那个 jar 中的 class 文件,目的很简单:将那个 jar 添加到你的 class 路径,你的 IDE 自动完成对话框等将根据设计自动开始建议这些.

但是,lombok 也有很多 class 只是 'make it tick',这些并不适合 public 消费。像 lombok.eclipse.HandleGetter 这样的东西,它是在 eclipse 代理中处理 @Getter 注释的实现。在任何项目的任何地方引用此 class 都没有意义或目的 - 这是 lombok 内部的事情。如果我们只是将该 jar 文件插入 jar,然后您键入 Handle 并按下 IDE 的自动完成快捷键,您仍然会得到建议。

类似地,我们将一些依赖项直接发送到 lombok.jar - 这是一个 'shaded jar'(包含所有依赖项的 jar),尽管我们没有很多,但保持 lombok.jar一个不错的小尺寸。尽管如此,ASM(一个字节码操作库)仍在其中,而且相当受欢迎。

大多数着色工具提供的标准着色解决方案是在名称前加上一些前缀。 ASM 的 org.objectweb.asm.AnnotationVisitor class 将变为 org.projectlombok.shading.org.objectweb.asm.AnnotationVisitor。重点是,你的 IDE 不知道,如果你还在你的项目中使用 asm(你也使用 lombok),并且你想要 AnnotationVisitor 那么你输入 AnnV 并点击 cmd+space 或诸如此类的东西,您的 IDE 两者都建议。这很丑陋,我们希望避免这种情况。

因此,我们构建了自己的着色器,它的工作原理是首先没有 class 文件。这样,IDEs 和任何其他自动化工具甚至都不知道我们的 ASM classes 或我们的实现细节是否存在。此类工具(例如您的 IDE)看到的唯一文件是您想要看到的类型:lombok.Builderlombok.extern.slf4j.Slf4jlombok.experimental.UtilityClass 等。

它是如何工作的

Java 的 classloader 架构是抽象的:您可以自己制作。 class 加载器提供的原语很简单:“将这个包含字节码的字节数组(即 class 文件的内容)转换为 Class<?> 定义”,以及您'应该在你自己写的时候实现 classloader 是双重的:

  • 这里是一个资源键,比如“/com/foo/load.png”。请向我提供包含此数据的 InputStream。
  • 这是一个完全限定的 class 名称,例如“com.foo.MyApp”。请提供一个代表它的 Class<?> 实例。

开箱即用,java 附带默认的 classloader。这个默认的 classloader 通过检查你的 CLASSPATH 来回答这些问题——它可以通过多种方式提供(通过 jar 清单的 Class-Path 条目,或者通过 JVM 可执行文件的 -cp 参数,或者CLASSPATH 环境变量),并扫描 class 路径上的每个条目以查找请求的资源,能够读取文件系统以及打开 jar 文件。

但这只是 a classloader。融入 java 的一般原则的一种实现。你可以自己写。您可以编写一个 class 加载程序来动态生成资源,或者从网络加载它们。

或者,像 lombok 那样,通过打开自己的 jar 并查找 .SCL.lombok 文件来加载它们。

因此,lombok 的工作方式如下:当您启动它时,'entrypoint'(包含 public static void main 的 class - 或者在 lombok 的情况下,javac 模式它是注释处理器入口点,对于 eclipse,它是 agentmain),我们使用一些花哨的技巧从你那里 'hide' 它:agentmain 不需要在 public class 中(它不能是 .SCL.lombok 文件 - 我们的 classloader 还不可用,我们需要先 bootstrap!)。注释处理器确实必须在 public class 中,但是,它是一个 public class 在私有包 class 中,因此,几乎每个 IDE 知道它是 'invisible' 并且不会显示它,但是 javac 的注释 运行ner 接受它。

从那里,我们注册了一个 classloader,它能够通过读取 .SCL.lombok 文件来加载 classes,这让我们可以隐藏我们想要的所有其他内容隐藏。

我想开发 lombok,这妨碍了我!

不需要;只需克隆我们的存储库,运行 ant eclipseant intellij,然后就可以了。没有先分叉就无法扩展 lombok;我们希望 lombok 能够在没有它的情况下进行扩展,但这比不做 .SCL.lombok 事情要复杂得多。 Eclipse 运行s 在 equinox 之上,一个 运行 时间模块化系统,要使它正常工作需要各种各样的东西,这些东西会使 'just toss some extra handlers on the classpath' 不是在第一个扩展 lombok 的可行途径地点。