Подтвердить что ты не робот

Написание пользовательских обработчиков аннотаций Lombok

Я хочу написать собственные обработчики аннотации Lombok. Я знаю http://notatube.blogspot.de/2010/12/project-lombok-creating-custom.html. Но текущий файл jombok jar не содержит много файлов .class, но файлы с именем .SCL.lombok вместо этого.

Я обнаружил, что файлы .SCL.lombok являются .class файлами, сборка script Lombok действительно переименовывает их при создании файла jar, а ShadowClassLoader способен загружать эти классы - и, как представляется, аббревиатура SCL исходит из этого. Похоже, что причина этого заключается в том, чтобы просто "Избегать заражения пространства имен любого проекта с использованием баннера на основе SCL. Автозаполнение в IDE не будет предлагать ничего, кроме фактического публичного API".

Я мог только скомпилировать свой пользовательский обработчик

  • распаковка содержимого lombok.jar
  • переименование файлов .SCL.lombok в .class
  • добавление результирующего каталога в путь класса компиляции

Кроме того, чтобы иметь возможность использовать мой пользовательский обработчик, мне нужно было создать новую жировую банку, содержащую как классы ломбок, так и мой пользовательский обработчик. Пользовательский загрузчик классов 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)
}
4b9b3361

Ответ 1

Тем временем Reinier Zwitserloot создал новый git -branch sclExpansionUpdate, который содержит обновленную версию ShadowClassLoader:

ShadowClassLoader теперь более дружелюбен к попытке расширить ломбок.

Ваш (отдельный) jar/dir должен иметь файл с именем META-INF/ShadowClassLoader. Этот файл должен содержать строку "Ломбок". Если у вас это, будут загружены любые классы в этом jar/dir в том же пространстве, что и классы ломбока. Вы также можете переименовать класс файлы в .SCL.lombok, чтобы избежать поиска других загрузчиков.

Я предполагаю, что это еще не попало в основную ветку, потому что это, конечно же, не было проверено так - я просто попробовал это для себя, и он содержит небольшую ошибку, которая предотвращает загрузку необходимых META-INF/сервисов из расширений, Чтобы исправить это, вы должны заменить два вызова метода на partOfShadow на inOwnBase:

[... 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" - nice!

Ответ 2

Я нашел это blog, в котором объясняется, что является правильным способом создания собственного обработчика. В частности, говорится, что обработчики обнаружены через фреймворк под названием SPI.

Ответ 3

Используя данные этого и другого ответов (от Балдера), нам удалось собрать собственный обработчик аннотаций Lombok: Symbok. Не стесняйтесь использовать это в качестве образца для написания своего собственного.

Кстати, вместо того, чтобы писать собственный обработчик Lombok, вы могли бы вместо этого реализовать плагин javac - это может быть проще.