106 votes

Comment lire toutes les classes d'un paquetage Java dans le classpath ?

J'ai besoin de lire les classes contenues dans un paquetage Java. Ces classes sont dans le classpath. Je dois effectuer cette tâche directement à partir d'un programme Java. Connaissez-vous un moyen simple de le faire ?

List<Class> classes = readClassesFrom("my.package")

6voto

Sławek Points 539

Scannotation y Réflexions utiliser l'approche de balayage des chemins de classe :

Reflections reflections = new Reflections("my.package");
Set<Class<? extends Object>> classes = reflections.getSubTypesOf(Object.class);

Une autre approche consiste à utiliser API Java Pluggable de traitement des annotations pour écrire le processeur d'annotation qui collectera toutes les classes annotées au moment de la compilation et construira le fichier d'index pour l'utilisation au moment de l'exécution. Ce mécanisme est implémenté dans ClassIndex bibliothèque :

Iterable<Class> classes = ClassIndex.getPackageClasses("my.package");

2voto

Brent Nash Points 6337

Cette fonctionnalité est toujours suspicieusement absente de l'API de réflexion Java pour autant que je sache. Vous pouvez obtenir un objet de paquetage en faisant simplement ceci :

Package packageObj = Package.getPackage("my.package");

Mais comme vous l'avez probablement remarqué, cela ne vous permettra pas de lister les classes de ce paquet. Pour l'instant, vous devez adopter une approche plus orientée système de fichiers.

J'ai trouvé quelques exemples d'implémentation dans this poste

Je ne suis pas sûr à 100% que ces méthodes fonctionneront lorsque vos classes sont enfouies dans des fichiers JAR, mais j'espère que l'une d'entre elles vous conviendra.

Je suis d'accord avec @skaffman... si vous avez une autre façon de procéder, je vous recommande de le faire à la place.

2voto

Ondra Žižka Points 8262
  1. Bill Burke a écrit une (belle article sur le balayage des classes] et ensuite il a écrit Scannotation .

  2. Hibernate a déjà écrit cela :

    • org.hibernate.ejb.packaging.Scanner
    • org.hibernate.ejb.packaging.NativeScanner
  3. CDI pourrait résoudre ce problème, mais je ne sais pas - je n'ai pas encore fait de recherches approfondies.

.

@Inject Instance< MyClass> x;
...
x.iterator() 

Également pour les annotations :

abstract class MyAnnotationQualifier
extends AnnotationLiteral<Entity> implements Entity {}

2voto

noelob Points 59

eXtcos semble prometteur. Imaginez que vous voulez trouver toutes les classes qui :

  1. Étendre de la classe "Component", et les stocker
  2. sont annotés avec "MyComponent", et
  3. Sont dans le paquet "commun".

Avec eXtcos, il suffit de

ClasspathScanner scanner = new ClasspathScanner();
final Set<Class> classStore = new ArraySet<Class>();

Set<Class> classes = scanner.getClasses(new ClassQuery() {
    protected void query() {
        select().
        from(“common”).
        andStore(thoseExtending(Component.class).into(classStore)).
        returning(allAnnotatedWith(MyComponent.class));
    }
});

1voto

NawaMan Points 10266

Il se trouve que je l'ai mis en œuvre et qu'il fonctionne dans la plupart des cas. Comme elle est longue, je l'ai mise dans un fichier fichier ici .

L'idée est de trouver l'emplacement du fichier source de la classe qui est disponible dans la plupart des cas (une exception connue sont les fichiers de classe JVM -- pour autant que j'ai testé). Si le code est dans un répertoire, parcourez tous les fichiers et ne repérez que les fichiers de classe. Si le code est dans un fichier JAR, parcourez toutes les entrées.

Cette méthode ne peut être utilisée que lorsque :

  1. Vous avez une classe qui se trouve dans le même paquet que celui que vous voulez découvrir. Cette classe est appelée SeedClass. Par exemple, si vous voulez lister toutes les classes de 'java.io', la classe d'origine peut être java.io.File .

  2. Vos classes se trouvent dans un répertoire ou dans un fichier JAR qui contient des informations sur le fichier source (pas le fichier de code source, mais simplement le fichier source). D'après ce que j'ai essayé, cela fonctionne presque à 100%, sauf pour les classes JVM (ces classes sont fournies avec la JVM).

  3. Votre programme doit avoir la permission d'accéder au ProtectionDomain de ces classes. Si votre programme est chargé localement, il ne devrait pas y avoir de problème.

J'ai testé le programme uniquement pour mon utilisation régulière, il peut donc encore avoir des problèmes.

J'espère que cela vous aidera.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X