Saya perlu membaca Manifest
file, yang mengirimkan kelas saya, tetapi ketika saya menggunakan:
getClass().getClassLoader().getResources(...)
Saya mendapatkan MANIFEST
dari yang pertama .jar
dimuat ke Java Runtime.
Aplikasi saya akan berjalan dari applet atau webstart,
jadi saya tidak akan memiliki akses ke .jar
file saya sendiri , saya kira.
Saya sebenarnya ingin membaca Export-package
atribut dari .jar
mana memulai Felix OSGi, jadi saya bisa mengekspos paket-paket itu ke Felix. Ada ide?
java
osgi
manifest.mf
apache-felix
Houtman
sumber
sumber
Jawaban:
Anda dapat melakukan satu dari dua hal:
Panggil
getResources()
dan ulangi melalui koleksi URL yang dikembalikan, bacalah sebagai manifes sampai Anda menemukan milik Anda:Anda dapat mencoba memeriksa apakah
getClass().getClassLoader()
merupakan instance darijava.net.URLClassLoader
. Mayoritas classloader Sun adalah, termasukAppletClassLoader
. Anda kemudian dapat melemparkannya dan meneleponfindResource()
yang telah dikenal - untuk applet, setidaknya - untuk mengembalikan manifes yang diperlukan secara langsung:sumber
Anda dapat menemukan URL untuk kelas Anda terlebih dahulu. Jika itu JAR, maka Anda memuat manifes dari sana. Sebagai contoh,
sumber
classPath.replace("org/example/MyClass.class", "META-INF/MANIFEST.MF"
getSimpleName
menghapus nama kelas luar. Ini akan bekerja untuk kelas batin:clazz.getName().replace (".", "/") + ".class"
.Anda dapat menggunakan
Manifests
dari manifes jcabi dan membaca atribut apa pun dari file MANIFEST.MF yang tersedia hanya dengan satu baris:Satu-satunya ketergantungan yang Anda butuhkan adalah:
Juga, lihat posting blog ini untuk detail lebih lanjut: http://www.yegor256.com/2014/07/03/how-to-read-manifest-mf.html
sumber
<logger name="com.jcabi.manifests" level="OFF"/>
Saya akui di muka bahwa jawaban ini tidak menjawab pertanyaan awal, yaitu bahwa pada umumnya dapat mengakses Manifest. Namun jika yang benar-benar diperlukan adalah membaca salah satu dari sejumlah atribut Manifes "standar", solusi berikut ini jauh lebih sederhana daripada yang diposting di atas. Jadi saya berharap moderator akan mengizinkannya. Perhatikan bahwa solusi ini ada di Kotlin, bukan Java, tetapi saya berharap bahwa port ke Java akan sepele. (Meskipun saya akui saya tidak tahu bahasa Jawa yang setara dengan ".`package`".
Dalam kasus saya, saya ingin membaca atribut "Implementasi-Versi" jadi saya mulai dengan solusi yang diberikan di atas untuk mendapatkan aliran dan kemudian membacanya untuk mendapatkan nilai. Sementara solusi ini berhasil, seorang rekan kerja yang meninjau kode saya menunjukkan kepada saya cara yang lebih mudah untuk melakukan apa yang saya inginkan. Perhatikan bahwa solusi ini ada di Kotlin, bukan Jawa.
Sekali lagi perhatikan bahwa ini tidak menjawab pertanyaan awal, khususnya "Paket ekspor" tampaknya tidak menjadi salah satu atribut yang didukung. Yang mengatakan, ada myPackage.name yang mengembalikan nilai. Mungkin seseorang yang memahami hal ini lebih dari yang dapat saya komentari apakah itu mengembalikan nilai yang diminta oleh pengirim aslinya.
sumber
String implementationVersion = MyApplication.class.getPackage().getImplementationVersion();
Saya percaya cara paling tepat untuk mendapatkan manifes untuk bundel apa pun (termasuk bundel yang memuat kelas tertentu) adalah dengan menggunakan objek Bundle atau BundleContext.
Perhatikan bahwa objek Bundle juga menyediakan
getEntry(String path)
untuk mencari sumber daya yang terkandung dalam bundel tertentu, daripada mencari seluruh classpath bundel itu.Secara umum, jika Anda menginginkan informasi bundel spesifik, jangan mengandalkan asumsi tentang classloader, cukup gunakan API OSGi secara langsung.
sumber
Kode berikut ini berfungsi dengan beberapa jenis arsip (jar, perang) dan beberapa jenis classloader (jar, url, vfs, ...)
sumber
clz.getResource(resource).toString()
memiliki garis miring terbalik?Cara termudah adalah dengan menggunakan kelas JarURLConnection:
Karena dalam beberapa kasus
...class.getProtectionDomain().getCodeSource().getLocation();
memberi jalanvfs:/
, jadi ini harus ditangani tambahan.sumber
Anda dapat menggunakan getProtectionDomain (). GetCodeSource () seperti ini:
sumber
getCodeSource
dapat kembalinull
. Apa kriterianya, bahwa ini akan berhasil? The dokumentasi tidak menjelaskan hal ini.DataUtilities
diimpor? Sepertinya tidak ada di JDK.Mengapa Anda termasuk langkah getClassLoader? Jika Anda mengatakan "this.getClass (). GetResource ()" Anda harus mendapatkan sumber daya relatif terhadap kelas panggilan. Saya tidak pernah menggunakan ClassLoader.getResource (), meskipun dari melihat cepat pada Java Docs sepertinya itu akan membuat Anda sumber daya pertama dari nama yang ditemukan di classpath saat ini.
sumber
class.getResource("myresource.txt")
akan mencoba memuat sumber daya itucom/mypackage/myresource.txt
. Bagaimana tepatnya Anda akan menggunakan pendekatan ini untuk mendapatkan manifes?sumber
cl.getResourceAsStream("META-INF/MANIFEST.MF")
.classLoader.getResource(..)
danurl.openStream()
benar-benar tidak relevan dan rawan kesalahan karena mencoba melakukan hal yang samaclassLoader.getResourceAsStream(..)
.ClassLoader classLoader = cl.getClassLoader(); return new Manifest(classLoader.getResourceAsStream("/META-INF/MANIFEST.MF"));
Saya telah menggunakan solusi dari Anthony Juckel tetapi dalam MANIFEST.MF kuncinya harus dimulai dengan huruf besar.
Jadi file MANIFEST.MF saya mengandung kunci seperti:
Mykey: value
Kemudian di aktivator atau kelas lain Anda dapat menggunakan kode dari Anthony untuk membaca file MANIFEST.MF dan nilai yang Anda butuhkan.
sumber
Saya punya solusi aneh ini yang menjalankan aplikasi perang di server Jetty tertanam tetapi aplikasi ini juga harus berjalan di server Tomcat standar, dan kami memiliki beberapa properti khusus di manfest.
Masalahnya adalah ketika di Tomcat, manifes dapat dibaca, tetapi ketika di dermaga, manifes acak diambil (yang melewatkan properti khusus)
Berdasarkan jawaban Alex Konshin, saya datang dengan solusi berikut (inputstream kemudian digunakan dalam kelas Manifest):
sumber