במאמר הזה נסביר איך לעבור מ-Maven אל Bazel, כולל הדרישות המוקדמות ושלבי ההתקנה. הוא מתאר את ההבדלים בין Maven לבין Bazel ומספק דוגמה להעברה באמצעות פרויקט Guaba.
בזמן המעבר מכל כלי build ל-Bazel, עדיף להפעיל את שני הכלים המקבילים בו-זמנית עד שצוות הפיתוח, מערכת ה-CI וכל מערכת רלוונטית אחרת תעברו ביניהם. אתם יכולים להריץ את Maven ואת Bazel באותו מאגר.
לפני שמתחילים
- התקנת Bazel אם היא עדיין לא מותקנת.
- אם אין לכם ניסיון קודם ב-Bazel, קראו את המדריך Bazel: Build Java לפני שתתחילו את ההעברה. המדריך מסביר את התפיסות, המבנה והסינונים של התוויות של בזל.
הבדלים בין Maven לבין Bazel
- Maven משתמש ב-
pom.xmlקבצים ברמה העליונה. מאחר ש-Bazel תומכת במספר קובצי build ויעדים מרובים לכל קובץ ב-BUILD, כך שגרסאות build הן מצטברות יותר מ-Maven'. - Maven אחראי על השלבים של תהליך הפריסה. Bazel לא מבצעת אוטומציה של הפריסה.
- Bazel מאפשרת לך להביע תלות בין שפות.
- כשמוסיפים קטעים חדשים לפרויקט, עם Bazel ייתכן שתצטרכו להוסיף קובצי
BUILDחדשים. השיטה המומלצת היא להוסיף קובץBUILDלכל חבילת Java חדשה.
מעבר מ-Maven ל-Bazel
השלבים הבאים מתארים כיצד להעביר את הפרויקט שלך ל-Bazel:
הדוגמאות הבאות נובעות מהעברה של פרויקט גויאבה מ- Maven ל-Bazel.
פרויקט גויאבה שבו נעשה שימוש הוא גרסה v31.1. הדוגמאות לשימוש בגוואבה לא מפורטות בכל שלב בתהליך ההעברה, אבל הן מציגות את הקבצים ואת התוכן שנוצרו או נוספו באופן ידני בהעברה.
$ git clone https://github.com/google/guava.git && cd guava
$ git checkout v31.1
1. יצירת קובץ WORKSPACE
יוצרים קובץ בשם WORKSPACE (root) של הפרויקט. אם לפרויקט אין תלויות חיצוניות, קובץ Workspace לא יכול להיות ריק.
אם הפרויקט תלוי בקבצים או בחבילות שלא נכללות באחת מהספריות של הפרויקט, יש לציין את התלות החיצוניות החיצוניות בקובץ Workspace. כדי להגדיר באופן אוטומטי תלויות חיצוניות לקובץ Workspace, משתמשים ב-rules_jvm_external. להוראות על השימוש בערכת כללים זו, קראו את README.
דוגמה לפרויקט פרויקט גויאבה: יחסי תלות חיצוניים
אפשר לציין את יחסי התלות החיצוניים של פרויקט גויאבה באמצעות הכלל rules_jvm_external.
יש להוסיף את קטע הקוד הבא לקובץ WORKSPACE:
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
RULES_JVM_EXTERNAL_TAG = "4.3"
RULES_JVM_EXTERNAL_SHA = "6274687f6fc5783b589f56a2f1ed60de3ce1f99bc4e8f9edef3de43bdf7c6e74"
http_archive(
name = "rules_jvm_external",
sha256 = RULES_JVM_EXTERNAL_SHA,
strip_prefix = "rules_jvm_external-%s" % RULES_JVM_EXTERNAL_TAG,
url = "https://github.com/bazelbuild/rules_jvm_external/archive/%s.zip" % RULES_JVM_EXTERNAL_TAG,
)
load("@rules_jvm_external//:defs.bzl", "maven_install")
maven_install(
artifacts = [
"com.google.code.findbugs:jsr305:3.0.2",
"com.google.errorprone:error_prone_annotations:2.11.0",
"com.google.j2objc:j2objc-annotations:1.3",
"org.codehaus.mojo:animal-sniffer-annotations:1.20",
"org.checkerframework:checker-qual:3.12.0",
],
repositories = [
"https://repo1.maven.org/maven2",
],
)
2. יצירת קובץ BUILD אחד
עכשיו, אחרי שסביבת העבודה שלכם מוגדרת ותלויות חיצוניות (אם רלוונטי), אתם צריכים ליצור BUILD קבצים כדי לתאר את אופן הבנייה של הפרויקט. בניגוד ל-Maven עם קובץ pom.xml יחיד, בזל יכולה להשתמש
בקבצים רבים של BUILD כדי לבנות פרויקט. הקבצים האלה מציינים כמה יעדים לבנייה, כך ש-Bazel יכולה ליצור גרסאות מצטברות.
הוספת BUILD קבצים בשלבים. תוכלו להתחיל להוסיף קובץ BUILD לרמה הבסיסית (root) של הפרויקט ולהשתמש בו כדי ליצור גרסת build ראשונית באמצעות Bazel.
לאחר מכן אפשר לצמצם את ה-build על ידי הוספה של עוד BUILD קבצים עם יעדים מפורטים יותר.
באותה ספרייה של קובץ ה-
WORKSPACE, תוכלו ליצור קובץ טקסט ולתת לו שםBUILD.בקובץ
BUILDהזה השתמשו בכלל המתאים כדי ליצור יעד אחד כדי לבנות את הפרויקט. ריכזנו בשבילכם כמה טיפים:משתמשים בכלל המתאים:
כדי ליצור פרויקטים עם מודול Maven יחיד, יש להשתמש בכלל
java_libraryבאופן הבא:java_library( name = "everything", srcs = glob(["src/main/java/**/*.java"]), resources = glob(["src/main/resources/**"]), deps = ["//:all-external-targets"], )כדי ליצור פרויקטים עם מספר מודולים של Maven, יש להשתמש בכלל
java_libraryבאופן הבא:java_library( name = "everything", srcs = glob([ "Module1/src/main/java/**/*.java", "Module2/src/main/java/**/*.java", ... ]), resources = glob([ "Module1/src/main/resources/**", "Module2/src/main/resources/**", ... ]), deps = ["//:all-external-targets"], )כדי ליצור קבצים בינאריים, יש להשתמש בכלל
java_binary:java_binary( name = "everything", srcs = glob(["src/main/java/**/*.java"]), resources = glob(["src/main/resources/**"]), deps = ["//:all-external-targets"], main_class = "com.example.Main" )
מציינים את המאפיינים:
name: נותנים ליעד שם משמעותי. בדוגמאות שלמעלה, היעד נקרא "everyinging."srcs: משתמשים בגלובוסים כדי לרשום את כל קובצי ה-Java בפרויקט.resources: באמצעות כדור הארץ כדי לפרט את כל המשאבים בפרויקט.deps: צריך לקבוע אלו יחסי תלות חיצוניים צריכים להיות בפרויקט שלכם. לדוגמה, אם יצרתם רשימה של יחסי תלות חיצוניים באמצעות הכליgenerate_workspace, התלויות עבורjava_libraryהן הספריות המפורטות במאקרוgenerated_java_libraries.
בדוגמה הבאה ניתן לראות את קובץ ה-BUILD ברמה העליונה שהועבר מהפרויקט בגואבה.
עכשיו יש לכם קובץ
BUILDברמה הבסיסית (root) של הפרויקט, ובנו את הפרויקט כדי לוודא שהוא פועל. בשורת הפקודה, מספריית העבודה שלך, השתמשו ב-bazel build //:everythingכדי לבנות את הפרויקט שלכם עם Bazel.הפרויקט נבנה בהצלחה עם Bazel. יהיה עליך להוסיף עוד
BUILDקבצים כדי לאפשר גרסאות מצטברות של הפרויקט.
דוגמה לפרויקט גויאבה: התחלה עם קובץ BUILD אחד
בעת העברת פרויקט הגואבה לבזאל, תחילה נעשה שימוש בקובץ BUILD אחד לבניית הפרויקט כולו. אלו התכנים של קובץ BUILD הראשוני הזה בספריית Workspace:
java_library(
name = "everything",
srcs = glob([
"guava/src/**/*.java",
"futures/failureaccess/src/**/*.java",
]),
deps = [
"@maven//:com_google_code_findbugs_jsr305",
"@maven//:com_google_errorprone_error_prone_annotations",
"@maven//:com_google_j2objc_j2objc_annotations",
"@maven//:org_checkerframework_checker_qual",
"@maven//:org_codehaus_mojo_animal_sniffer_annotations",
],
)
3. יצירת קובצי BUILD נוספים (אופציונלי)
מאחר ש-Bazel פועלת רק עם BUILD file אחת, כפי שראיתם אחרי שסיימתם את הבנייה הראשונה. כדאי לשקול לפצל את המבנה לחלקים קטנים יותר על ידי הוספה של עוד BUILD קבצים עם יעדים מפורטים.
קובצי BUILD מרובים עם יעדים מרובים מגדילים את רמת הפירוט, מה שמאפשר:
- מספר גרסאות מצטברות של הפרויקט,
- הרצה מקבילה של ה-build,
- ניהול שוטף של ה-build עבור משתמשים עתידיים
- שליטה על החשיפה של יעדים בין חבילות, שעלולה למנוע בעיות כגון ספריות המכילות פרטי יישום שדלפות לממשקי API ציבוריים.
טיפים להוספת BUILD קבצים:
- אפשר להתחיל על ידי הוספת קובץ
BUILDלכל חבילת Java. התחילו עם חבילות Java שיש להן את התלות הנמוכה ביותר ועובדות עד לחבילות התלויות ביותר. - כשמוסיפים
BUILDקבצים ומציינים יעדים, יש להוסיף את היעדים החדשים לקטעים מתוךdepsיעדים שתלויים בהם. חשוב לשים לב שהפונקציהglob()לא חוצה גבולות של חבילה, ולכן מספר החבילות מתרחב –glob()יתכווץ. - בכל פעם שמוסיפים קובץ
BUILDלספרייהmain, יש להוסיף קובץBUILDלספרייה המתאימה ב-test. - יש להקפיד להגביל את החשיפה בצורה נכונה בין חבילות.
- כדי לפשט את הבעיות בפתרון בעיות בהגדרת הקבצים של
BUILD, צריך לוודא שהפרויקט ממשיך לפעול ב-Bazel בזמן ההוספה של כל קובץ build. מומלץ להפעיל אתbazel build //...כדי לוודא שכל היעדים עדיין נוצרים.
4. בונים באמצעות Bazel
בונים באמצעות Bazel בזמן שמוסיפים BUILD קבצים לאימות ההגדרה של ה-build.
אם יש לכם BUILD קבצים ברמת הפירוט הרצויה, תוכלו להשתמש ב-Bazel כדי ליצור את כל גרסאות ה-build.