java.lang.UnsatisfiedLinkError no *****। dll in java.library.path


92

मैं अपने वेब एप्लिकेशन में कस्टम dll फ़ाइल कैसे लोड कर सकता हूं? मैंने निम्नलिखित कोशिश की है:

  • सभी आवश्यक dlls को system32फ़ोल्डर में कॉपी किया और उनमें से एक को Servletकंस्ट्रक्टर में लोड करने का प्रयास कियाSystem.loadLibrary
  • में आवश्यक dlls की नकल की tomcat_home/shared/libऔरtomcat_home/common/lib

ये सभी dll WEB-INF/libवेब-एप्लिकेशन में हैं

जवाबों:


154

System.loadLibrary()काम करने के लिए , पुस्तकालय (विंडोज पर, एक डीएलएल) को आपके PATH याjava.library.path सिस्टम सिस्टम में सूचीबद्ध पथ पर कहीं निर्देशिका में होना चाहिए (ताकि आप जावा को लॉन्च कर सकें java -Djava.library.path=/path/to/dir)।

इसके अतिरिक्त, loadLibrary()आप .dllअंत के बिना, लाइब्रेरी का आधार नाम निर्दिष्ट करते हैं । तो, के लिए /path/to/something.dll, आप बस का उपयोग करेंगे System.loadLibrary("something")

आपको उस सटीक को भी देखना होगा UnsatisfiedLinkErrorजो आपको मिल रहा है। अगर यह कुछ ऐसा कहे:

Exception in thread "main" java.lang.UnsatisfiedLinkError: no foo in java.library.path

तो यह आपके या में foo पुस्तकालय (foo.dll) नहीं मिल सकता है । अगर यह कुछ ऐसा कहे:PATHjava.library.path

Exception in thread "main" java.lang.UnsatisfiedLinkError: com.example.program.ClassName.foo()V

तब पुस्तकालय में कुछ गलत है इस अर्थ में कि जावा अपने वास्तविक देशी समकक्ष के लिए आपके आवेदन में एक मूल जावा फ़ंक्शन को मैप करने में सक्षम नहीं है।

इसके साथ शुरू करने के लिए, मैं आपके System.loadLibrary()कॉल के आसपास कुछ लॉगिंग देखूंगा कि क्या यह ठीक से निष्पादित होता है। यदि यह एक अपवाद फेंकता है या एक कोड पथ में नहीं है जिसे वास्तव में निष्पादित किया जाता है, तो आपको हमेशा UnsatisfiedLinkErrorऊपर वर्णित प्रकार मिलेगा ।

एक विचार के रूप में, अधिकांश लोगों ने अपनी loadLibrary()कॉल को मूल तरीकों के साथ कक्षा में एक स्थिर इनिशियलाइज़र ब्लॉक में डाल दिया , यह सुनिश्चित करने के लिए कि इसे हमेशा एक बार निष्पादित किया जाता है:

class Foo {

    static {
        System.loadLibrary('foo');
    }

    public Foo() {
    }

}

1
System32 में सभी dll डालकर और System.loadLibrary ("कुछ") का उपयोग करके काम किया। मैं पहले System.loadLibrary ("something.dll") कर रहा था। क्यों यह WEB-INF से सभी dlls लोड नहीं कर सकता? मुझे लगता है कि यह डिफ़ॉल्ट रूप से सभी जार लोड करता है। मैं इन Dll को WEB-INF से सीधे System32 के बजाय लोड करने के लिए क्या कर सकता हूं / उन्हें java.library.path में निर्दिष्ट कर सकता हूं
केतन खैरनार

2
+1 टिप्पणी के लिए "bla.dll" के बजाय 'bla.dll' के उपयोग के loadLibrary()लिए-- बहुत उपयोगी है जब आपके पास कोई सुराग नहीं है कि आप क्या गलत कर रहे हैं।
MarnixKlooster ReinstateMonica

