Saya perlu membaca kelas yang terdapat dalam paket Java. Kelas-kelas itu ada di classpath. Saya perlu melakukan tugas ini dari program Java secara langsung. Apakah Anda tahu cara sederhana untuk melakukannya?
List<Class> classes = readClassesFrom("my.package")
java
reflection
Jørgen R
sumber
sumber
Jawaban:
Jika Anda memiliki Spring di classpath Anda maka yang berikut ini akan melakukannya.
Temukan semua kelas dalam paket yang dianotasi dengan XmlRootElement:
sumber
Anda dapat menggunakan Proyek Refleksi yang dijelaskan di sini
Cukup lengkap dan mudah digunakan.
Deskripsi singkat dari situs web di atas:
Contoh:
sumber
Saya menggunakan yang ini, ini berfungsi dengan file atau arsip jar
sumber
Spring telah mengimplementasikan fungsi pencarian classpath yang sangat baik di file
PathMatchingResourcePatternResolver
. Jika Anda menggunakanclasspath*
awalan:, Anda dapat menemukan semua sumber daya, termasuk kelas dalam hierarki tertentu, dan bahkan memfilternya jika Anda mau. Kemudian Anda dapat menggunakan turunan dariAbstractTypeHierarchyTraversingFilter
,AnnotationTypeFilter
danAssignableTypeFilter
untuk memfilter sumber daya tersebut baik pada anotasi tingkat kelas atau pada antarmuka yang mereka implementasikan.sumber
Java 1.6.0_24:
Solusi ini telah diuji dalam lingkungan EJB .
sumber
Scannotation dan Reflections menggunakan pendekatan pemindaian jalur kelas:
Pendekatan lain adalah dengan menggunakan Java Pluggable Annotation Processing API untuk menulis pemroses anotasi yang akan mengumpulkan semua kelas beranotasi pada waktu kompilasi dan membangun file indeks untuk penggunaan runtime. Mekanisme ini diimplementasikan di perpustakaan ClassIndex :
sumber
Fungsionalitas itu secara mencurigakan masih hilang dari API refleksi Java sejauh yang saya tahu. Anda bisa mendapatkan objek paket hanya dengan melakukan ini:
Tetapi seperti yang mungkin Anda perhatikan, itu tidak akan membiarkan Anda membuat daftar kelas dalam paket itu. Untuk saat ini, Anda harus mengambil pendekatan yang lebih berorientasi pada sistem file.
Saya menemukan beberapa contoh implementasi di posting ini
Saya tidak 100% yakin metode ini akan berfungsi ketika kelas Anda dimakamkan dalam file JAR, tetapi saya harap salah satunya melakukannya untuk Anda.
Saya setuju dengan @skaffman ... jika Anda memiliki cara lain untuk melakukan hal ini, saya sarankan untuk melakukannya.
sumber
Mekanisme paling kuat untuk mencantumkan semua kelas dalam paket tertentu saat ini adalah ClassGraph , karena menangani larik mekanisme spesifikasi jalur kelas seluas mungkin , termasuk sistem modul JPMS yang baru. (Saya penulisnya.)
sumber
eXtcos terlihat menjanjikan. Bayangkan Anda ingin menemukan semua kelas yang:
Dengan eXtcos, ini sesederhana
sumber
Bill Burke telah menulis ( artikel bagus tentang pemindaian kelas] dan kemudian dia menulis Scannotation .
Hibernate telah menulis ini:
CDI mungkin menyelesaikan ini, tetapi tidak tahu - belum menyelidiki sepenuhnya
.
Juga untuk anotasi:
sumber
Saya kebetulan telah mengimplementasikannya, dan itu berhasil dalam banyak kasus. Karena panjang, saya simpan di file di sini .
Idenya adalah untuk menemukan lokasi file sumber kelas yang tersedia dalam banyak kasus (pengecualian yang diketahui adalah file kelas JVM - sejauh yang saya uji). Jika kode ada dalam direktori, pindai semua file dan hanya tempatkan file kelas. Jika kode ada dalam file JAR, pindai semua entri.
Metode ini hanya dapat digunakan jika:
Anda memiliki kelas yang ada dalam paket yang sama dengan yang ingin Anda temukan, Kelas ini disebut SeedClass. Misalnya, jika Anda ingin membuat daftar semua kelas di 'java.io', kelas benih mungkin
java.io.File
.Kelas Anda berada dalam direktori atau dalam file JAR yang memiliki informasi file sumber (bukan file kode sumber, tetapi hanya file sumber). Sejauh yang saya coba, ini berfungsi hampir 100% kecuali kelas JVM (kelas-kelas itu datang dengan JVM).
Program Anda harus memiliki izin untuk mengakses ProtectionDomain dari kelas tersebut. Jika program Anda dimuat secara lokal, seharusnya tidak ada masalah.
Saya telah menguji program hanya untuk penggunaan biasa, jadi mungkin masih ada masalah.
Saya harap ini membantu.
sumber
Berikut adalah opsi lain, sedikit modifikasi pada jawaban lain di atas / di bawah:
sumber
Kembali ketika applet adalah tempat umum, seseorang mungkin memiliki URL di classpath. Ketika classloader membutuhkan sebuah kelas, classloader akan mencari semua lokasi di classpath, termasuk resource http. Karena Anda dapat memiliki hal-hal seperti URL dan direktori di classpath, tidak ada cara mudah untuk mendapatkan daftar kelas yang pasti.
Namun, Anda bisa sangat dekat. Beberapa perpustakaan Spring melakukan ini sekarang. Anda bisa mendapatkan semua jar di classpath, dan membukanya seperti file. Anda kemudian dapat mengambil daftar file ini, dan membuat struktur data yang berisi kelas Anda.
sumber
gunakan pakar ketergantungan:
lalu gunakan kode ini:
sumber
Brent - alasan pengaitan adalah salah satu cara yang berkaitan dengan fakta bahwa setiap kelas pada komponen apa pun dari CLASSPATH Anda dapat mendeklarasikan dirinya sendiri dalam paket apa pun (kecuali untuk java / javax). Jadi tidak ada pemetaan SEMUA kelas dalam "paket" tertentu karena tidak ada yang tahu atau bisa tahu. Anda dapat memperbarui file jar besok dan menghapus atau menambahkan kelas. Ini seperti mencoba mendapatkan daftar semua orang yang bernama John / Jon / Johan di semua negara di dunia - tidak ada dari kita yang maha tahu sehingga tidak ada dari kita yang akan memiliki jawaban yang benar.
sumber