25

I know there are incredible set of tools for loading plugin classes in java, but today an idea came to my mind.

What if I have a bunch of annotated and un-annotated classes in package "org.home.junk" (annotated with annotation "@AnnotatedClass") and those classes have annotated methods with say annotation "@AnnotatedMethod".

First question: can I at run-time get an array/collection of all the classes in that specific package, so that I could check which one's are annotated and create an instance of them. (I am aware however how to check if Some.class has annotations courtesy of this guide: http://isagoksu.com/2009/development/java/creating-custom-annotations-and-making-use-of-them/)

Second question: - If I can do what I'd like in first question - what would be the most political way to do this?

I believe it is possible, as I understand JUnit loads test-case classes in some similar manner.

Also it would be cool if this could be done with minimal third party libraries and such, again - if it's possible :)

ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
Xeperis
  • 1,449
  • 2
  • 25
  • 41

4 Answers4

31

First answer: Take a look at this project.

Reflections reflections = new Reflections("org.home.junk");
Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(javax.persistence.Entity.class);

It returns all the classes from org.home.junk annotated with javax.persistence.Entity annotation.

Second Answer: To create new instance of above classes you can do this

for (Class<?> clazz : annotated) {
    final Object newInstance = clazz.newInstance();
}

Hope this answers everything.

Kowser
  • 8,123
  • 7
  • 40
  • 63
2

If you have Spring(3rd party, sorry :-)), use the org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider

A code usage example can be found in this SO question

Community
  • 1
  • 1
Vitaliy
  • 8,044
  • 7
  • 38
  • 66
2

It can be done with techniques that check the filesystem because it is more a classloader issue than a reflection one. Check this: Can you find all classes in a package using reflection?.

If you can check all the class files that exists in a directory, you can easily get the corresponding class using this method

Class<?> klass = Class.forName(className)

To know if a class is annotated or not is a reflection issue. Getting the annotations used in a class is done this way:

Annotation[] annotations = klass.getAnnotations();

Be sure to define your custom annotation with a retention policy type visible at run time.

@Retention(RetentionPolicy.RUNTIME) 

This article is a good resource for more info on that: http://tutorials.jenkov.com/java-reflection/annotations.html.

Community
  • 1
  • 1
gersonZaragocin
  • 1,122
  • 12
  • 20
1

It all depends on what kind of requirement you have for annotation.

Like e.g. @EJB : This annotation is designed so that container will identify and do EJB Specific work which requires scanning through files and then finding such classes.

However if your requirement is only to enable specific functionality based on annotation then you can do it using java reflection only

e.g. @NotNull : This annotation is designed in JSR 303 to verify that Annotated element is not null. This functionality can be easily implemented at run time using reflection API

Amit Deshpande
  • 19,001
  • 4
  • 46
  • 72