编写自定义Lombok Annotation处理程序

我想编写自定义Lombok Annotation处理程序。 我知道http://notatube.blogspot.de/2010/12/project-lombok-creating-custom.html 。 但是当前的lombok jar文件不包含许多.class文件,而是包含名为.SCL.lombok的文件。

我发现,.SCL.lombok文件是.class文件,Lombok的构建脚本在生成jar文件时重命名它们,而ShadowClassLoader能够加载这些类 – 而且首字母缩略词SCL似乎来自于此。 似乎这样做的原因只是“避免使用基于SCL的jar污染任何项目的命名空间。IDE中的自动完成程序不会提出除实际公共API之外的任何内容。”

我只能通过编译我的自定义处理程序

  • 解压缩lombok.jar的内容
  • 将.SCL.lombok文件重命名为.class
  • 将生成的目录添加到编译类路径中

另外,为了能够使用我的自定义处理程序,我需要创建一个包含lombok类和我的自定义处理程序的新fat jar。 自定义lombok类加载器实质上阻止在其他多个jar中添加自定义处理程序。

这是扩展Lombok的唯一方法吗? 或者我错过了什么?

我使用以下的buildscript

apply plugin: 'java' repositories { jcenter() } configurations { lombok compileOnly } def unpackedAndRenamedLombokDir = file("$buildDir/lombok") task unpackAndRenameLombok { inputs.files configurations.lombok outputs.dir unpackedAndRenamedLombokDir doFirst { mkdir unpackedAndRenamedLombokDir delete unpackedAndRenamedLombokDir.listFiles() } doLast { copy { from zipTree(configurations.lombok.singleFile) into unpackedAndRenamedLombokDir rename "(.*)[.]SCL[.]lombok", '$1.class' } } } sourceSets { main { compileClasspath += configurations.compileOnly output.dir(unpackedAndRenamedLombokDir, builtBy: unpackAndRenameLombok) } } tasks.compileJava { dependsOn unpackAndRenameLombok } dependencies { compile files("${System.properties['java.home']}/../lib/tools.jar") compile "org.eclipse.jdt:org.eclipse.jdt.core:3.10.0" compile 'javax.inject:javax.inject:1' lombok 'org.projectlombok:lombok:1.16.6' compileOnly files(unpackedAndRenamedLombokDir) } 

在此期间,Reinier Zwitserloot创建了一个新的git-branch sclExpansionUpdate ,它包含ShadowClassLoader的更新版本:

ShadowClassLoader现在更友好地尝试扩展lombok。

你的(单独的)jar / dir应该有一个名为META-INF / ShadowClassLoader的文件。 该文件应包含字符串’lombok’。 如果你有,那个jar / dir中的任何类都将被加载到与lombok类相同的空间中。 您还可以将类文件重命名为.SCL.lombok,以避免其他加载器找到它们。

我想这还没有进入主分支,因为它肯定没有经过那么多的测试 – 我只是为自己尝试了它,它包含一个小错误,阻止从扩展加载所需的META-INF /服务。 要修复它,你应该用partOfShadow替换对partOfShadow两个方法调用:

 [... line 443] Enumeration sec = super.getResources(name); while (sec.hasMoreElements()) { URL item = sec.nextElement(); if (!inOwnBase(item, name)) vector.add(item); // <<-- HERE } if (altName != null) { Enumeration tern = super.getResources(altName); while (tern.hasMoreElements()) { URL item = tern.nextElement(); if (!inOwnBase(item, altName)) vector.add(item); // <<-- AND HERE } } 

我用上面的修复测试了它,它似乎工作正常(尽管测试不多)。

在旁注:使用这​​种新的扩展机制,现在终于也可以将扩展注释处理程序和注释放在与“lombok”不同的命名空间中 - 很好!

我发现这个博客解释了创建自己的处理程序的正确方法。 具体来说,是说通过一个名为SPI的框架发现了处理程序。