Ich muss Klassen lesen, die in einem Java-Paket enthalten sind. Diese Klassen befinden sich im Klassenpfad. Ich muss diese Aufgabe direkt von einem Java-Programm aus erledigen. Kennen Sie einen einfachen Weg?
List<Class> classes = readClassesFrom("my.package")
java
reflection
Jørgen R.
quelle
quelle
Antworten:
Wenn Sie Spring in Ihrem Klassenpfad haben, wird dies von den folgenden ausgeführt.
Suchen Sie alle Klassen in einem Paket, die mit XmlRootElement versehen sind:
quelle
Sie können das hier beschriebene Reflections-Projekt verwenden
Es ist ziemlich vollständig und einfach zu bedienen.
Kurzbeschreibung von der obigen Website:
Beispiel:
quelle
Ich benutze dieses, es funktioniert mit Dateien oder JAR-Archiven
quelle
Spring hat eine hervorragende Suchfunktion für Klassenpfade in der implementiert
PathMatchingResourcePatternResolver
. Wenn Sie dasclasspath*
Präfix: verwenden, können Sie alle Ressourcen, einschließlich Klassen in einer bestimmten Hierarchie, finden und bei Bedarf sogar filtern. Dann können Sie die Kinder verwendenAbstractTypeHierarchyTraversingFilter
,AnnotationTypeFilter
undAssignableTypeFilter
diese Ressourcen entweder auf Klassenebene Anmerkungen oder auf Schnittstellen implementieren sie zu filtern.quelle
Java 1.6.0_24:
Diese Lösung wurde in der EJB- Umgebung getestet .
quelle
Scannotation und Reflections verwenden den Scanansatz für Klassenpfade:
Ein anderer Ansatz besteht darin, die Java Pluggable Annotation Processing API zu verwenden, um einen Annotationsprozessor zu schreiben, der alle kommentierten Klassen zur Kompilierungszeit sammelt und die Indexdatei für die Laufzeit erstellt. Dieser Mechanismus ist in der ClassIndex- Bibliothek implementiert :
quelle
Soweit ich weiß, fehlt diese Funktionalität in der Java Reflection API immer noch verdächtig. Sie können ein Paketobjekt erhalten, indem Sie einfach Folgendes tun:
Aber wie Sie wahrscheinlich bemerkt haben, können Sie damit die Klassen in diesem Paket nicht auflisten. Ab sofort müssen Sie einen Dateisystem-orientierten Ansatz wählen.
Ich habe in diesem Beitrag einige Beispielimplementierungen gefunden
Ich bin nicht 100% sicher, ob diese Methoden funktionieren, wenn Ihre Klassen in JAR-Dateien vergraben sind, aber ich hoffe, dass eine davon dies für Sie erledigt.
Ich stimme @skaffman zu ... wenn Sie eine andere Vorgehensweise haben, würde ich empfehlen, dies stattdessen zu tun.
quelle
Der robusteste Mechanismus zum Auflisten aller Klassen in einem bestimmten Paket ist derzeit ClassGraph , da er die größtmögliche Anzahl von Klassenpfadspezifikationsmechanismen verarbeitet , einschließlich des neuen JPMS-Modulsystems. (Ich bin der Autor.)
quelle
eXtcos sieht vielversprechend aus. Stellen Sie sich vor, Sie möchten alle Klassen finden, die:
Mit eXtcos ist dies so einfach wie
quelle
Bill Burke hat einen (schönen Artikel über das Scannen von Klassen) geschrieben und dann Scannotation geschrieben .
Hibernate hat dies bereits geschrieben:
CDI könnte dies lösen, weiß es aber nicht - habe es noch nicht vollständig untersucht
.
Auch für Anmerkungen:
quelle
Ich habe es zufällig implementiert und es funktioniert in den meisten Fällen. Da es lang ist, habe ich es hier in eine Datei eingefügt .
Die Idee ist, den Speicherort der Klassenquelldatei zu finden, der in den meisten Fällen verfügbar ist (eine bekannte Ausnahme sind JVM-Klassendateien - soweit ich getestet habe). Wenn sich der Code in einem Verzeichnis befindet, durchsuchen Sie alle Dateien und nur Spotklassendateien. Wenn sich der Code in einer JAR-Datei befindet, scannen Sie alle Einträge.
Diese Methode kann nur angewendet werden, wenn:
Sie haben eine Klasse, die sich in demselben Paket befindet, das Sie entdecken möchten. Diese Klasse wird als SeedClass bezeichnet. Wenn Sie beispielsweise alle Klassen in 'java.io' auflisten möchten, kann dies die Startklasse sein
java.io.File
.Ihre Klassen befinden sich in einem Verzeichnis oder in einer JAR-Datei, die Informationen zur Quelldatei enthält (keine Quellcodedatei, sondern nur eine Quelldatei). Soweit ich es versucht habe, funktioniert es fast zu 100% mit Ausnahme der JVM-Klasse (diese Klassen werden mit der JVM geliefert).
Ihr Programm muss über die Berechtigung zum Zugriff auf ProtectionDomain dieser Klassen verfügen. Wenn Ihr Programm lokal geladen ist, sollte es kein Problem geben.
Ich habe das Programm nur für meinen regulären Gebrauch getestet, daher kann es immer noch Probleme geben.
Ich hoffe das hilft.
quelle
Hier ist eine weitere Option, eine geringfügige Änderung an einer anderen Antwort oben / unten:
quelle
Damals, als Applets an der Tagesordnung waren, hatte man möglicherweise eine URL im Klassenpfad. Wenn der Klassenladeprogramm eine Klasse benötigt, durchsucht er alle Speicherorte im Klassenpfad, einschließlich der http-Ressourcen. Da der Klassenpfad URLs und Verzeichnisse enthalten kann, gibt es keine einfache Möglichkeit, eine endgültige Liste der Klassen zu erhalten.
Sie können jedoch ziemlich nahe kommen. Einige der Spring-Bibliotheken tun dies jetzt. Sie können alle Jars in den Klassenpfad aufnehmen und sie wie Dateien öffnen. Sie können dann diese Liste von Dateien nehmen und eine Datenstruktur erstellen, die Ihre Klassen enthält.
quelle
Verwenden Sie den Abhängigkeits-Maven:
Verwenden Sie dann diesen Code:
quelle
Brent - der Grund, warum die Zuordnung eine Möglichkeit ist, hat damit zu tun, dass sich jede Klasse in einer beliebigen Komponente Ihres CLASSPATH in einem beliebigen Paket deklarieren kann (außer in Java / Javax). Daher gibt es einfach keine Zuordnung ALLER Klassen in einem bestimmten "Paket", da niemand weiß oder wissen kann. Sie können morgen eine JAR-Datei aktualisieren und Klassen entfernen oder hinzufügen. Es ist, als würde man versuchen, eine Liste aller Menschen mit dem Namen John / Jon / Johan in allen Ländern der Welt zu bekommen - keiner von uns ist allwissend, daher wird keiner von uns jemals die richtige Antwort haben.
quelle