java.lang.UnsatisectedLinkError No *****। jll.library.path এ dll


92

আমি কীভাবে আমার ওয়েব অ্যাপ্লিকেশনটিতে একটি কাস্টম dll ফাইল লোড করতে পারি? আমি নিম্নলিখিত চেষ্টা করেছি:

  • system32ফোল্ডারে সমস্ত প্রয়োজনীয় dlls অনুলিপি করেছেন এবং তাদের মধ্যে একটি Servletকনস্ট্রাক্টরে লোড করার চেষ্টা করেছেনSystem.loadLibrary
  • প্রয়োজনীয় dlls অনুলিপি tomcat_home/shared/libএবংtomcat_home/common/lib

এই সমস্ত dlls WEB-INF/libওয়েব অ্যাপ্লিকেশন হয়

উত্তর:


156

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() {
    }

}

4
System32 এ সমস্ত dll স্থাপন করে এবং System.loadLibrary ("কিছু") ব্যবহার করে কাজ করা হয়েছে। আমি আগে System.लोडলিবারি ("কিছু.ডিল") করছিলাম। এটি ওয়েবে-আইএনএফ থেকে সমস্ত ঘর কেন বোঝায় না? আমার ধারণা এটি ডিফল্টভাবে সমস্ত জার লোড করে দেয়। আমি সিস্টেম 32 এর পরিবর্তে ডব্লিউইবি-আইএনএফ থেকে সরাসরি এই লোডগুলি লোড করতে / জাভা.লিবারিয়ান.পথ
কেতন খায়রনার

4
মন্তব্য করার জন্য "bla.dll" এর পরিবর্তে 'bla "ব্যবহারের জন্য" bla "এর জন্য +1 - loadLibrary()যখন আপনি কী ভুল করছেন সে সম্পর্কে আপনার কোনও ধারণা নেই তখন খুব দরকারী।
মার্নিক্স ক্লাস্টার রিইনস্টেটমোনিকা

21
আমার সিস্টেমে (লিনাক্স এবং জাভা)) আমার একটি libউপসর্গ প্রয়োজন । তাই System.loadLibrary("foo")প্রয়োজন libfoo.so
ক্রিস্টিয়ানালম

4
ধন্যবাদ উইন্ডোজের জন্য "PATH" আপডেট করার সময় এটি আমার জন্য কাজ করেছিল যাতে এতে * .so ফাইল যুক্ত ফোল্ডার থাকে।
ব্যবহারকারী 613114

আমি ওএসএক্স blah.jnilibএবং লিনাক্সের প্রয়োজনীয় শপথ নিতে পারি libblah.so। ঠিক আছে, দুই ঘন্টা পরে, বহু চেষ্টা করার পরে, আমি এই সিদ্ধান্তে পৌঁছেছি যে lib
ওএসএক্সেরও

15

রানটাইমে 'java.library.path' পরিবর্তনশীল পরিবর্তন করা যথেষ্ট নয় কারণ এটি কেবল একবার JVM দ্বারা পড়ে read আপনাকে এটি পুনরায় সেট করতে হবে:

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)

এটি ঘটেছিল কারণ আপনার ডিএলএলটি মূলত লোড করা ক্লাসলুডার এখনও এই ডিএলএলটিকে উল্লেখ করে। যাইহোক, আপনার ওয়েব অ্যাপসটি এখন একটি নতুন ক্লাসলোডার দিয়ে চলছে এবং একই জেভিএম চলছে এবং কোনও জেভিএম একই ডিএলএল-তে 2 রেফারেন্সের অনুমতি দেবে না, আপনি এটি পুনরায় লোড করতে পারবেন না । সুতরাং, আপনার ওয়েব অ্যাপ্লিকেশন বিদ্যমান ডিএলএল অ্যাক্সেস করতে পারে না এবং একটি নতুন লোড করতে পারে না। সুতরাং .... আপনি আটকে আছেন।

টমক্যাটের ক্লাসলোডার ডকুমেন্টেশনের মধ্যে উল্লেখ করা হয়েছে যে আপনার পুনরায় লোড হওয়া ওয়েবআপস কেন একটি নতুন বিচ্ছিন্ন ClassLoader এ চলে এবং আপনি কীভাবে এই সীমাবদ্ধতাটি (খুব উচ্চ স্তরে) কাজ করতে পারেন।

সমাধানটি হ'ল অ্যাডাম বাটকিনের সমাধানটি আরও বাড়িয়ে দেওয়া:

   package awesome;

   public class Foo {

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

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

    }

তারপরে এই সংকলিত শ্রেণিকে JUST সমেত একটি জার রেখে TOMCAT_HOME / lib ফোল্ডারে।

