Parikshit
Parikshit

Reputation: 325

How to access package level annotations in package-info.java runtime from a jar?

How can i access all package-info classes in a jar in my class path ? I want to access the package level annotations used in these classes.

I want to do the following steps:-

  1. Find all the package-info.java classes
  2. Get their packages
  3. Get the annotation @PackageOwner

Upvotes: 7

Views: 6778

Answers (4)

blurredd
blurredd

Reputation: 185

If you need to dynamically load a Package, and you can't directly reference an existing class to get the Package, then you can use the following to load the package-info class and retrieve the annotation:

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

This removes the need to use an external dependency, and you don't have to be aware of any classes in the target package.

Upvotes: 1

altaroinj
altaroinj

Reputation: 71

There's a more simple solution, not involving an external api. You can get the Package object from a class located in the package for which you want the annotations. And then get these annotations by calling the method getAnnotations() on the package :

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

Thanks to this link that helped me on this question. I had first read this thread and Parikshit's answer but I didn't want to use an external api.

Upvotes: 7

Parikshit
Parikshit

Reputation: 325

guava 14+ came to the rescue :)

following code works

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

application of the annotation is below for the package-info.java

@PackageOwner(owner = "shaikhm")
package com.somepackage;

Upvotes: 5

Eduardo Briguenti Vieira
Eduardo Briguenti Vieira

Reputation: 4589

Maybe you could try the reflections library.

https://github.com/ronmamo/reflections

A typical use of Reflections would be:

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

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

Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(SomeAnnotation.class);

Upvotes: 1

Related Questions