Как получить доступ к аннотациям уровня пакета во время выполнения package-info.java из банки?

Как я могу получить доступ ко всем классам с информацией о пакетах в банке в моем пути к классам? Я хочу получить доступ к аннотациям уровня пакета, используемым в этих классах.

Я хочу сделать следующие шаги: -

  1. Найдите все классы package-info.java
  2. Получить их пакеты
  3. Получите аннотацию @PackageOwner

person Parikshit    schedule 18.11.2015    source источник
comment
Пакет javadoc может быть полезен   -  person planetmaker    schedule 18.11.2015


Ответы (4)


Есть более простое решение, без внешнего API. Вы можете получить объект Package из класса, расположенного в пакете, для которого вы хотите получить аннотации. А затем получите эти аннотации, вызвав метод getAnnotations() для пакета:

import java.lang.annotation.Annotation;

public class PackageAnnotationsTest {

    public static void main(String[] args) {
        Package myPackage = AClassInMyPackage.class.getPackage();
        Annotation[] myPackageAnnotations = myPackage.getAnnotations();
        System.out.println("Available annotations for package : " + myPackage.getName());
        for(Annotation a : myPackageAnnotations) {
            System.out.println("\t * " + a.annotationType());
        }
    }
}

Благодаря этой ссылке, которая помогла мне в этом вопросе. Я впервые прочитал эту тему и ответ Парикшита, но я не хотел использовать внешний API.

person altaroinj    schedule 04.12.2015
comment
Со мной проблема заключалась в том, что в базовом пакете было много классов информации о пакете. Также я не мог использовать package-info.class.getPackage(), потому что компилятор выдает ошибку. - person Parikshit; 08.12.2015
comment
Я действительно не понимаю. Для каждого пакета может быть только один файл package-info.java. И способ получить доступ к аннотациям, расположенным в этом файле, состоит в том, чтобы вызвать getPackage().getAnnotations() для реального класса пакета, а не самого класса пакета (кстати, это не настоящий класс). - person altaroinj; 11.12.2015
comment
Допустим, у меня есть пакет com.mercedes.car, который я считаю своим базовым пакетом. У меня может быть только один package-info.java для этого пакета. Но у меня может быть отдельный пакет в com.mercedes.car.engine. Также я не знаю, какие классы существуют в пакете. Так что нет вопроса AClassInMyPackage.class.getPackage(); - person Parikshit; 22.12.2015
comment
Я предположил, что ваша проблема заключалась в том, чтобы получить информацию из файла package-info.class, а не в том, чтобы найти все ваши пакеты и прочитать связанные с ними аннотации. - person altaroinj; 23.12.2015

на помощь пришла гуава 14+ :)

следующий код работает

public class OwnerFinder {
    public static void main(String[] args) {
        try {
            ClassPath classPath = ClassPath.from(OwnerFinder.class.getClassLoader());
            classPath.getTopLevelClassesRecursive("com.somepackage")
                    .stream()
                    .filter(c -> c.getSimpleName().equals("package-info"))
                    .map(c -> c.load().getPackage().getAnnotation(PackageOwner.class))
                    .forEach(a -> System.out.println(a.owner()));

        } catch(IOException e) {
            e.printStackTrace();
        }
    }
}

применение аннотации ниже для package-info.java

@PackageOwner(owner = "shaikhm")
package com.somepackage;
person Parikshit    schedule 20.11.2015
comment
Приложение: ваша аннотация должна быть снабжена аннотацией @Retention(RetentionPolicy.RUNTIME), чтобы этот механизм мог ее подобрать. - person Luke; 09.11.2018

Возможно, вы могли бы попробовать библиотеку reflections.

https://github.com/ronmamo/reflections

Типичное использование Reflections:

Reflections reflections = new Reflections("my.project");

Set<Class<? extends SomeType>> subTypes = reflections.getSubTypesOf(SomeType.class);

Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(SomeAnnotation.class);
person edubriguenti    schedule 18.11.2015
comment
Я понял, что найти классы package-info не получится. Я не могу использовать отражения.getSubTypesOf(package-info.class). Выдает ошибку компиляции. Может быть потому, что package-info не имеет структуры классов. Хотелось бы API для доступа к аннотированным пакетам. Я пробовал Package.getPackages(), но он возвращает только пакеты загруженных классов. - person Parikshit; 19.11.2015

Если вам нужно динамически загрузить Package, и вы не можете напрямую ссылаться на существующий класс, чтобы получить Package, вы можете использовать следующее для загрузки класса информации о пакете и получения аннотации:

Package pkg = Class.forName(packageName + ".package-info").getPackage();
PackageOwner packageOwner = pkg.getAnnotation(PackageOwner.class);

Это устраняет необходимость использования внешней зависимости, и вам не нужно знать о каких-либо классах в целевом пакете.

person blurredd    schedule 31.05.2018
comment
Следует отметить, что вам не обязательно использовать getPackage, вы также можете получить аннотации из объекта package-info Class, что Package#getAnnotation и делает внутри. - person Clashsoft; 12.12.2019