คำตอบเดิมของ Adam Batkin จะนำคุณไปสู่วิธีแก้ปัญหา แต่ถ้าคุณปรับใช้เว็บแอปอีกครั้ง (โดยไม่ต้องรีสตาร์ทคอนเทนเนอร์เว็บของคุณ) คุณควรพบข้อผิดพลาดต่อไปนี้:
java.lang.UnsatisfiedLinkError: Native Library "foo" already loaded in another classloader
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1715)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1646)
at java.lang.Runtime.load0(Runtime.java:787)
at java.lang.System.load(System.java:1022)
สิ่งนี้เกิดขึ้นเนื่องจาก ClassLoader ที่โหลด DLL ของคุณ แต่เดิมยังคงอ้างอิง DLL นี้ อย่างไรก็ตามขณะนี้เว็บแอปของคุณทำงานด้วย ClassLoader ใหม่และเนื่องจาก JVM เดียวกันกำลังทำงานอยู่และ JVM ไม่อนุญาตให้มีการอ้างอิง 2 รายการไปยัง DLL เดียวกันคุณจึงไม่สามารถโหลดซ้ำได้ ดังนั้นเว็บแอปของคุณจึงไม่สามารถเข้าถึง DLL ที่มีอยู่และไม่สามารถโหลดใหม่ได้ ดังนั้น .... คุณติดอยู่
เอกสาร ClassLoader ของ Tomcat จะอธิบายว่าเหตุใดเว็บแอปที่โหลดซ้ำของคุณจึงทำงานใน ClassLoader ใหม่ที่แยกออกมาและคุณจะแก้ไขข้อ จำกัด นี้ได้อย่างไร (ในระดับที่สูงมาก)
วิธีแก้ปัญหาคือการขยายโซลูชันของ Adam Batkin เล็กน้อย:
package awesome;
public class Foo {
static {
System.loadLibrary('foo');
}
public static void main(String[] args) {
}
}
จากนั้นวาง jar ที่มีเพียงคลาสที่คอมไพล์นี้ลงในโฟลเดอร์ TOMCAT_HOME / lib
ตอนนี้ภายใน webapp ของคุณคุณต้องบังคับให้ Tomcat อ้างอิงคลาสนี้ซึ่งสามารถทำได้ง่ายๆดังนี้:
Class.forName("awesome.Foo");
ตอนนี้ DLL ของคุณควรโหลดใน classloader ทั่วไปและสามารถอ้างอิงได้จากเว็บแอปของคุณแม้ว่าจะถูกปรับใช้ใหม่
เข้าท่า?
สำเนาอ้างอิงการทำงานสามารถพบได้ในรหัส Google, คง dll-bootstrapper