الإشارة إلى المكتبات لـ Linux قابلة للتنفيذ
-
21-09-2019 - |
سؤال
لقد كتبت تطبيقًا في Java وقمت بتجميعه بشكل ناجح باستخدام GCJ. لقد نجح الأمر بشكل جيد ، لكنني واجهت عقبة: لا يمكنني تشغيل القابل للتنفيذ إلا من خلال برنامج نصي shell ، لأنني يجب أن أحدد مسارات المكتبة.
المكتبات التي أحتاجها هي SWT و Xerces و Gnu-Crypto.
هل هناك طريقة لربط المكتبات بشكل ثابت عند التجميع gcj
, ، أم أن هذه ليست فكرة جيدة؟ بدلاً من ذلك ، هل يمكنني تحديد مسار المكتبة (النسبي) أثناء التجميع؟
في الوقت الحاضر ، يبدو البرنامج النصي الخاص بي مثل هذا:
#!/bin/sh
export LD_LIBRARY_PATH=./libs/:$LD_LIBRARY_PATH
exec ./MyJavaApp $*
المحلول
الفكرة هي جعل المجال الثابت "sys_paths" فارغًا بحيث يقوم ببناء المسارات من القيمة المتغيرة. انظر المنشور هنا (المنشور رقم 223 بواسطة Ajaysingh516) http://forums.sun.com/thread.jspa؟messageid=3744346#3744346
Class clazz = ClassLoader.class;
Field field = clazz.getDeclaredField("sys_paths");
boolean accessible = field.isAccessible();
if (!accessible)
field.setAccessible(true);
Object original = field.get(clazz);
// Reset it to null so that whenever "System.loadLibrary" is called, it
// will be reconstructed with the changed value.
field.set(clazz, null);
try {
// Change the value and load the library.
System.setProperty("java.library.path", "./libs/");
System.loadLibrary("mylibapr");
} finally {
// Revert back the changes.
field.set(clazz, original);
field.setAccessible(accessible);
}
.
خصائص نظام GCJ (انظر: الخصائص القياسية التي تدعمها LIBGCJ)
http://gcc.gnu.org/onlinedocs/gcj/system-properties.html
.
الحل#2: تعيين متغير بيئة النظام في وقت الترجمة
http://linux.die.net/man/1/gcj
لهذا عليك استخدام المعلمة -Djava.library.path=./libs/
مع gcj
من دليل GCJ (أعلاه الرابط):
-مين = اسم className
يتم استخدام هذا الخيار عند الارتباط بتحديد اسم الفصل الذي يجب استدعاء طريقة "الرئيسية" عند تشغيل القابل للتنفيذ الناتج.
-dname [= value
لا يمكن استخدام هذا الخيار إلا مع "-مان". يحدد خاصية النظام المسماة مع قيمة القيمة. إذا لم يتم تحديد القيمة ، فإنها تتخلف عن السلسلة الفارغة. تتم تهيئة خصائص النظام هذه عند بدء تشغيل البرنامج ويمكن استردادها في وقت التشغيل باستخدام طريقة "java.lang.system.getProperty".
لم أعمل أبدًا مع GCJ ، ولكن وفقًا لمستندات المستندات ، يمكن استرداد خصائص النظام هذه في وقت التشغيل ، وبالتالي فسيكون محمولًا لأنظمة أخرى أيضًا.
انظر أيضا: http://gcc.gnu.org/wiki/stivaly_linking_libgcj؟action=show&redirect=stily+Linking+LibgCj
نصائح أخرى
للإجابة على الجزء الأول من سؤالك -
من صفحة GCJ Man: "قد يتسبب الارتباط الثابت لـ LIBGCJ إلى الفصول الدراسية. عادة ما تكون النتيجة (ولكن ليس دائمًا) "ClassNotFoundException" يتم إلقاؤها في وقت التشغيل. يجب استخدام الحذر عند استخدام هذا الخيار. "
للربط الثابت للمكتبات الأخرى ، لست متأكدًا. لم يكن لدي سبب للقيام بذلك.
تختلف Linux Executables عن Windows. عادةً ما يكون لديك "قاذفة" أو بعض هذا الاعتماد على نظام الرياح الدقيق الذي تستخدمه. قمت بتعيين الرمز في ذلك ، وليس على القابل للتنفيذ نفسه. عادةً ما يتم استخدام البرامج النصية لإطلاق لتعيين أي بيئة تحتاجها لتشغيل القابلة للتنفيذ. مرة أخرى ، كل هذا يعتمد على نظام نافذة سطح المكتب الدقيق.
لماذا تستخدم AOT؟ أود أن أقترح قراءة المقالة التالية. أحد العيوب التي يذكرها AOTS هي ما يلي ...
التطبيقات الديناميكية. قد تكون الفصول التي يتم تحميلها ديناميكيًا في وقت التشغيل غير متاح لمطور التطبيق. يمكن أن تكون هذه المكونات الإضافية من طرف ثالث ، وكلاء ديناميكيين ، وفئات أخرى تم إنشاؤها في وقت التشغيل وما إلى ذلك. لذلك يجب أن يتضمن نظام وقت التشغيل مترجم Java Bytecode و/أو مترجم JIT.