编写自定义龙目岛注释处理程序

2022-09-01 12:15:13

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

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

我只能通过以下方式编译我的自定义处理程序

  • 打开龙目岛的内容.jar
  • 重命名 .SCL.龙目岛文件到.class
  • 将生成的目录添加到编译类路径

此外,为了能够使用我的自定义处理程序,我需要创建一个新的胖罐,其中包含龙目岛类和我的自定义处理程序。自定义 lombok 类装入器基本上可以防止在其他多个 jar 中添加自定义处理程序。

这是延长龙目岛的唯一途径吗?还是我错过了什么?

我正在使用以下构建脚本

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)
}

答案 1

与此同时,Reinier Zwitserloot创建了一个新的git-branch sclExpansionUpdate,其中包含ShadowClassLoader的更新版本:

ShadowClassLoader现在对尝试扩展龙目岛更友好。

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

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

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

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

我用上面的修复程序测试了它,它似乎工作正常(虽然没有经过太多测试)。

另外要注意的是:有了这个新的扩展机制,现在终于可以将扩展注释处理程序和注释放在与“lombok”不同的命名空间中 - 很好!


答案 2

使用这个问题和其他答案(由Balder)的输入,我们设法将一个自定义的龙目岛注释处理程序放在一起:Symbok。随意使用它作为编写自己的示例。

顺便说一句,与其编写自定义的龙目岛处理程序,您还可以实现javac插件 - 它可能更简单。


推荐