Sie finden alle Klassen in einem Paket mit der spiegelung?
Ist es möglich, alle Klassen und Schnittstellen in einem Paket? (Schnell anschauen, z.B. - Paket
, es würde scheinen, Nein.)
Zur info die Lösung Amit links zu arbeiten, obwohl es ein Fehler, wenn die Klasse Pfad ein Leerzeichen drin (und wahrscheinlich für andere nicht-alphanumerische Zeichen). wenn Sie es in jede Art von Produktion code, siehe mein Kommentar zu seiner Antwort für einen workaround.
Beachten Sie auch diesem post.
Siehe zugehörigen Antwort: stackoverflow.com/a/30149061/4102160
Beachten Sie auch diesem post.
Beachten Sie auch diesem post.
Siehe zugehörigen Antwort: stackoverflow.com/a/30149061/4102160
Beachten Sie auch diesem post.
InformationsquelleAutor Jonik | 2009-02-06
Du musst angemeldet sein, um einen Kommentar abzugeben.
Aufgrund der dynamischen Natur des class loaders ist dies nicht möglich. Class loader sind nicht erforderlich, zu sagen, die VM, welche Klassen es geben kann, stattdessen werden Sie nur übergeben, fordert für Klassen, und haben, um zurückzukehren, eine Klasse oder eine exception zu werfen.
Jedoch, wenn Sie schreiben Ihre eigenen class loader, oder überprüfen Sie die klassenpfade und die Gläser, ist es möglich, diese Informationen zu finden. Dies wird über die Dateisystem-Operationen, obwohl, und nicht Reflexion. Es könnte sogar Bibliotheken, die helfen können Sie dies tun.
Wenn es gibt Klassen, die generiert oder geliefert aus der Ferne, werden Sie nicht in der Lage sein, zu entdecken diese Klassen.
Die normale Methode ist, anstatt irgendwo zu registrieren, die Klassen, die Sie benötigen Zugriff auf eine Datei oder einen Verweis in eine andere Klasse. Oder benutzen Sie einfach das übereinkommen, wenn es um die Namensgebung.
Nachtrag: Die Reflections-Bibliothek erlauben Ihnen, Klassen in der aktuellen Klassenpfad befinden. Es kann verwendet werden, um alle Klassen in einem Paket:
Beachten Sie, dass diese Lösung funktioniert nicht wie standardmäßig getSubTypesOf nicht zurück Subtypen von Object. Siehe Aleksander Blomskøld die Lösung für das konfigurieren der SubTypeScanner.
Reflexionen erfordert Guave. Guave ist groß. Version 14.0.1 von 2,1 MB.
Funktionierte nicht für mich. Mac OSX - Reflexionen Abhängigkeit der version 0.9.9-RC1 (maven) - JDK 1.7. Überdenken Sie die akzeptierte Antwort. @AleksanderBlomskøld Antwort ist die eins-zu-gehen.!!!!!
Wenn die Rückgabe eine leere Liste initialisieren der Reflexionen Objekt wie folgt: Reflexionen Reflexionen = new Reflections("Ihre.Paket.hier", neue SubTypesScanner(false));
InformationsquelleAutor Staale
Sollten Sie vielleicht einen Blick auf die open-source -Reflexionen Bibliothek. Mit ihm können Sie leicht erreichen, was Sie wollen.
Erste, den setup der Reflexionen index (es ist ein bisschen chaotisch, da die Suche für alle Klassen, die standardmäßig deaktiviert ist):
Dann können Sie die Abfrage für alle Gegenstände in einem Paket:
Ich lief in Probleme auf meinem Mac mit diesem code (in Bezug auf native Bibliotheken), aber mit
.addUrls(ClasspathHelper.forJavaClassPath())
statt der oben gelöst für mich. Weniger code, wie gut!wenn jemand ein Wunder der einfachste Weg, um das Standard-Paket ist, dass der prefix ein leerer String sein -> "".
"Reflexionen" - Bibliothek hat eine schwierige Lizenz: github.com/ronmamo/reflections/blob/master/COPYING.txt . Der trick ist, dass die Lizenz erlaubt die freie Benutzung nur die Lizenz selbst. Also wirklich, die Bibliothek verwenden (nicht die Lizenz) muss jeder Kontakt mit dem Autor aushandeln und die Nutzungsbedingungen.
Serge, ich glaube, Sie missverstehen WTFPL: wtfpl.net ich denke, WTFPL bedeutet, dass Sie frei sind zu tun, was Sie wollen, nicht nur mit der Lizenz, aber mit dem code aswell
InformationsquelleAutor Aleksander Blomskøld
Google Guava 14 umfasst eine neue Klasse
- ClassPath
mit drei Methoden, um den scan für die top-level-Klassen:getTopLevelClasses()
getTopLevelClasses(String packageName)
getTopLevelClassesRecursive(String packageName)
Sehen die
- ClassPath
javadocs für mehr info.Es scheint, ClassPath funktioniert nicht auf Android.
Wie ich bereits in unten einen Kommentar,
ClassPath
Tags@Beta
, so könnte nicht eine gute Idee für einige...Zu sagen, dass diese arbeiten, in denen Reflexion nicht tun, ist ein bisschen seltsam, die Lösung ist zweifellos umgesetzt mit der spiegelung (und der class-loader) - Funktionalität.
Ich glaube er meinte die Reflections-Bibliothek erwähnt, die in der anderen Antwort.
InformationsquelleAutor Christoph Leiter
Könnten Sie diese Methode1 verwendet, die
ClassLoader
.__________
1 Diese Methode wurde schon ursprünglich von http://snippets.dzone.com/posts/show/4831, das war archiviert durch das Internet-Archiv, als mit nun. Das snippet ist auch in https://dzone.com/articles/get-all-classes-within-package.
%20
, aber dienew File()
Konstruktor behandelt, die als Literale Prozentzeichen zwei null. Ich habe es behoben durch ändern derdirs.add(...)
Linie:dirs.add(new File(resource.toURI()));
Dies auch bedeutete, dass ich musste hinzufügenURISyntaxException
um die throws-KlauselgetClasses
Dies auch nicht funktioniert, wenn die Klassen innerhalb eines Jar.
Die Sie gerade kopiert aus dzone.com/articles/get-all-classes-within-package! bitte Quelle das nächste mal
+1, weil diese Lösung erfordert KEINE externe Bibliotheken... NIE, wirklich NIE paar Ihren code zufällig mit Bibliotheken zu erreichen, eine kleine Sache wie diese. wissen Sie, dass Sie hinzufügen, potenzielle Angriffsfläche für Angreifer? Nov 2015 einen Apache-Commons-problem entdeckt, dass führt zu Remote Command Execution nur durch von Apache Commons in den classpath eines app-Bereitstellung auf Jboss/Weblogic - [foxglovesecurity.com/2015/11/06/...
richtig bemerkt, dass dieser code unterstützt keine jar. Um das zu unterstützen, Gläser & Verzeichnisse. Der code wurde geändert, wie unten angegeben:
InformationsquelleAutor
Frühjahr
Diesem Beispiel ist für das Frühjahr 4, aber Sie finden die classpath-scanner, die in früheren Versionen als gut.
Google Guava
Hinweis: In der version 14, die API ist immer noch gekennzeichnet als @Beta, also Vorsicht in der Produktion code.
Leider, die
ClassPath
Klasse in Guave ist auch gekennzeichnet mit@Beta
: "APIs sind gekennzeichnet mit dem @Beta-annotation auf Klassen-oder methodenebene sind FREIBLEIBEND. Sie können in keiner Weise verändert, oder sogar entfernt, in jedem major-release. Wenn Ihr code ist eine Bibliothek, die sich (D. H. es wird über den CLASSPATH der Benutzer außerhalb Ihrer eigenen Kontrolle), sollten Sie nicht verwenden die beta-APIs, es sei denn, Sie Verpacken diese..." code.google.com/p/guava-libraries/#Important_WarningsGuter Punkt, habe ich nicht bemerkt! Danke. Ich will hinzufügen, eine andere Antwort mit Spring classpath-scanner, der nicht beta ist sicher.
Zu finden geschachtelte statische Klassen mit Guave-Lösung
getAllClasses()
Methode verwendet werden kann.Die Spring-Lösung ist, die nur arbeiten, wenn Sie aus einem ausführbaren jar.
InformationsquelleAutor voho
Hallo. Ich habe immer einige Probleme hatte mit den oben genannten Lösungen (und auf anderen Seiten).
Ich, als Entwickler, Programmierung bin ein addon für eine API. Die API verhindert die Verwendung einer externen Bibliotheken oder 3rd-party-tools. Das setup besteht auch aus einer Mischung von code in jar-oder zip-Dateien und class-Dateien direkt in einige Verzeichnisse. Also mein code musste in der Lage sein zu arbeiten, um jedem setup. Nach viel Forschung, die ich habe kommen mit einer Methode, die die Arbeit in mindestens 95% aller möglichen setups.
Folgende code ist im Grunde der overkill-Methode, die immer funktioniert.
Code:
Dieser code durchsucht ein bestimmtes package für alle Klassen, die in Ihr enthalten sind. Es wird nur funktionieren für alle Klassen in der aktuellen
ClassLoader
.Diese drei Methoden bieten Ihnen die Möglichkeit zu finden, alle Klassen in einem Paket.
Verwenden Sie es wie folgt:
Die Erklärung:
Die Methode ruft zuerst die aktuelle
ClassLoader
. Anschließend ruft alle Ressourcen, die enthalten Sprach-Paket und iteriert dieseURL
s. Es erstellt dann eineURLConnection
und bestimmt, welche Art von URl, die wir haben. Es kann entweder ein Verzeichnis (FileURLConnection
) oder ein Verzeichnis innerhalb einer jar-oder zip-Datei (JarURLConnection
). Je nachdem, welche Art der Verbindung, die wir haben zwei verschiedene Methoden aufgerufen werden.Ersten mal sehen, was passiert, wenn es eine
FileURLConnection
.Es wird zunächst geprüft, ob die übergebene Datei existiert und ist ein Verzeichnis. Wenn das der Fall ist, prüft es, ob es eine class-Datei. Wenn das so ein
Class
- Objekt wird erstellt und in denArrayList
. Wenn es nicht eine Klasse-Datei, sondern ein Verzeichnis ist, können wir einfach Durchlaufen in Sie und das gleiche tun. Alle anderen Fälle/Dateien werden ignoriert.Wenn die
URLConnection
ist einJarURLConnection
die andere private Helfer-Methode aufgerufen werden. Diese Methode iteriert über alle Einträge in der zip - /jar-Archiv. Wenn ein Eintrag einer Klasse-Datei, und ist in dem Paket eineClass
- Objekt erstellt und gespeichert in derArrayList
.Nachdem alle Ressourcen wurden analysiert (die main-Methode) zurück, die
ArrayList
containig alle Klassen in das Paket gegeben, dass die aktuelleClassLoader
kennt.Bricht der Prozess an jedem Punkt eine
ClassNotFoundException
geworfen werden, die detaillierte Informationen über die genaue Ursache.sun.net.www.protocol.file.FileURLConnection
, das erzeugt eine Warnung beim kompilieren-Zeit ("Warnung: die Sonne.net.www.Protokoll.Datei.FileURLConnection Sun proprietary API and may be removed in a future release"). Gibt es eine alternative zu dieser Klasse, oder kann die Warnung unterdrückt werden mithilfe von Annotationen?Diese Methode funktioniert nicht für die bootstrap-Klassen wie in java.lang, java.util, ... Diese können gefunden werden, indem man System.getProperty("sun.boot.Klasse.Pfad"), splitting : oder ; (je nach OS) und dann läuft die leicht modifizierte Versionen der oben genannten checkDirectory und checkJarFile.
Sie können umgehen die Warnung/Fehler mit der Verbindung.getClass().getCanonicalName().equals( "sun.net.www.Protokoll.Datei.FileURLConnection" ). Wenn Sie wirklich wollen, Sie können erstellen Sie ein URLConnection, die Sie denken, SOLLTE die Verwendung von sun.net.www.Protokoll.Datei.FileURLConnection und auch zu vergleichen der name der connection-Klasse der name der Klasse, die Sie erstellt haben. Wenn Sie beide die gleichen Sie können es zu behandeln, als eine Instanz der Sonne.net.www.Protokoll.Datei.FileURLConnection anstatt versagt im Fall der name der Klasse ändert.
Sie können vermeiden, die FileURLConnection etwas wie das zu tun :
if ( ... instanceof JarURLConnecton) { ... } else { // Asume that the Connection is valid and points to a File }
Es ist, was ich habe auf meinem code zu suchen JPA-annotierten KlassenGetestet, es funktioniert für Ordner und jar
InformationsquelleAutor BrainStone
Ohne zusätzliche Bibliotheken:
upackage
istnull
... 🙁Für ein Paket "com.MeineFirma.Bohnen", Ersetze "test" mit "com/mycompany/Bohnen"
Ich bekomme eine null -, wenn mit diesem code. Scheint nur zu funktionieren, wenn Sie Ihr Glas ist eine ausführbare Datei
wenn Sie erhalten die Paket-Namen aus
String pack = getPackage().getName();
, dann müssen Siepack = pack.replaceAll("[.]", "/");
InformationsquelleAutor Williams López
In der Allgemeinen Klasse Lader nicht zulassen und Scannen, die durch alle Klassen im classpath. Aber in der Regel nur verwendet class-loader ist UrlClassLoader aus, die wir abrufen können, die Liste von Verzeichnissen und jar-Dateien (siehe getURLs) und öffnen Sie Sie eins nach dem anderen, um eine Liste der verfügbaren Klassen. Dieser Ansatz, genannt class-path Scannen, ist implementiert in Scannotation und Reflexionen.
Ein weiterer Ansatz ist die Verwendung Java Pluggable Annotation Processing API zu schreiben annotation-Prozessor sammelt alle annotierten Klassen zur compile-Zeit und erstellen Sie die index-Datei zur Laufzeit zu verwenden. Dieser Mechanismus wird umgesetzt in ClassIndex Bibliothek:
Beachten Sie, dass kein zusätzliches setup notwendig ist, da das Scannen ist voll automatisiert, Dank der Java-compiler automatisch entdecken Sie alle Prozessoren auf dem classpath.
welches tool Sie verwenden möchten?
Ich bin mit den Reflexionen lib. Aber ich habe es funktioniert nach der folgenden Problemumgehung erwähnt von @Aleksander Blomskøld für neuere Versionen von diesem lib.
Hallo, ich bin mit eclipse und kann es nicht arbeiten, ClassIndex.getPackageClasses("meine.Paket") return eine leere map
siehe: github.com/atteo/classindex#eclipse
InformationsquelleAutor Sławek
Schrieb ich FastClasspathScanner um dieses problem zu lösen. Es behandelt viele verschiedene Typen von classpath-scan-Aufgaben, hat eine einfache API, arbeitet mit vielen verschiedenen Classloadern-und classpath-Umgebungen, wurden sorgfältig parallelisiert und ist hoch optimiert für hohe Geschwindigkeit und niedrigen Speicherverbrauch. Es können sogar noch einen GraphViz-Visualisierung der Klasse graph, der zeigt, wie die Klassen miteinander verbunden sind.
Für deine ursprüngliche Frage zu finden, alle Klassen und Schnittstellen in einem Paket, die Sie tun können:
Gibt es viele mögliche Varianten, um diese-finden Sie in der Dokumentation (oben verlinkten) für die volle info.
InformationsquelleAutor Luke Hutchison
Hier ist, wie ich es mache. Ich scanne alle Unterordner (sub-packages) und ich versuche nicht, zu laden, anonyme Klassen:
InformationsquelleAutor Nadav B
Ich zusammen eine einfache github-Projekt, das dieses problem löst:
https://github.com/ddopson/java-class-enumerator
Sollte es funktionieren SOWOHL für Datei-basierte klassenpfade UND jar-Dateien.
Wenn Sie den Befehl 'make' nach dem Auschecken des Projekts wird es drucken Sie diese aus:
Siehe auch meine andere Antwort
InformationsquelleAutor Dave Dopson
Ja mit paar API ' s können Sie, hier ist, wie ich mag, es zu tun, konfrontiert mit diesem problem, die ich mit hibernate core & hatte, zu finden, welche Klassen wo kommentiert mit einer bestimmten annotation.
Machen diese eine benutzerdefinierte Anmerkung mit denen Sie Kennzeichnen, welche Klassen Sie abgeholt werden möchten.
Dann markieren Sie Ihre Klasse mit es wie
Machen diese utility-Klasse die folgende Methode
Rufen Sie die allFoundClassesAnnotatedWithEntitytobescanned() Methode, um einen Set von Klassen gefunden.
Sie benötigen libs, die unten gegeben
InformationsquelleAutor Sujal Mandal
Müssen Sie untersuchen jedes class-loader-Eintrag in der class-path:
Wenn Eintrag ein Verzeichnis ist, schauen Sie einfach in dem richtigen Unterverzeichnis:
Wenn der Eintrag, ist die Datei, und es ist Glas, überprüfen Sie die ZIP-Einträge von es:
Nun haben Sie alle Klassennamen innerhalb der Paket, Sie können versuchen, Sie zu laden, mit Reflexion und Analyse, wenn Sie Klassen oder interfaces, etc.
In diesem Beispiel wird nicht gehen durch sub-Pakete. Vielleicht ist das von Interesse für einige... @mr-Tee geben Sie Einfach das Paket, die Sie suchen. Ich habe dies in einem Projekt angegeben, die ein test-Paket innerhalb dieses Projektes zusammengestellt und verpackt es und nannte das Beispiel der JAR die main-Methode. Arbeitete wie ein Charme. 🙂
InformationsquelleAutor Danubian Sailor
Ich versucht habe zu verwenden, die Reflexionen, die Bibliothek, hatte aber einige Probleme, es zu benutzen, und es waren zu viele Gläser sollte ich auch nur einfach erhalten die Klassen in einem Paket.
Werde ich nach einer Lösung, die ich gefunden habe in dieser doppelten Frage: Wie alle Klassen-Namen in einem Paket?
Den Antwort wurde geschrieben von sp00m; ich habe Hinzugefügt, einige Korrekturen zu machen, damit es funktioniert:
Es nur verwenden, rufen Sie die Methode finden, wie sp00n erwähnt in diesem Beispiel:
Ich habe das erstellen von Instanzen der Klassen, wenn nötig.
InformationsquelleAutor Martín C
Schrieb ich einfach eine util-Klasse, die es beinhalten test-Methoden, können Sie einen check - ~
IteratePackageUtil.java:
InformationsquelleAutor Eric Wang
Fast alle Antworten, die entweder verwendet
Reflections
oder liest die class-Dateien aus dem Datei-system. Wenn Sie versuchen, Lesen die Klassen von Datei-system, erhalten Sie möglicherweise Fehler beim Verpacken der Anwendung als JAR-oder anderen. Auch können Sie nicht wollen, verwenden Sie eine separate Bibliothek für diesen Zweck.Hier ist ein anderer Ansatz, das ist reines java und nicht hängt davon ab, Datei-system.
Java 8 ist kein muss. Sie können for-Schleifen anstelle des streams.
Und Sie können testen, wie diese
ToolProvider.getSystemJavaCompiler()
dieser code nicht Scannen verschachtelte Pakete.Kann ich nicht machen, es funktioniert mit einem Paket von einem externen jar
InformationsquelleAutor bhdrkn
Aleksander Blomskøld Lösung nicht für mich arbeiten für parametrisierte tests
@RunWith(Parameterized.class)
bei der Verwendung von Maven. Die tests wurden richtig benannt, und auch wo Sie gefunden wurde, aber nicht ausgeführt:Einem ähnlichen Problem berichtet worden hier.
In meinem Fall
@Parameters
ist das erzeugen von Instanzen der jeweiligen Klasse in einem Paket. Die tests gut funktioniert, wenn lokal ausführen in der IDE. Jedoch beim ausführen von Maven keine Klassen, wo gefunden, mit Aleksander Blomskøld Lösung.Ich habe es mit dem folgenden geschnippelt, die wurde inspiriert durch David Pärsson Kommentar Aleksander Blomskøld Antwort:
InformationsquelleAutor Thorsten
Vorausgesetzt, Sie sind nicht mit jedem dynamischer class loader können Sie die Suche im classpath und für jeden Eintrag durchsuchen Sie das Verzeichnis oder die JAR-Datei.
InformationsquelleAutor Lawrence Dol
erwähnenswert
Wenn Sie möchten, um eine Liste aller Klassen unter bestimmten Paket, die Sie verwenden können
Reflection
folgende Weise:Dadurch wird eine Liste der Klassen, die Sie später verwenden können, wie Sie es wünschen.
InformationsquelleAutor Maroun
Es ist sehr gut möglich, aber ohne zusätzliche Bibliotheken, wie
Reflections
es ist schwer...Es ist schwer, weil du noch nicht das volle instrument bekommen, Klasse name.
Und, ich nehme den code von meinem
ClassFinder
Klasse:InformationsquelleAutor Muskovets
Basierend auf @Staale Antwort, und in einem Versuch, nicht zu verlassen sich auf Bibliotheken von Drittanbietern, würde ich implementieren der Datei-System-Ansatz durch die Untersuchung erste Paket physischen Standort mit:
InformationsquelleAutor
Wenn Sie nur suchen, um laden Sie eine Gruppe von verbundenen Klassen, dann die Feder kann Ihnen helfen.
Frühjahr instanziieren können eine Liste oder Karte aller Klassen, die die Implementierung eines bestimmten interface in einer Zeile code. Die Liste oder eine Karte enthalten, die Instanzen aller Klassen, implementieren diese Schnittstelle.
Dass gesagt wird, die als alternative zu dem laden der Liste der Klassen außerhalb der Datei-system, statt nur implementieren die gleiche Schnittstelle in allen Klassen, die Sie laden möchten, unabhängig von Paket und nutzen Spring, bieten Sie Instanzen aller von Ihnen. Auf diese Weise können Sie das laden (instanziieren) alle Klassen, die Sie wünschen, unabhängig davon, zu welchem Paket Sie sich befinden.
Auf der anderen Seite, wenn Sie alle in einem Paket ist, was Sie wollen, dann müssen einfach alle Klassen in diesem Paket implementieren eine bestimmte Schnittstelle.
InformationsquelleAutor Rodney P. Barbati
plain-java: FindAllClassesUsingPlainJavaReflectionTest.java
PS: zur Vereinfachung von Textbausteinen für die Behandlung von Fehlern, etc, ich bin mit der hier
vavr
undlombok
Bibliothekenandere Implementierungen gefunden werden kann, in mein GitHub daggerok/java-reflection-finden-annotierten Klassen oder-Methoden repo
InformationsquelleAutor Maksim Kostromin
Es ist nicht möglich, da alle Klassen im Paket kann nicht geladen werden, während Sie immer weiß, Paket einer Klasse.
InformationsquelleAutor Marko