I have encountered a somewhat strange behaviour. I use annotations to mark certain classes with a particular purpose, and then I use org.reflections library to find all the
You may perform the lookup without any third-party code as follows:
private static Set> getAnnotated(
Class> context, Class anno) throws IOException, URISyntaxException {
URI clURI = context.getResource(context.getSimpleName()+".class").toURI();
if(!clURI.getScheme().equals("file")) try {
FileSystems.getFileSystem(clURI);
} catch(FileSystemNotFoundException ex) {
FileSystems.newFileSystem(clURI, Collections.emptyMap());
}
String pkg=context.getPackage().getName();
return Files.list(Paths.get(clURI).getParent())
.map(p->p.getFileName().toString())
.filter(s->s.endsWith(".class"))
.map(s->s.substring(0, s.length()-6))
.map(s-> { try {
return context.getClassLoader().loadClass(pkg+'.'+s);
} catch(ClassNotFoundException ex) { return null; } })
.filter(c -> c!=null && c.isAnnotationPresent(anno))
.collect(Collectors.toSet());
}
The advantage of Path
over good old File
is that it abstracts over the filesystem (storage) and thus can be used to list package members even if the Class
is stored in a jar file (or any other kind of class storage for which a FileSystemProvider
exists).
You may use it as
Set> clazzes = getAnnotated(context, MyAnnotation.class);
where context
is a Class
within the package for which you want to get a annotated classes.