20
मेरे सिस्टम (लिनक्स और जावा 7) पर, मुझे एक libउपसर्ग की आवश्यकता है । तो System.loadLibrary("foo")जरूरत है libfoo.so
क्रिस्तिअल्म

2
धन्यवाद। यह मेरे लिए तब काम आया जब मैंने विंडोज़ के लिए "पैथ" को अपडेट किया ताकि इसमें फ़ोल्डर हो। * .so फ़ाइल।
user613114

15

रनवे पर 'java.library.path' वैरिएबल बदलना पर्याप्त नहीं है क्योंकि यह केवल JVM द्वारा एक बार पढ़ा जाता है। आपको इसे रीसेट करना होगा:

System.setProperty("java.library.path", path);
//set sys_paths to null
final Field sysPathsField = ClassLoader.class.getDeclaredField("sys_paths");
sysPathsField.setAccessible(true);
sysPathsField.set(null, null);

कृपया, यहां एक लूट ले लो: रनटाइम पर जावा लाइब्रेरी पथ बदलना


10

एडम बैटकिन का मूल उत्तर आपको एक समाधान की ओर ले जाएगा, लेकिन यदि आप अपने वेबएप को पुनः आरंभ करते हैं (अपने वेब कंटेनर को फिर से शुरू किए बिना), तो आपको निम्नलिखित त्रुटि में भाग लेना चाहिए:

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)

ऐसा इसलिए होता है क्योंकि ClassLader जो मूल रूप से आपके DLL को लोड करता है, वह अभी भी इस DLL को संदर्भित करता है। हालाँकि, आपका वेबप अब एक नए क्लासमैलर के साथ चल रहा है, और क्योंकि वही JVM चल रहा है और एक JVM एक ही DLL के 2 संदर्भों की अनुमति नहीं देगा, आप इसे पुनः लोड नहीं कर सकते । इस प्रकार, आपका webapp मौजूदा DLL तक नहीं पहुँच सकता है और एक नया लोड नहीं कर सकता है। इसलिए .... आप फंस गए हैं।

टॉमकैट के क्लास-लॉर्ड डॉक्यूमेंट की रूपरेखा यह बताती है कि आपका पुनः लोड किया गया व्हाट्सएप एक अलग-थलग पड़े क्लास-क्लास में क्यों चलता है और आप इस सीमा के आसपास (बहुत उच्च स्तर पर) कैसे काम कर सकते हैं।

समाधान है कि एडम बाटकिन के समाधान को थोड़ा बढ़ाया जाए:

   package awesome;

   public class Foo {

        static {
            System.loadLibrary('foo');
        }

        // required to work with JDK 6 and JDK 7
        public static void main(String[] args) {
        }

    }

तब TOMCAT_HOME / lib फ़ोल्डर में JUST में इस संकलित वर्ग वाले जार को रखना।

अब, अपने वेबएप के भीतर, आपको बस टॉम्कट को इस वर्ग को संदर्भित करने के लिए बाध्य करना होगा, जिसे बस इस प्रकार किया जा सकता है:

  Class.forName("awesome.Foo");

अब आपके DLL को सामान्य क्लास लोडर में लोड किया जाना चाहिए, और फिर से तैयार किए जाने के बाद भी आपके वेब से संदर्भित किया जा सकता है।

सही बात?

एक वर्किंग रेफरेंस कॉपी google code, static-dll-bootstrapper पर मिल सकती है


1
यह उत्तर एप्लिकेशन सर्वर के लिए उत्कृष्ट है और इसका अपना प्रश्न होना चाहिए क्योंकि यह इस प्रश्न पर व्यर्थ है।
जोशीडीएम

8

आप System.load()एक पूर्ण पथ प्रदान करने के लिए उपयोग कर सकते हैं जो आप चाहते हैं, संबंधित ओएस के लिए मानक पुस्तकालय फ़ोल्डर में एक फ़ाइल के बजाय।