এখন, আপনার ওয়েবঅ্যাপের মধ্যে, আপনাকে কেবল টমক্যাটকে এই শ্রেণীর রেফারেন্স করতে বাধ্য করতে হবে, যা কেবল এই হিসাবে করা যেতে পারে:

  Class.forName("awesome.Foo");

এখন আপনার ডিএলএলটি সাধারণ শ্রেণিবোর্ডারে লোড করা উচিত এবং পুনরায় কর্মরত হওয়ার পরেও আপনার ওয়েব অ্যাপ থেকে রেফারেন্স পাওয়া যায়।

ধারণা তৈরী কর?

একটি কার্যকারী রেফারেন্স অনুলিপি গুগল কোড, স্ট্যাটিক- dll-bootstrapper এ পাওয়া যাবে


4
এই উত্তরটি অ্যাপ্লিকেশন সার্ভারগুলির জন্য দুর্দান্ত এবং এটির নিজের প্রশ্ন থাকা উচিত কারণ এটি এই প্রশ্নটির অপচয় হয়।
জোশডিএম

8

আপনি System.load()ওএসের জন্য স্ট্যান্ডার্ড লাইব্রেরি ফোল্ডারে কোনও ফাইলের চেয়ে একটি নিখুঁত পথ সরবরাহ করতে ব্যবহার করতে পারেন ।

আপনি যদি ইতিমধ্যে বিদ্যমান নেটিভ অ্যাপ্লিকেশন চান, ব্যবহার করুন System.loadLibrary(String filename)। আপনি যদি নিজের নিজস্ব সরবরাহ করতে চান তবে আপনি সম্ভবত লোড () দিয়ে ভাল।

loadLibraryআপনার java.library.pathসেটটি সঠিকভাবে ব্যবহার করতে সক্ষম হওয়া উচিত । ClassLoader.javaউভয় পাথ পরীক্ষা করা হচ্ছে তা বাস্তবায়নের উত্সের জন্য দেখুন (ওপেনজেডিকে)


ধন্যবাদ লোড ব্যবহার করা আসলে অনেক সহজ এবং আরও স্বজ্ঞাত আইএমএইচও। আমি যাই করুক না কেন কাজ করার জন্য লোডলিবারি পেতে পারি নি ...
প্ল্যানকলকেল

4
এই সমাধান লাইব্রেরিগুলির জন্য কাজ করে না যা তাদের নিজস্ব গ্রন্থাগারগুলি লোড করে।
জাস্টিন স্কাইলস

7

যে ক্ষেত্রে সমস্যাটি হ'ল সিস্টেম.লোডলাইবারি ডিএলএলকে প্রশ্নের সন্ধান করতে পারে না, একটি সাধারণ ভুল ধারণা (জাভার ত্রুটি বার্তা দ্বারা জোরিত) হ'ল সিস্টেম সম্পত্তি java.library.path এর উত্তর। আপনি যদি নিজের ডিএলএল অবস্থিত ডিরেক্টরিটিতে java.library.path সিস্টেমের সম্পত্তিটি সেট করেন তবে System.loadLibrary সত্যিই আপনার ডিএলএল খুঁজে পাবে। তবে, আপনার ডিএলএল যদি অন্য ডিএলএলগুলির উপর নির্ভর করে, যেমনটি প্রায়শই ঘটে থাকে, তবে java.library.path সহায়তা করতে পারে না, কারণ নির্ভরশীল ডিএলএলগুলির লোডিং পুরোপুরি অপারেটিং সিস্টেম দ্বারা পরিচালিত হয়, যা জাভা.লাইবারির কিছুই জানে না। পথ সুতরাং, জাভা.লিবেরি.পথকে বাইপাস করা এবং জেভিএম শুরু করার পূর্বে আপনার ডিএলএল ডিরেক্টরিটি এলডি_লিবারি_পথ (লিনাক্স), ডিওয়াইএলডি_লিবারি_প্যাথ (ম্যাকোস), বা পাথ (উইন্ডোজ) এ যুক্ত করা প্রায় সবসময়ই ভাল।

(দ্রষ্টব্য: আমি ডিএলএল বা ভাগ করা লাইব্রেরির জেনেরিক অর্থে "ডিএলএল" শব্দটি ব্যবহার করছি)


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. একটি ফোল্ডার তৈরি করুন এবং এতে পিডিএফ্লিব জার রাখুন এবং আপনার PATH ভেরিয়েবলের মধ্যে ফোল্ডারটি যুক্ত করুন

এটি টমক্যাট 6 এর সাথে কাজ করেছিল।


