Mungkin ini akan membantu seseorang karena itu berhasil cukup baik untuk saya. Masalahnya dapat diselesaikan dengan mengintegrasikan dependensi Anda sendiri. Ikuti langkah-langkah sederhana ini
Cek dulu errornya yang seharusnya seperti ini :
- Eksekusi metode gagal:
- java.lang.LinkageError:pelanggaran batasan loader:
- ketika menyelesaikan metode "org.slf4j.impl.StaticLoggerBinder .getLoggerFactory()Lorg/slf4j/ILoggerFactory;"
- pemuat kelas (contoh org/openmrs/module/ModuleClassLoader) dari kelas saat ini, org/slf4j/LoggerFactory ,
- dan pemuat kelas (contoh org/apache/catalina/loader/WebappClassLoader) untuk kelas yang diselesaikan, org/slf4j/impl/StaticLoggerBinder ,
- memiliki objek Kelas yang berbeda untuk tipe taticLoggerBinder.getLoggerFactory()Lorg/slf4j/ILoggerFactory; digunakan dalam tanda tangan
-
Lihat dua kelas yang disorot. Pencarian Google untuk mereka seperti "StaticLoggerBinder.class jar download" &"LoggeraFactory.class jar download". Ini akan menunjukkan kepada Anda tautan pertama atau kedua (Situs adalah http://www.java2s.com ) yang merupakan salah satu versi jar yang telah Anda sertakan dalam proyek Anda. Anda dapat dengan cerdas mengidentifikasinya sendiri, tetapi kami kecanduan google;)
-
Setelah itu anda akan mengetahui nama file jarnya, dalam kasus saya ini seperti slf4j-log4j12-1.5.6.jar &slf4j-api-1.5.8
- Sekarang versi terbaru dari file ini tersedia di sini http://mvnrepository.com/ (sebenarnya semua versi hingga saat ini, ini adalah situs tempat maven mendapatkan dependensi Anda).
- Sekarang tambahkan kedua file sebagai dependensi dengan versi terbaru (atau pertahankan kedua versi file tetap sama, salah satu versi yang dipilih adalah yang lama). Berikut adalah dependensi yang harus Anda sertakan di pom.xml
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.7</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.7</version>
</dependency>
Bisakah Anda menentukan pemuat kelas? Jika tidak, coba tentukan pemuat kelas konteks seperti ini:
Thread thread = Thread.currentThread();
ClassLoader contextClassLoader = thread.getContextClassLoader();
try {
thread.setContextClassLoader(yourClassLoader);
callDom4j();
} finally {
thread.setContextClassLoader(contextClassLoader);
}
Saya tidak familiar dengan Java Plugin Framework, tapi saya menulis kode untuk Eclipse, dan saya mengalami masalah serupa dari waktu ke waktu. Saya tidak menjamin ini akan memperbaikinya, tetapi mungkin patut dicoba.
Kedengarannya seperti masalah hierarki classloader. Saya tidak tahu jenis lingkungan apa yang digunakan aplikasi Anda, tetapi terkadang masalah ini dapat terjadi di lingkungan web - di mana server aplikasi membuat hierarki pemuat kelas, menyerupai sesuatu seperti:
javahome/lib - sebagai root
appserver/lib - sebagai anak dari root
webapp/WEB-INF/lib - sebagai anak dari anak root
dll
Biasanya classloader mendelegasikan pemuatan ke classloader induknya (ini dikenal sebagai "parent-first
"), dan jika classloader tersebut tidak dapat menemukan class tersebut, maka child classloader akan mencoba melakukannya. Misalnya, jika class yang digunakan sebagai JAR di webapp/WEB-INF/lib mencoba memuat class, pertama-tama ia akan meminta classloader yang sesuai dengan appserver/lib untuk memuat kelas (yang pada gilirannya meminta classloader yang sesuai dengan javahome/lib untuk memuat kelas), dan jika pencarian ini gagal, maka WEB-INF/lib dicari kecocokan dengan kelas ini.
Di lingkungan web, Anda dapat mengalami masalah dengan hierarki ini. Misalnya, satu kesalahan/masalah yang saya alami sebelumnya adalah ketika kelas di WEB-INF/lib bergantung pada kelas yang diterapkan di appserver/lib, yang pada gilirannya bergantung pada kelas yang diterapkan di WEB-INF/lib. Ini menyebabkan kegagalan karena sementara classloader dapat mendelegasikan ke classloader induk, mereka tidak dapat mendelegasikan kembali ke bawah pohon. Jadi, classloader WEB-INF/lib akan meminta appserver/lib classloader untuk sebuah kelas, appserver/lib classloader akan memuat kelas itu dan mencoba memuat kelas dependen, dan gagal karena tidak dapat menemukan kelas itu di appserver/lib atau javahome /lib.
Jadi, meskipun Anda mungkin tidak menerapkan aplikasi Anda di lingkungan server web/aplikasi, penjelasan saya yang terlalu panjang mungkin berlaku untuk Anda jika lingkungan Anda memiliki hierarki pengaturan classloader. Melakukannya? Apakah JPF melakukan semacam keajaiban classloader agar dapat mengimplementasikan fitur pluginnya?
LinkageError adalah apa yang akan Anda dapatkan dalam kasus klasik di mana Anda memiliki kelas C yang dimuat oleh lebih dari satu pemuat kelas dan kelas tersebut digunakan bersama dalam kode yang sama (dibandingkan, dilemparkan, dll). Tidak masalah apakah itu nama Kelas yang sama atau bahkan jika itu dimuat dari toples yang identik - Kelas dari satu pemuat kelas selalu diperlakukan sebagai Kelas yang berbeda jika dimuat dari pemuat kelas lain.
Pesannya (yang telah meningkat pesat selama bertahun-tahun) berbunyi:
Exception in thread "AWT-EventQueue-0" java.lang.LinkageError:
loader constraint violation in interface itable initialization:
when resolving method "org.apache.batik.dom.svg.SVGOMDocument.createAttribute(Ljava/lang/String;)Lorg/w3c/dom/Attr;"
the class loader (instance of org/java/plugin/standard/StandardPluginClassLoader)
of the current class, org/apache/batik/dom/svg/SVGOMDocument,
and the class loader (instance of ) for interface org/w3c/dom/Document
have different Class objects for the type org/w3c/dom/Attr used in the signature
Jadi, di sini masalahnya adalah menyelesaikan metode SVGOMDocument.createAttribute(), yang menggunakan org.w3c.dom.Attr (bagian dari pustaka DOM standar). Namun, versi Attr yang dimuat dengan Batik dimuat dari classloader yang berbeda dari instance Attr yang Anda berikan ke metode.
Anda akan melihat bahwa versi Batik tampaknya dimuat dari plugin Java. Dan milik Anda sedang dimuat dari " ", yang kemungkinan besar adalah salah satu pemuat JVM bawaan (boot classpath, ESOM, atau classpath).
Tiga model classloader yang menonjol adalah:
- delegasi (default di JDK - tanya orang tua, lalu saya)
- pasca-delegasi (umum di plugin, servlet, dan tempat di mana Anda ingin isolasi - tanya saya, lalu orang tua)
- saudara (umum dalam model dependensi seperti OSGi, Eclipse, dll)
Saya tidak tahu strategi pendelegasian apa yang digunakan pemuat kelas JPF, tetapi kuncinya adalah Anda ingin satu versi pustaka dom dimuat dan semua orang mengambil sumber kelas itu dari lokasi yang sama. Itu mungkin berarti menghapusnya dari classpath dan memuatnya sebagai plugin, atau mencegah Batik memuatnya, atau yang lainnya.