यदि आप मूल एप्लिकेशन चाहते हैं जो पहले से मौजूद हैं, तो उपयोग करें System.loadLibrary(String filename)। यदि आप अपना स्वयं का प्रदान करना चाहते हैं तो आप शायद लोड () के साथ बेहतर हैं।

आपको सेट के loadLibraryसाथ java.library.pathसही तरीके से उपयोग करने में भी सक्षम होना चाहिए । ClassLoader.javaक्रियान्वयन स्रोत के लिए देखें दोनों रास्तों की जाँच की जा रही है (OpenJDK)


धन्यवाद। लोड का उपयोग करना वास्तव में बहुत आसान और अधिक सहज आईएमएचओ है। कोई फर्क नहीं पड़ता कि मैं क्या किया काम करने के लिए loadLibrary नहीं मिल सका ...
Plankalkül

2
यह समाधान उन पुस्तकालयों के लिए काम नहीं करता है जो अपने स्वयं के मूल पुस्तकालयों को लोड करते हैं।
जस्टिन स्काइल्स

7

इस मामले में जहां समस्या यह है कि System.loadLibrary प्रश्न में DLL नहीं पा सकते हैं, एक सामान्य गलतफहमी (जावा के त्रुटि संदेश द्वारा प्रबलित) है कि सिस्टम गुण java.library.path इसका उत्तर है। यदि आप उस सिस्टम प्रॉपर्टी java.library.path को उस डायरेक्टरी में सेट करते हैं, जहाँ आपका DLL स्थित है, तो System.loadLibrary वास्तव में आपका DLL खोजेगा। हालाँकि, यदि आपका DLL बदले में अन्य DLL पर निर्भर करता है, जैसा कि अक्सर होता है, तो java.library.path मदद नहीं कर सकता है, क्योंकि निर्भर DLL के लोडिंग को पूरी तरह से ऑपरेटिंग सिस्टम द्वारा प्रबंधित किया जाता है, जो java.library के कुछ भी नहीं जानता है। पथ। इस प्रकार, java.library.path को बायपास करना लगभग हमेशा बेहतर होता है और जेवीएम शुरू करने से पहले अपने DLL की निर्देशिका को LD_LIBRARY_PATH (Linux), DYLD_LIBRARY_PATH (MacOS), या पथ (Windows) में जोड़ें।

(नोट: मैं DLL या साझा लाइब्रेरी के सामान्य अर्थ में "DLL" शब्द का उपयोग कर रहा हूं।)


5

यदि आपको किसी ऐसी निर्देशिका के सापेक्ष फ़ाइल लोड करने की आवश्यकता है जहाँ आप पहले से मौजूद हैं (जैसे वर्तमान निर्देशिका में), तो यहाँ एक आसान समाधान है:

File f;

if (System.getProperty("sun.arch.data.model").equals("32")) {
    // 32-bit JVM
    f = new File("mylibfile32.so");
} else {
    // 64-bit JVM
    f = new File("mylibfile64.so");
}
System.load(f.getAbsolutePath());

4

जिनकी तलाश है java.lang.UnsatisfiedLinkError: no pdf_java in java.library.path

मैं एक ही अपवाद का सामना कर रहा था; मैंने इसे बनाने के लिए हर चीज और महत्वपूर्ण चीजों की कोशिश की:

  1. पीडीएफ का सही संस्करण lib.jar (मेरे मामले में यह सर्वर रनटाइम में रखा गया गलत संस्करण जार था)
  2. एक फ़ोल्डर बनाएं और उसमें pdflib जार रखें और अपने PATH चर में फ़ोल्डर जोड़ें

इसने tomcat 6 के साथ काम किया।


3
  1. यदि आप मानते हैं कि आपने मूल देयता का एक रास्ता जोड़ा है %PATH%, तो इसके साथ परीक्षण करने का प्रयास करें:

    System.out.println(System.getProperty("java.library.path"))