3
  1. আপনি যদি বিশ্বাস করেন যে আপনি নেটিভ লিবের একটি পথ যুক্ত করেছেন তবে এর %PATH%সাথে পরীক্ষার চেষ্টা করুন:

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

এটি আপনার ডিএল চালু থাকলে আসলে দেখাতে হবে %PATH%

  1. আইডিই আইডিয়াটি পুনরায় চালু করুন, এটি এনভির সাথে ভেরিয়েবল সেটআপ করার পরে এটিতে যুক্ত করে আমার জন্য কাজ করতে উপস্থিত হয়েছিল %PATH%

2

বেচারা আমার! এর পিছনে একটি পুরো দিন ব্যয় করেছে any এখানে কোনও লিখিতভাবে লিখলে যদি কোনও সংস্থা এই সমস্যাটির প্রতিলিপি করে।

আমি অ্যাডামের পরামর্শ মতো লোড করার চেষ্টা করছিলাম তবে AMD64 বনাম আইএ 32 ব্যতিক্রমের সাথে ধরা পড়লাম। অ্যাডামের (কোনও সন্দেহ নেই সেরা বাছাই) ওয়াকথ্রু অনুসারে কাজ করার পরে যদি কোনও ক্ষেত্রে সর্বশেষ জেরের bit৪ বিটের সংস্করণ রাখার চেষ্টা করুন তবে নিশ্চিত হন আপনার জেআরই এবং জেডিকে 64 বিট এবং আপনি এটি সঠিকভাবে আপনার ক্লাসপথে যুক্ত করেছেন।

আমার কাজের উদাহরণটি এখানে যায়: অসন্তুষ্ট লিঙ্ক ত্রুটি


0

উইন্ডোজের জন্য আমি দেখতে পেলাম যে আমি যখন ফাইলগুলি (jd2xsx.dll কল এবং ftd2xx.dll) উইন্ডোজ / সিস্টেম 32 ফোল্ডারে লোড করেছি তখন এটি সমস্যার সমাধান করে। আমি তখন আমার নতুন fd2xx.dll সাথে পরামিতিগুলির সাথে করণীয় নিয়ে একটি সমস্যা পেয়েছিলাম যার কারণে আমাকে এই ডিলের পুরানো সংস্করণটি লোড করতে হয়েছিল। আমি পরে এটি বের করতে হবে।

দ্রষ্টব্য: jd2xsx.dll ftd2xx.dll কে কল করে তাই কেবল jd2xx.dll এর জন্য পথ নির্ধারণ করা কার্যকর নাও হতে পারে।


0

আমি ম্যাক ওএস এক্স ইয়োসেমাইট এবং নেটবিয়ানস ৮.০২ ব্যবহার করছি, আমি একই ত্রুটি পেয়েছি এবং যে সহজ সমাধানটি আমি পেয়েছি তা উপরের মত, যখন আপনাকে প্রকল্পে নেটিভ লাইব্রেরি অন্তর্ভুক্ত করা দরকার তখন এটি কার্যকর is নেটবিনের জন্য পরবর্তী কাজটি করুন:

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"
পথটিতে

মিম আমি গত বছরের জন্য জাভা নিয়ে কাজ করছি না তবে দ্বন্দ্ব দেখা দিতে পারে তাই ফাইলের ফাঁকে ফাঁকা স্থান যোগ করা থেকে বিরত থাকার পরামর্শ দিই ।
alexventuraio

0

আমার একই সমস্যা ছিল এবং ডিলটির একটি নতুন নামকরণের কারণে ত্রুটি হয়েছিল। এটি ঘটতে পারে যে লাইব্রেরির নামটিও ডেলির অভ্যন্তরে কোথাও লেখা ছিল। আমি যখন এর আসল নামটি পিছনে রেখেছি তখন আমি ব্যবহার করে লোড করতে সক্ষম হয়েছিSystem.loadLibrary


0

এটি কেবল সহজ জাভা লিখুন সহজ-প্রদর্শনসমূহ: উইন্ডোতে আপনার কমান্ড লাইনের বৈশিষ্ট্যগুলি এবং তারপরে java.library.path দ্বারা দেখানো পথে সমস্ত ফাইল আটকান।


0

প্রথমত, আপনি নিজের স্থানীয় লাইব্রেরিতে ডিরেক্টরিটি নিশ্চিত করতে চাইবেন java.library.path। এটি এখানে কীভাবে করবেন তা দেখুন । তারপরে, আপনি কল করতে পারেন System.loadLibrary(nativeLibraryNameWithoutExtension)- আপনার লাইব্রেরির নামে ফাইল এক্সটেনশন অন্তর্ভুক্ত না করার বিষয়ে নিশ্চিত হয়ে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.