Двоичное / квалифицированное имя не так?Начинается с:$ - PullRequest
2 голосов
/ 11 апреля 2019

Я использую обработчик аннотаций, который я написал.Он работал нормально на JDK 8, и теперь у меня возникла проблема с JDK 12.

У меня есть TypeElement, и я хочу получить его двоичное имя для передачи на Class.forName.

Я использую javax.lang.model.util.Elements.getBinaryName(TypeElement), и он возвращает значение мусора <any?>$OuterClass.InnerClass вместо ожидаемого example3.OuterClass$InnerClass.

Я попытался заменить getBinaryName на TypeElement.getQualifiedName (хотя этоне совсем работа для внутреннего класса), но это дает мне тот же результат мусора.Я пытался найти эту проблему, но большинство поисковых систем убирают все специальные символы и дают мне бесполезные результаты.

TypeElement был получен путем перехвата MirroredTypeException примерно так:

try {
    exampleAnnotation.value();
    throw new IllegalStateException("Expected a MirroredTypeException.");
} catch (MirroredTypeException ex) {
    return (TypeElement) types.asElement(ex.getTypeMirror());
}

А вот определение ExampleAnnotation:

package example1;

@Target(PACKAGE)
@Retention(RUNTIME)
@Documented
public @interface ExampleAnnotation {
    Class<? extends Derived> value() default Derived.class;

    interface Derived<A extends Annotation> extends Base<A> {
        String foo();
    }
}

А вот пример аннотации, к которой процессор обращается в package-info.java:

@ExampleAnnotation(OuterClass.InnerClass.class)
package example2;
import example1.ExampleAnnotation;

У меня естьтакже пробовал полное имя example3.OuterClass.InnerClass.class, но это также приводит к появлению мусора: <any?>$example3.OuterClass.InnerClass.

Я сомневаюсь, что это имеет значение, но процессоры аннотаций все еще отмечены @SupportedSourceVersion(SourceVersion.RELEASE_8), и я запускаю это на Gradle 5.3.1.

Я проверил, что путь к процессору содержит файлы jar для пакетов example1 и example3, включая процессоры аннотаций.

Я не внес никаких изменений в учетную запись системы модулей, поэтому подумал, что, возможно,это как-то влияет на код.

Только что попытался создать проект Maven и в настоящее время не могу воспроизвести проблему, поэтому может быть проблема с моей конфигурацией Gradle,похоже на то, что предложил @Colin Alworth.

1 Ответ

0 голосов
/ 12 апреля 2019

Я недавно обновился до новой версии Gradle и начал использовать зависимости «annotationProcessor».

Похоже, что <any?>$ добавляется перед двоичными / квалифицированными именами классов (как это выглядит в источнике), если класс отсутствует в classpath (или если он не импортирован, или написан неправильно) , У меня была только баночка аннотации на processorpath.

Чтобы предупредить потребителей моего процессора аннотаций об этой ошибке, я смог обнаружить ее, сравнив TypeElement.asType().getKind() == TypeKind.ERROR сразу после обнаружения MirroredTypeException.

...