There are many ways to find all methods with a specific annotation if you know the package you're searching in (for example by using the Reflections library). But if I'm writing a library, then I don't know the name of the package that's using my library. How would I go about finding all methods with a specific annotation in a case like this?
-
1Reflections doesn't know "the package", it's _told_ which package/class to search. Your library would have to have some entry point where users provide what they want to scan. – Sotirios Delimanolis Oct 31 '21 at 15:16
-
1@SotiriosDelimanolis the question is not implying that Reflection knew the package. It names Reflection only as an example to find the methods “*if you know the package you're searching in*”. – Holger Nov 01 '21 at 11:52
1 Answers
If you know the package name, you can use a classpath scanner like ClassGraph to find classes within that package, and then you can use reflection to list the methods for each class and find which ones have the correct annotation. Since you do not know the package name, you'll have to think creatively to find it.
I would personally try something like determining the current the call stack, getting the StackTraceElement
at the very bottom of the stack, using StackTraceElement#getClassName()
and Class#forName(String)
to get the implementing program's main class (or the class of the thread which is calling your library), getting that class's package (Class#getPackage()
), and then using Package#getName()
to get the package's name.
Altogether, it would look something like this:
public static String getImplementingPackageName() throws ClassNotFoundException {
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
StackTraceElement bottom = stackTraceElements[stackTraceElements.length - 1];
Class<?> caller = Class.forName(bottom.getClassName());
Package callerPackage = caller.getPackage();
String packageName = callerPackage.getName();
return packageName;
}

- 2,749
- 3
- 21
- 42
-
1Using a stack trace is a very unreliable mechanism. It’s better to use a `StackWalker` for such a task. Note that `Class.forName(…)` is operating in the context of this `getImplementingPackageName()` method which might not even see the class (e.g. because it has been defined by a different class loader and the dependency chain is the other way round, the caller has access to this method). `Class.forName(…) .getPackage()` is not even necessary when you’re just returning the package name, you could simply apply `substring(0, … lastIndexOf('.'))` to the class name. – Holger Nov 01 '21 at 12:02