تبين هذه الوثيقة أسلوب تحويل كود برامج لغة جافا إلى كود أصيل لويندوز باستخدام إصدارة محددة من GNU Compiler Collection (GCC) ذي المصدر المفتوح تعمل تحت ويندوز و مجهزة خصيصا لهذا الغرض. تبين الوثيقة كيفية اتمام هذه العملية مع خيارات الربط الستاتيكي أو الديناميكي لكود غير ذي واجهة مستخدم رسومية أو ذي واجهة مستخدم رسومية.
Java, Open Source, GCC, GCJ, Native Compile, Windows, AWT, Swing, SWT, SwingWT, Eclipse, Static Linking, Dynamic Linking, GUI
التعديلات: - كتابة الوثيقة الأساسية.
الإصدار 0.9
مشروع الوثيقة التقنية مشروع تطوعي
من مجتمع الكمبيوتر العربي يهدف إلى وضع معلومات تقنية مركزة و متقدمة في وثائق
قابلة للتنزيل من الوب وسهلة الطباعة ومسموح بتوزيعها حسب رخصة الإستخدام. هذه
الوثائق ستكون قابلة للنمو و الزيادة و التصحيح من قبل من يتطوع. ينتج من ذلك
زيادة المعرفة حتى للكاتب نفسه و إخراج جهد تعاوني يصبح مرجعا في موضوع الوثيقة
للجمهور التقني العربي. للمزيد من المعلومات و لمعرفة أسلوب المشاركة و معاييرها
الرجاء زيارة صفحة المشروع.
سأقوم هنا بشرح مبسط لكيقية تحويل Compile)) شفرة مصدر لبرنامج مكتوب بجافا إلى كود أصيل باستخدام الكومبايلر الأسطوري مفتوح المصدر GCC. العملية ممكنة تحت ويندوز أو لينوكس و يمكن عمل تحويل إلى ملف تنفيذي أو مكتبة ربط( لكل من ويندوز أو لينوكس) مستقل بذاته ولا يحتاج إلى وجود أي آلة افتراضية لجافا Java Virtual Machine في الجهاز المراد تشغيل البرنامج عليه و هذا هو الفرق بين هذه الطريقة و الطريقة المنتهجة من بعض البرامج الصغيرة التي تخرج ملف exe لتشغيل برامج جافا بدون عمل تحويل لكود أصيل و إنما يقوم هذا الملف التنفيذي بمجرد البحث عن آلة جافا الإفتراضية في الجهاز وتشغيل البرنامج عن طريقها ولا يعمل البرنامج بدون وجودها. العملية المشروحة هنا هي تحت ويندوز لإنتاج ملف تنفيذي exe لويندوز.
|
لماذا يحتاج أي شخص لعمل تحويل أصيل لكود جافا؟ البرامج المكتوبة بلغة جافا تحتاج في الوضع الطبيعي إلى وجود آلة جافا الإفتراضية في الجهاز الهدف المراد تشغيل البرنامج عليه. و لكن في الحقيقة فإن معظم الأجهزة المكتبية التي تستعمل نظام التشغيل ويندوز لا تحتوي إلاإصدارة قديمة جدا من اآلة الإفتراضية من إنتاج ميكروسوفت. هذه الإصدارة غير كافية لتشغيل أي برنامج جافا حديث و يلزم وجود إصدارة حديثة من Sun Java Runtime Environment أو مايقابلها (من IBM مثلا) . إذن عندما تريد توزيع البرنامج فأنت أمام خيارين: الأول هو توزيع Java RE مع برنامجك و الثاني هو الطلب من المستخدمين الحصول عليها بطريقتهم الخاصة (تنزيل من ويب مثلا). الحجم المضغوط لحزمة Java RE من Sun وقت كتابة هذه السطور (الإصدارة 1.4205) هو 14.91 ميجابايت. هذا الحجم الكبير يمثل مشكلة لطرق التوزيع عبر ويب. الحل الثالث إذا هو الإستغناء عن آلة جافا الإفتراضية و عمل تحويل أصيل إلى الى نظام التشغيل الهدف و هو كما تلاحظ في الأمثلة يقلل الحجم كثيرا. يفيد أيضا التحويل الأصيل في تسريع عمل البرنامج بإزالة عبئي الترجمة (Interpretation) و وقت بدء آلة جافا الإفتراضية. على الرغم من التحسن المضطرد في السرعة في إصدارات جافا الحديثة و تقنيات Just In Time Compile إلا أنه يمكن ملاحظة الزيادة في السرعة عند عمل تحويل أصيل خصوصا في وقت بدء البرنامج. ماهي عيوب التحويل الأصيل لجافا؟ الأول أن هذا ممكن في التطبيقات المكتبية ولن يعمل (ولاحاجة له حقيقة) في برامج جهة المزود لعدم وجود دعم له في مزودات تطبيقات جافا. الثاني أن عملية التحويل الأصيل يمكن عملها باستخدام برامج تجارية غالية جدا أو باستخدام برامج مفتوحة المصدر (المشروحة هنا) ولكنها في مراحل التطوير الأولى (لاحظ أننا في هذه الوثيقة نستخدم إصدارة ليست معتمدة كإصدارة مستقرة و ليست حتى إصدارة رسمية من GCC). إذن ربما تواجه بعض المشاكل في البرامج الأكثر تعقيدا. |
تبنت حركة المصدر المفتوح لغة جافا بدرجة كبيرة. من المشاريع الكبرى مفتوحة المصدر المتضمنة تقنيات جافا Eclipse و NetBeans و Tomcat و JBoss وغيرها الكثير ولكن ما يعنينا هنا هو مشروع GCC وهذه الحروف هي اختصار GNU Compiler Collection وهو أداة التطوير الرئيسية في Linux/Unix وحركة المصادر المفتوحة. يحوي GCC محولات ( (Compilers للعديد من لغات البرمجة منها GCC (GNU C Compiler) و GCJ (GNU Java Compiler). يعامل GCJ جافا كأية لغة أخرى مدعومة ويسمح بعمل تحويل إلى كود أصيل باستعمال تحسينات Optimization عالية الكفاءة مستعارة من GCC حيث أن جافا هي في الحقيقة مجموعة جزئية من C++. تسمح مجموعة محولات GCC بتكامل وثيق أيضا بين جافا و C++ عبر ال Compiled Native Interface (CNI) الأسهل والأكثر مباشرة من أسلوب Java Native Interface (JNI) القياسي. يستطيع GCJ أيضا (وهي الميزة الأساسية التي سنستخدمه فيها في هذا المقال) عمل تحويل لكود جافا إلى كود أصيل Native Code)) بحيث لاتعود لغة جافا مترجمة (Interpreted) و إنما محولة (Compiled). بمعنى آخر لايوجد ByteCode و إنما كود تنفيذي.
GCJ يمكنه الآن ترجمة كود جافا ويدعم مكتبة الأصناف حتى الإصدارة 1.2(مع الكلمة المفتاحية assert من 1.4) باستثناء حزمتي Swing و AWT الذي يجري العمل عليهما حاليا. لاحظ أن كل الأصناف مكتوبة من قبل مبرمجي المصدر المفتوح ضمن مشروع GNU Classpath. رغم أن كتابة حزمتي Swing و AWT لم تكتمل فإنه بالمقابل يمكن تحويل برامج بواجهة رسومية مكتوبة ياستخدام حزمة SWT من مشروع Eclipse (من تنفيذ IBM أساسا) و التي تلقى رواجا بين مبرمجي جافا مؤخرا.
|
نبذة عن خيارات تطوير تطبيقات واجهة المستخدم الرسومية المتوفرة لمبرمجي جافا بشكل عام: توفر حزمة AWT واجهة برمجة موحدة API لكل نظم التشغيل المدعومة إلا أنها تطلب الشفرة الأصيلة لنظام التشغيل لتنفيذ إظهار عناصر الواجهة الرسومية. لذا اتيعت أسلوب العامل المشترك الأصغر بين الأنظمة فلم تدعم من عناصر واجهة الإستخدام إلا ماهو موجود في كل الأنظمة المدعومة مما نتج عنه عدد محدود من العناصر المدعومة و الميزات إضافة لعيوب أخرى كثيرة. قامت بعد هذا SUN بتقديم حزمة Swing وهي تقدم عناصر تحكم رسومية غنية جدا مكتوبة بلغة جافا فقط. تنتهج حزمة SWT أسلوب شبيه نوعا ما مع أسلوب AWT حيث تعتبر طبقة تنادي الشفرة الأصيلة لنظام التشغيل ولكنها تدعم عدد كبير من عناصر الواجهة الرسومية حيث أنها تنادي الشفرة الأصيلة في حالة وجود دعم من نظام التشغيل للعنصر المطلوب و تحاكي Emulate هذا العنصر في حالة عدم وجود دعم له من نظام التشغيل بكود منها. فتأخذ منهج متوسط بين منهجي AWT و Swing . وتتغلب على العديد من عيوب التصميم الأخرى في AWT.
|
حسنا إذا يمكنك إذا بناء برامج بواجهة مستخدم رسومية لسطح المكتب بلغة جافا تحت GCJ(أو تحت Sun JDK أيضا بالطبع) باستخدام حزمة SWT. يمكنك الحصول على ملف ال jar و التوثيق من موقع مشروع Eclipse.
على الرغم من أن تعلم واجهة برمجة SWT سهل ,حيث أن التوثيق واضح وهي تشبه Swingإلى حد ما, لكن ماذا لو أنك تكاسلت عن تعلم SWT ولكنك تريد الإستفادة من ميزة التحويل الأصيل في GCJ. أو أن لديك كود موجود مكتوب ب Swing/AWT وتريد تحويله لكود أصيل في GCJ ؟
رغم أن الحل الحقيقي هو الإنتظار حتى تنتهي كتابة حزمتي Swing و AWT في GNU Classpath فإن حلا مؤقتا فعالا ظهر حديثا في مشروع يسمى SwingWTأشبه بالجسر. تقوم هذه الحزمة باستخدام واجهة برمجة Swing و AWT و لكنها تنفذ باستخدام SWT. أي أنك تكتب Swing/AWT وتحصل على SWT.
لنجعل هذا كله يعمل معا ونجعل الحياة أسهل في نفس الوقت فإننا سنستعمل (وهو كل ماتحتاجه) الملف المضغوط التالي: gcc34-20040607.tar.bz2 الذي يمكنك تنزيله من الموقع http://www.thisiscool.com/gcc_mingw.htm
44 ميجابات تقريبا.
ماذا يحوي هذا الملف؟
يحوي GCC 3.4 و مايلزم لعمله في ويندوز مرقوعا برقع لم تتم الموافقة عليها بعد. ومايلزم لتحويل كود SWT و AWT و Swing (الأخيران باستخدام SwingWT).
إلى العمل:
التعليمات التالية ستعمل فقط على الإصدارة الخاصة من GCC الموجودة في الملف المذكور أعلاه من الموقع المحدد.
c:\ thisiscool-gcc
|
محتويات ملف Hello.java |
|
public class Hello{ public static void main(String[] args){ System.out.println("Hello GCJ!\n"); } } |
gcj will link statically with the original libraries.
gcj "c:\w\hello\Hello.java" --main=Hello -o "c:\w\hello\Hello.exe"
لن يظهر gcj أي رسالة في حالة النجاح.
gcj will link dynamically with the original libraries.
Please remember that when you distribute executables linked
this way, the GPL requires you to make the source of libgcj.dll
available as well in the same manner that you make your binaries
available. (That is, same IP address, etc(
gcj "c:\w\hello\Hello.java" --main=Hello -o "c:\w\hello\Hello.exe"
ربما يظهر gcj بعض الرسائل التي تبدأ ب
Info:
لايعني هذا وجود أي مشكلة العملية تمت بنجاح.
C:\thisiscool-gcc\gcc-3.4\i686-pc-mingw32\lib ملف باسم libgcj.dll.origdll .انسخه إلى مجلد الملف التنفيذي الناتج ثم غير اسمه إلى libgcj.dll عندها سيعمل البرنامج بنجاح عند تجربته.
لاحظ أن حجم الملف التنفيذي الناتج هو 399 كيلوبايت فقط وهذا بسبب أن معظم الكود الذي يحتاجه البرنامج للتنفيذ موجود في مكتبة الربط libgcj.dll وستتم استعارته منها في وقت تشغيل الملف وهذا هو معنى الربط الديناميكي . و لكن حجم هذه المكتبة (المأخوذة من ملف libgcj.dll.origdll كما تذكر) هو 4.95 مبجابايت. والحجم المضغوط للملف التنفيذي و المكتبة مضغوطين معا في ملف rar هو 1.22 ميجابايت الذي لازال مناسب للتوزيع على ويب. هناك ميزة أخرى هنا أن المستخدمين لبرنامجك الخطير سيحتاجون لتنزيل الملفين في المرة الأولى فقط وبعدها في حالة أنك أجريت أي تحديثات على برنامجك فلن يحتاجوا إلا لتنزيل الملف التنفيذي الصغير جدا فقط.
|
محتويات ملف HelloGUI.java |
|
import javax.swing.*; import java.awt.event.*;
public class HelloGUI extends JFrame{
static JButton myButton=new JButton("Show Text"); static JTextField myText=new JTextField(); static boolean switched=false;
public HelloGUI(){ setSize(400,150); setTitle("HelloGUI"); setDefaultCloseOperation(EXIT_ON_CLOSE); myText.setBounds(100,60,200,35); myButton.setBounds(100,20,200,35); myButton.addActionListener(new myButtonActionAdapter()); getContentPane().setLayout(null); getContentPane().add(myButton); getContentPane().add(myText); setVisible(true); } public static void main(String[] args){ HelloGUI myFrame=new HelloGUI(); }
class myButtonActionAdapter implements ActionListener {
public void actionPerformed(ActionEvent e) { if(!switched){ myText.setText("Hello GCJ!"); myButton.setText("Erase Text"); switched=true; } else { myText.setText(""); myButton.setText("Show Text"); switched=false; } } }
} |
gcj will link statically with integrated SWT + SwingWT.
gcj "c:\w\hellogui\HelloGUI.java" --main=HelloGUI -o "c:\w\hellogui\HelloGUI.exe"
لن يظهر gcj أي رسالة في حالة النجاح.
swt-win32-3054.dll في موضع يراه الملف التنفيذي. فقم بنسخه من المجلد
c:\thisiscool-gcc/gcc-3.4/i686-pc-mingw32/lib
إلى مجلد البرنامج التنفيذي الناتج.
لاحظ أن حجم الملف التنفيذي الناتج هو 8.53 ميجابايت وهذا بسبب أن أي كود يحتاجه البرنامج للتنفيذ من المكتبات قد وضع في داخل الملف التنفيذي الناتج ذاته (باستثناء كود مكتبة ربط swt المذكورة المربوط ديناميكيا) وهذا هو معنى الربط الستاتيكي كما سبق الذكر. يمكن تقليص حجم الملف بضغطه هو وملف الDLL المذكور باستخدام WinRAR حتى 1.42 ميجا بايت فقط وهو حجم مناسب للتوزيع على ويب.
gcj will link dynamically with integrated SWT + SwingWT.
Please remember that when you distribute executables linked
this way, the GPL requires you to make the source of libgcj.dll
available as well in the same manner that you make your binaries
available. (That is, same IP address, etc.(
gcj "c:\w\hellogui\HelloGUI.java" --main=HelloGUI -o "c:\w\hellogui\HelloGUI.exe"
ربما يظهر gcj بعض الرسائل التي تبدأ ب
Info:
لايعني هذا وجود أي مشكلة العملية تمت بنجاح.
C:\thisiscool-gcc\gcc-3.4\i686-pc-mingw32\lib وانسخ الملف libgcj.dll.guidll (انتبه ليس libgcj.dll.origdll المستخدم في الحالة رقم 2) إلى مجلد الملف التنفيذي الناتج ثم غير اسمه إلى libgcj.dll. كما أن البرنامج سيحتاج أيضا ملف swt-win32-3054.dll المستخدم في الخطوة السابقة فضعه في مجلد البرنامج التنفيذي إن لم يكن هناك بالفعل. عند توفر ملفي DLL المذكورين سيعمل البرنامج بنجاح عند تجربته.
لاحظ أن حجم الملف التنفيذي الناتج هو 463 كيلوبايت فقط وهذا بسبب أن معظم الكود الذي يحتاجه البرنامج للتنفيذ موجود في مكتبات الربط وستتم استعارته منها في وقت تشغيل الملف وهذا هو معنى الربط الديناميكي كماتعلم . و لكن حجم هذه المكتبة (المأخوذة من ملف libgcj.dll.guidll كما تذكر) هو 10.4 مبجابايت. والحجم المضغوط للملف التنفيذي و ملفي الDLL مضغوطين معا في ملف rar هو 2.35 ميجابايت فقط الذي لازال مناسب للتوزيع على ويب. الميزة في الربط الديناميكي كما ذكرنا هو أن المستخدمين لبرنامجك الخطير سيحتاجون لتنزيل ملفات الDLL في المرة الأولى فقط وبعدها في حالة أنك أجريت أي تحديثات على برنامجك أو وزعت برامج أخرى مبنية بنفس الأسلوب فلن يحتاجوا إلا لتنزيل الملف التنفيذي الصغير جدا فقط لأن لديهم ملفات الDLL التي لم تتغير.
(نشجع المشاركة)
|
الصفحة الرسمية لهذه الوثيقة. تأكد أن الوثيقة التي لديك هي الإصدارة الأحدث. |
http://www.arabcc.net/techdoc/gcjnativewin
|
|
لمناقشة هذه الوثيقة مع الكاتب و اقتراح التصحيحات و الإضافات زر صفحة المناقشة الرسمية |
|
|
مجتمع الكمبيوتر العربي (مصدر الوثيقة) |
|
|
مشروع الوثيقة التقنية من مجتمع الكمبيوتر العربي |
|
|
البريد الإلكتروني للكاتب |
|
|
صفحة تنزيل حزمة البرامج المطلوبة و معلومات عنها (e) |
|
|
الصفحة الرسمية لمشروع GCC (e) |
|
|
دليل الإستخدام الرسمي ل GCC (e) |
|
|
الصفحة الرسمية لمشروع Eclipse (e) |
|
|
الصفحة الرسمية لمشروع SwingWT (e) |
|
إصدارة |
Version |
|
إصدارة مستقرة |
Stable Version |
|
آلة افتراضية |
Virtual Machine |
|
التحويل فقط في الوقت المناسب |
JIT (Just In Time) Compile |
|
حزمة |
Package |
|
ربط |
Link (Object Code) |
|
رقعة |
Patch |
|
صنف |
Class |
|
عناصر واجهة المستخدم الرسومية |
Widgets, Controls |
|
كلمة مفتاحية |
Keyword |
|
كود أصيل |
Native Code |
|
محاكاة |
Emulation |
|
مزود |
Server |
|
مزود تطبيقات |
Application Server |
|
مفتوح المصدر |
Open Source |
|
مكتبة ربط ديناميكي |
Dynamic Link Library |
|
ملف تنفيذي |
Executable File |
|
واجهة المستخدم الرسومية |
Graphical User Interface, GUI |
|
وصلة |
Hyper Link |
|
يترجم |
Interpret |
|
يحول |
Compile |
|
ينزل |
Download |