यदि आपका dll चालू है तो यह आपको वास्तव में दिखाना चाहिए %PATH%

  1. आईडीई आइडिया को फिर से शुरू करें, जो मेरे द्वारा काम करने के बाद एनवी चर को इसमें जोड़कर काम करने के लिए दिखाई दिया %PATH%

2

बेचारा मैं ! इसके पीछे एक पूरा दिन बिताया। किसी भी निकाय ने इस मुद्दे की प्रतिकृति बनाने के लिए इसे नीचे रखा।

मैं आदम के सुझाए अनुसार लोड करने की कोशिश कर रहा था, लेकिन फिर AMD64 बनाम IA 32 अपवाद के साथ पकड़ा गया। यदि एडम के अनुसार काम करने के बाद किसी भी मामले में (सबसे अच्छा पिक) संदेह नहीं है, तो नवीनतम jre.Make के 64 बिट संस्करण का प्रयास करें। आपका JRE और JDK 64 बिट है और आपने इसे अपने क्लासपाथ में सही तरीके से जोड़ा है।

मेरा काम करने का उदाहरण यहां मिलता है: असंतुष्ट लिंक त्रुटि


0

खिड़कियों के लिए मैंने पाया कि जब मैं भरा (jd2xsx.dll कॉल & ftd2xx.dll) को windowws / system32 फ़ोल्डर में लोड किया तो इससे समस्याएं हल हो गईं। मैं तो मेरे नए fd2xx.dll के साथ एक मुद्दा था मापदंडों के साथ करने के लिए जिसके कारण मुझे इस dll के पुराने संस्करण को लोड करना पड़ा। मुझे बाद में इसे पूरा करना होगा।

नोट: jd2xsx.dll ftd2xx.dll को कॉल करता है, इसलिए केवल jd2xx.dll के लिए पथ सेट करने से काम नहीं हो सकता है।


0

मैं Mac OS X Yosemite और Netbeans 8.02 का उपयोग कर रहा हूं, मुझे वही त्रुटि मिली और मुझे जो सरल समाधान मिला है वह ऊपर की तरह है, यह तब उपयोगी है जब आपको प्रोजेक्ट में मूल लाइब्रेरी शामिल करने की आवश्यकता होती है। तो Netbeans के लिए अगला काम करें:

1.- Right click on the Project
2.- Properties
3.- Click on RUN
4.- VM Options: java -Djava.library.path="your_path"
5.- for example in my case: java -Djava.library.path=</Users/Lexynux/NetBeansProjects/NAO/libs>
6.- Ok

मुझे उम्मीद है कि यह किसी के लिए उपयोगी हो सकता है। लिंक जहां मुझे समाधान मिला है वह यहां है: java.library.path - यह क्या है और कैसे उपयोग करना है


हाय एलेक्स, मैं यहाँ एक सवाल है कोई समस्या है अगर पुस्तकालय पथ इस पंक्ति में पथ में कुछ रिक्ति शामिल हैVM Options: java -Djava.library.path="your_path"
लोकेश पांडे

मम्म मैं पिछले साल के लिए जावा के साथ काम नहीं कर रहा हूं, लेकिन संघर्ष के रूप में प्रकट हो सकता है मैं फ़ाइल पथ में रिक्त स्थान जोड़ने से बचने की सलाह देता हूं ।
एलेक्सवेंटुरायो

0

मुझे एक ही समस्या थी और त्रुटि डीएल के एक नाम के कारण थी। ऐसा हो सकता है कि पुस्तकालय का नाम भी dll के अंदर कहीं लिखा हो। जब मैंने इसका मूल नाम वापस रखा तो मैं इसका उपयोग करने में सक्षम थाSystem.loadLibrary


0

यह सिर्फ़ java -XshowSettings लिखना सरल है: विंडोज़ में आपकी कमांड लाइन पर गुण और फिर java.library.path द्वारा दिखाए गए रास्ते में सभी फ़ाइलों को पेस्ट करें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.