Jack הוא שרשרת הכלים לבניית Android שמוגדרת כברירת מחדל ב-Android 6.0 עד Android 8.1
Jack הוא שרשרת כלים של Android שקומפלה ממקור Java ל-bytecode של Android dex. כדי להשתמש ב-Jack, לא צריך לעשות שום דבר שונה – פשוט משתמשים בפקודות הרגילות של makefile כדי לקמפל את העץ או את הפרויקט. Android 8.1 היא הגרסה האחרונה שנעשה בה שימוש ב-Jack.
מידע על ג'ק
החיבור של השקע מוצג באיור 1.
איור 1. סקירה כללית של גל.
פורמט ספרייה של Jack
ל-Jack יש .jack פורמט קובץ משלו שמכיל את קוד ה-dex שעבר קומפילציה מראש בספרייה, וכך מאפשר קומפילציה מהירה יותר (pre-dex).
איור 2. תוכן קובץ הספרייה של Jack.
Jill
כפי שמוצג באיור הבא, הכלי Jill מתרגם את הספריות הקיימות .jar לפורמט החדש של הספריות.
איור 3. תהליך עבודה לייבוא ספרייה קיימת של .jar.
שרת קומפילציה של Jack
בפעם הראשונה שמשתמשים ב-Jack, הוא מפעיל שרת הידור מקומי של Jack במחשב. השרת הזה:
- הוא מביא לשיפור מהירות מובנה כי הוא מאפשר להימנע מהפעלת JRE JVM חדש של המארח, מטעינת קוד Jack, מאתחול Jack ומחימום ה-JIT בכל קומפילציה. בנוסף, הוא מספק זמני קומפילציה טובים מאוד במהלך קומפילציות קטנות (לדוגמה, במצב מצטבר).
- זהו פתרון לטווח קצר לשליטה במספר ההידור של Jack במקביל. השרת מונע עומס יתר על המחשב (בעיה בזיכרון או בדיסק) כי הוא מגביל את מספר ההידור המקבילי.
שרת Jack משבית את עצמו אחרי זמן השהיה ללא קומפילציה.
הוא משתמש בשתי יציאות TCP בממשק localhost ולא זמין מבחוץ. אפשר לשנות את כל הפרמטרים (מספר הקומפילציות המקבילות, הזמן הקצוב לתפוגה, מספר היציאות וכו') על ידי עריכה של הקובץ $HOME/.jack.
קובץ $HOME/.jack
קובץ $HOME/.jack מכיל את ההגדרות הבאות למשתני שרת Jack בתחביר מלא של bash:
-
SERVER=trueמפעיל את תכונת השרת של Jack. -
SERVER_PORT_SERVICE=8072מגדיר את מספר יציאת ה-TCP של השרת למטרות קומפילציה. -
SERVER_PORT_ADMIN=8073מגדיר את מספר יציאת ה-TCP של השרת למטרות ניהול. SERVER_COUNT=1לא נמצא בשימוש.-
SERVER_NB_COMPILE=4מגדיר את המספר המקסימלי של קומפילציות מקבילות שמותרות. SERVER_TIMEOUT=60מגדיר את מספר השניות של חוסר פעילות שהשרת צריך להמתין בלי לבצע קומפילציה לפני שהוא נסגר.SERVER_LOG=${SERVER_LOG:=$SERVER_DIR/jack-$SERVER_PORT_SERVICE.log}מגדיר את הקובץ שבו נכתבים יומני השרת. כברירת מחדל, אפשר להגדיר למשתנה הזה ערך חדש באמצעות משתנה סביבה. -
JACK_VM_COMMAND=${JACK_VM_COMMAND:=java}מגדיר את פקודת ברירת המחדל שמשמשת להפעלת JVM במארח. כברירת מחדל, אפשר להחליף את הערך של המשתנה הזה באמצעות משתנה סביבה.
פתרון בעיות באוספי Jack
| בעיה | פעולה |
|---|---|
| המחשב לא מגיב במהלך ההידור או שמתרחשת שגיאה בהידור של Jack בגלל חוסר זיכרון | כדי לצמצם את מספר הקומפילציות של Jack שמתבצעות בו-זמנית, עורכים את $HOME/.jack ומשנים את SERVER_NB_COMPILE לערך נמוך יותר. |
| הקומפילציות נכשלות בגלל השגיאה Cannot launch background server (אי אפשר להפעיל שרת ברקע) | הסיבה הסבירה ביותר היא שיציאות TCP כבר נמצאות בשימוש במחשב. שינוי
היציאות על ידי עריכת $HOME/.jack (המשתנים SERVER_PORT_SERVICE ו-SERVER_PORT_ADMIN). כדי לבטל את החסימה, משביתים את שרת הקומפילציה של Jack. לשם כך, עורכים את $HOME/.jack ומשנים את SERVER ל-false. לצערנו, זה מאט באופן משמעותי את ההידור שלכם, ויכול להיות שתצטרכו להפעיל את make -j עם בקרת טעינה (אפשרות -l מתוך make). |
| הקומפילציה נתקעת בלי להתקדם | כדי לבטל את החסימה, צריך להרוג את שרת הרקע של Jack באמצעות
jack-admin kill-server) ואז להסיר את הספריות הזמניות
שנמצאות ב-jack-$USER של הספרייה הזמנית
(/tmp או $TMPDIR). |
איתור היומן של Jack
אם הפעלתם פקודת make עם יעד dist, יומן Jack נמצא במיקום $ANDROID_BUILD_TOP/out/dist/logs/jack-server.log.
אחרת, אפשר להריץ את הפקודה jack-admin server-log כדי למצוא את היומן.
במקרה של כשלים שניתן לשחזר ב-Jack, אפשר לקבל יומן מפורט יותר על ידי הגדרת המשתנה הבא:
export ANDROID_JACK_EXTRA_ARGS="--verbose debug --sanity-checks on -D sched.runner=single-threaded"
משתמשים בפקודות רגילות של makefile כדי לקמפל את העץ (או את הפרויקט) ומצרפים פלט ושגיאה רגילים. כדי להסיר יומני בנייה מפורטים, מריצים את הפקודה:
unset ANDROID_JACK_EXTRA_ARGS
מגבלות על שקעים
כברירת מחדל, רק משתמש אחד יכול להשתמש בשרת Jack במחשב. כדי לתמוך במשתמשים נוספים, בוחרים מספרי יציאות שונים לכל משתמש ומשנים את SERVER_NB_COMPILE בהתאם. אפשר גם להשבית את שרת Jack על ידי הגדרת SERVER=false ב-$HOME/.jack.
הקומפילציה של CTS איטית בגלל השילוב הנוכחי של vm-tests-tf.
אין תמיכה בכלי מניפולציה של קוד בייט (כמו JaCoCo).
שימוש ב-Jack
Jack תומך בשפת התכנות Java 1.7 ומשלב את התכונות הנוספות שמתוארות בהמשך.
Pre-dex
כשמייצרים קובץ ספרייה של Jack, ה-.dex של הספרייה נוצר ונשמר בתוך קובץ הספרייה .jack כ-pre-dex.
במהלך הקומפילציה, Jack משתמש מחדש ב-pre-dex מכל ספרייה. כל הספריות עוברות
pre-dexing.
איור 4. ספריות Jack עם קובץ pre-dex.
אם משתמשים בהקטנה, בהסתרת קוד או באריזה מחדש בהידור, Jack לא משתמש מחדש בספרייה לפני ה-dex.
קומפילציה מצטברת
קומפילציה מצטברת פירושה שרק הרכיבים שהשתנו מאז הקומפילציה האחרונה (והתלות שלהם) עוברים קומפילציה מחדש. קומפילציה מצטברת יכולה להיות מהירה משמעותית מקומפילציה מלאה, אם השינויים מוגבלים לקבוצה של רכיבים.
הקומפילציה המצטברת מושבתת כברירת מחדל (ומושבתת אוטומטית כשמופעלות האפשרויות 'הקטנה', 'הצפנה', 'אריזה מחדש' או 'multi-dex legacy'). כדי להפעיל בנייה מצטברת, מוסיפים את השורה הבאה לקובץ Android.mk של הפרויקט שרוצים לבנות באופן מצטבר:
LOCAL_JACK_ENABLED := incremental
כיווץ וערפול קוד (obfuscation)
ג'ק משתמש בקובצי הגדרה של ProGuard כדי להפעיל כיווץ והסתרה.
אלה כמה מהאפשרויות הנפוצות:
@-include-basedirectory-injars-
-outjars(יש תמיכה רק בקובץ jar אחד של פלט) -libraryjars-keep-keepclassmembers-keepclasseswithmembers-keepnames-keepclassmembernames-keepclasseswithmembernames-printseeds
אפשרויות ההקטנה כוללות:
-dontshrink
אפשרויות ההסתרה כוללות את האפשרויות הבאות:
-dontobfuscate-printmapping-applymapping-obfuscationdictionary-classobfuscationdictionary-packageobfuscationdictionary-useuniqueclassmembernames-dontusemixedcaseclassnames-keeppackagenames-flattenpackagehierarchy-repackageclasses-keepattributes-adaptclassstrings
האפשרויות שמתעלמים מהן כוללות את האפשרויות הבאות:
-dontoptimize(Jack doesn't optimize)-
-dontpreverify(ג'ק לא מבצע אימות מראש) -skipnonpubliclibraryclasses-dontskipnonpubliclibraryclasses-dontskipnonpubliclibraryclassmembers-keepdirectories-target-forceprocessing-printusage-whyareyoukeeping-optimizations-optimizationpasses-assumenosideeffects-allowaccessmodification-mergeinterfacesaggressively-overloadaggressively-microedition-verbose-dontnote-dontwarn-ignorewarnings-printconfiguration-dump
אריזה מחדש
ג'ק משתמש בקובצי תצורה של jarjar כדי לבצע אריזה מחדש. אמנם Jack תואם לסוגי כללים מסוג rule, אבל הוא לא תואם לסוגי כללים מסוג zap או keep.
תמיכה ב-multidex
Jack מציע תמיכה מובנית וגם תמיכה מדור קודם ב-multidex. מכיוון שקובצי dex מוגבלים ל-65,000 שיטות, אפליקציות עם יותר מ-65,000 שיטות צריכות להיות מחולקות למספר קובצי dex. לפרטים נוספים, אפשר לעיין במאמר בנושא הפעלת multidex באפליקציות עם יותר מ-64,000 שיטות