ארבעה דברים טובים שנוספו עם Java 7

כבר נשמעה הרבה ביקורת, על כמה מעט נוסף במשך חמש וטיפה שנות הפיתוח (או יותר נכון: דיונים) – של ג\’אווה 7.
אם גלעד שליט ידע ג\’אווה לפני שנחטף – אז הוא חזר לסביבה מוכרת וחסרת הפתעות.

סיכמתי כמה דברים חיוביים לאלו שיעברו ל Java 7, במקרה או בכוונה, ששווה להכיר:
פחות צורך במשמעת עצמית ב Exception Handling
Java נבנתה בצורה שתקל על המפתח להמנע משגיאות, הפחזבל (Garbage Collector) חסך מיליוני שנות פרך של debug וחיפוש אחר זליגות זכרון. בכל זאת, חברה שלא אנקוב בשמה, שילמה 17 מיליון דולר השתתפות בנזקים של הלקוח בעקבות הבאג הבא (חפשו אותו):

  Connection conn = null;
  Statement stmt = null;
  try {
    conn = connectionPool.getConnection();
    stmt = conn.createStatement();
    // Do the lookup logic
    // return a list of results
    } finally {
      if (stmt != null) {
        stmt.close();
      }
      if (conn != null) {
        conn.close();
    }
  }

אני מניח שהבאג לא צועק, הקוד נראה במבט ראשון מסודר ונכון. אבל מה – אם ()stmt.close יזרוק exception (בגלל מנגנון ה keep alive  של Oracle?), ה connection לא יתנקה וכשפעולה זו תחזור שוב ושוב, Oracle יסרב לקבל עוד קריאות. במערכת Mission Critical המשמעות היא לבצע restart לבסיס הנתונים כל מספר דקות, חוסר יכולת לעבוד, יום בטלה לעובדים והפסד אדיר ללקוח.

הפתרון הוא לעטוף ב try-catch נוספים (ה catch יישאר כנראה ריק) את קריאות ה ()close של stmt ו conn. זה היה ה best practice שדרשנו ממפתחים לעשות, שוב ושוב, וברגשות מעורבים.

איך מוודאים שבקשה זו תיושם בפועל? ביצוע תחוף של Code Reviews, הגדרת המודעות בקרב המפתחים ובארגון שעובד נכון – בניית Connection Pool שיודע לזרוק Connections בשעת לחץ.
בג\’אווה 7 ניתן לכתוב את הקוד הבא:

  try (Connection conn = connectionPool.getConnection();
       Statement stmt = conn.createStatement()) {
    // Do the lookup logic
    // return a list of results
    } catch {
      // respond to exception

    }

  }


שדואג ש conn ו stmt ייסגרו, אם לא שווים ל null ולמרות exceptions שיכולים להזרק. הוא מקביל לקוד הארוך והמכוער שתארתי למעלה. נחמד!

פחות חזרה חזרה חזרה ב catch statement
תופסים שלושה סוגי Exception ורוצים לעשות אותו הדבר?
מעכשיו כתבו:

} catch (IOException | SQLException | SQLStatementException ex) {
  log.warn(ex);
  throw ex;
}
המשתנה ex יתייחס לסוג ה Exception (מתוך השלושה) שנזרק. יופי.

Performance Profiling: שחרור VistualVM
אם תחפשו בתוך ספריית Bin ב JDK שהורדתם, תגלו שיושב לו שם Profiler בשם VisualVM. מלבד כך שהוא חינמי, מתחבר לכל ה IDEs החשובים (עם plugin) ויש לו ממשק משתמש נחמד, הוא מספק נקודת איזון מאוד מוצלחת של פשוטות מול עוצמה. הוא ידידותי – אבל גם אינו צעצוע. הוא יכול להספיק לרוב משימות ה profiling הנפוצות, גם בתוך tomcat, ואינו דורש הגדרות מיוחדות לJVM או לשרת שאתם עובדים איתו.

כדי לוודא שאתם משתמשים בגרסה החדשה ביותר חפשו כאן. בזמן כתיבת הפוסט הגרסה העדכנית היא 1.3.3.

נ.ב. – אופס, תפסתם אותי. VisualVM מסופק החל ממרץ כבר ב JDK 1.6 ואינו חידוש של Java 7. בכלל הוא יכול לעבוד (תחת מגבלות) עם אפילקציות שקומפלו ב JDK1.4. הוספתי אותו לכאן מכיוון שהוא תוספת מכובדת ל JDK שקל לפספס בגלל שיצא ב update ולא ב major release.

גרסה חדשה – מספר חדש
סימן חיים, ג\’אווה עדיין קיימת! זה לא דבר גדול אבל, (סרקזם קל) זה בהחלט אחד השינויים הבולטים בגרסה שקיבלנו.

בהצלחה!

האם Java גוססת?

כבר בסביבות שנת 2008 התחיל לצבור תאוצה הקרב על הירושה: איזו שפה תחליף את שפת Java? אם היה קרב לרשת את סטלין בעודו בחיים, מחנות החינוך מחדש בסיביר היו מקבלים מספר חברים חדשים לשורותיהם, אבל שפת Java עם הקהילה הפתוחה שלה, היא רחוקה מאוד מדיקטטורה*. אחת התלונות הקשות על Java היא הקצב האיטי בו גוף התקינה של Java מקבל החלטות. JDK 1.7 יצא לאחר חמש שנים ולא כלל שיפורים יוצאי דופן. C#, שפה מאוד דומה, מציגה שיפורים משמעותיים (לדוגמה LINQ, closures) באופן תדיר.

האם צריך להחליף את Java? מה רע בה?
if it’s not broken – don’t touch it!” יאמרו רבים.
if it’s ain’t broke – break it” יענו המהפכנים. “חובה עלינו לחפש שיפורים כל הזמן”, בתרגום חופשי. “ואם נוח לנו במצב הקיים, אדרבא”
התלונות העיקריות לגבי Java הן הבאות:

שפה  verbose (מרבה במילים) ומסורבלת.
יש אינספור דוגמאות של: 10 שורות בג’אווה, 4 שורות ב X (שפה אחרת) . דברים מרגיזים כוללים:

  • Checked exceptions
  • Java Beans (הסינטקסט המסורבל של getXXX/setXXX שהופך משפטים לקשים לקריאה)
  •  הצורך לכתובanonymous class  בכדי להעביר פונקציה פשוטה כפרמטר (שפות אחרות פשוט נותנת להקליד את הקוד הרצוי במקום הנכון)

גוף התקינה הוא שמרן ואיטי.

“מדוע היה צריך לחכות לג’אווה 7 בכדי שמשפט switch יוכל לקבל String?” היא תלונה נפוצה וקלה להבנה (אך קצת קטנונית). הבעיה האמיתית היא ריבוי ה cores שהפך למציאות תיכנותית, וחוסר היכולת של Java להתאים את עצמה למציאות החדשה. Fork-Join שהגיע באיחור ולא יושב יפה בתוך השפה ו Actors (בדקו בתחתית הפוסט בבלוג זה להסבר על Actors) שמתכנתי Java אוספים משדות זרים.

האם שפה שהיא verbose (מרבה במילים) משפיעה באופן משמעותי על פריון המתכנתים? השאוות הראו שלספריות העומדות לרשות המפתח, ה IDE, ניסיון והכישרון של המפתח יש השפעה גדולה מהשפה עצמה. רק אסמבלי (ואולי קצת קובול) נשארה משמעותית מאחור (מקור: ספר Code Complete) אני מכיר היטב את הטענה שכתיבה ברובי או פייטון היא הרבה יותר מהירה אך אין לזה חיזוק אמפירי. הסיכוי לטעויות בשפות אלה בגלל שאין בדיקת קומפיילר מפצה לרעה על ה syntax הקליל. אני מניח שזו עניין של הרגשה ואולי מתכנתים מעולים שלא צריכים קומפיילר (שמעתי TDD?) באמת כותבים מהר יותר בשפות סקריפט. 
בואו נתבונן בשני האלמנטים האובייקטיבים (לא תלוי במתכנת) שכן משפרים את הפריון, וכיצד השפות החדשות יכולות להתמודד מול Java:
1.כלים – auto-complete, קומפיילר טוב, Refactoring וכו’. כל שפה חדשה שמוצגת לשוק מהר מאוד מייצרת כלים בסיסיים (לפחות syntax highlighting ו auto-complete), קשה לשכנע שהשפה שלך תקצר זמני פיתוח אם אתה אמור לעבוד ב Notepad. כל מערכות ה IDE המרכזית (Eclipse, VS, IntelliJ ו NetBeans) בנויות להרחבה ותמיכה בשפות נוספות.
2.  ספריות – האם עלייך לכתוב ספריית Scheduling בעצמך, או שאתה מוריד את Quartzומתחיל לעבוד? ב C++ לא היו הרבה ספריות משותפות, אולי בגלל שהיו קומפיילרים שונים למערכות הפעלה שונות. ברגע שJava הציגה את “Write Once, Run Everywhere“** – כמות הספריות הזמינות להורדה (ובחינם) נערמה והפכה לכוחה הגדול של Java – ה Community. אז איך מציגים שפה עם 0 ספריות מול Java עם אלפי ספרות בדוקות ובוגרות? רובי הצליחה להתרומם בעזרת Rails – ספרייה חדשנית ומוצלחת במיוחד לפיתוח אפליקציות Web (וגם בעזרת שפה מוצלחת בפני עצמה, כמובן) – אבל זה לא הספיק. ואז – נתגלתה השיטה: ב JDK 1.6, ה JVM – Java Virtual Machine הורחב לתמוך ב JavaScript שיתקמפל ל Byte Code – וירוץ בצד השרת. לצורך העניין נעשו שינויים שאפשרו ל JVM לתמוך בתכונות של שפה דינמית (כלומר פונקציה היא evaluated רק ברגע שצריך להריץ אותה, שמאפשר לתוכנה לבצע שינויים עד אותו הרגע). הסכר נפרץ ושפות רבות קפצו על ה JVM: בוגר, יעיל, מוצלח,highly optimized, עם התקנה לעשרות מערכות הפעלה ואולי הכי חשוב – היכולת  להשתמש באופן טבעי בכל מאגר ספריות הJava הקיימות. אפילו שפות שהיה להן Virtual Machine – פיתחו וריאציה עבור ה JVM.
 
היכן המהפכה?
אוקיי, אז עברו שלוש שנים, וJavaעדיין כאן. השפות שעשו זינוק בשנה האחרונה הן דווקא LUA ו F# – שאינן קשורות ל JVM. השפות המדוברות תופסות הרבה נפח בכנסים ובבלוגים, אך עדיין הנוכחות שלהן סה”כ קטנה.
ברוכים הבאים לעולם העסקי (ניתן לומר: האמיתי). מקום שבו טכנולוגיה טובה לא מבטיחה הצלחה, מקום שבו שיתופי פעולה והרגלים הם בעלי כוח מכריע.
הדעיכה של Java כנראה התחילה, אבל Java לא עתידה להעלם סתם כך. הייתי מעריך שיעברו עוד שנים רבות עד שJava תחשב כשפה לא רלוונטית. כמות הקוד הקיים, הספרות והכי חשוב – האנשים שמושקעים באופו אישי בJava הוא עצום והוא לא יעלם סתם כך. (בעולם הJVM) תמיכת ה IDE בJava היא עדיין הטובה ללא עוררין, וכך גם כמות החומר הלימודי. יתרונות השפות המדוברות – הן עדיין הדרגתיות וצריך סיבה טובה כדי לעשות מעבר.למשל: אם יש לי בעיות Concurrency קשות באמת, אני יכול לכתוב מודול ב Scala, לייצר .jar ולצרף אותו לפרוייקט הJava הקיים.

ישנו Pattern ידוע בתעשייה: כאשר טכנולוגיה מתיישנת, בעלי העניין המושקעים בה מוצאים דרכים שונות ומשונות להאריך את חייה. Java לא צפויה להיות שונה: אם תתחיל עזיבה משמעותית מJava אוקל תכניס במהירות כמה שינויים שישאירו את Java אופציה מספיק טובה, כך ש”תסחוב” עוד כמה שנים.

אז מה אנחנו לומדים ? למרות שJava בנסיגה אטית – אתם יכולים ללכת לישון בשקט: לא תתעוררו מחר לעולם-ללא-ג’אווה. בכל זאת מעניין להכיר על מה המהומה, בניתי רשימה קצרה של השפות הבולטות בזמן כתיבת הפוסט:

Scala  – כנראה המתמודדת הבולטת ביותר. משלבת אלמנטים פונקציונליים ו Object Oriented. מאפשרת גם תכנות דינמי (כמוJavaScript  או רובי) אבל גם Static Typing – כלומר הקומפיילר יתפוס לכם את רוב הבעיות. הייחוד שלה היא ההצלחה לשלב פרדיגמות שונות בצורה מוצלחת והתכנות מהיסוד לשפה לתכנות מקבילי. היא תהיה יחסית נוחה למתכנת Java, C++ או C# אבל תציע הרבה כוח ואפשרויות שלא היו זמינות בשפות אלה.
Groovy– שפה מגניבה, שכוללת אלמנטים של python Syntax ותאימות רבה לJava. קוד Java ללא שינוי צפוי להתקמפל בגרובי ב 95% מהמקרים. נעשתה עבודה לא כ”כ מסודרת בפרטים – וכבר יצאה גרובי++ שמטפלת בכמה מהבעיות. הביאה לעולם את Grails שזה העתק של Rails של רובי, ואת Griffon – שזו גרסת ה Desktop לאותה ארכיטקטורה. נראתה מועמדת מובילה לפני שנתיים-שלוש (בעיקר בעקבות backward compatibility), אך לאחר שהמפתח שלה הצהיר “אם הייתי מכיר את סקאלה – לא הייתי טורח לפתח את גרובי” גורלה כנראה נחרץ.
JRuby– רובי היא רביזיה Pure-Object-Oriented של שפת Python מתחילת שנות ה-90 שהוזכרה קודם. יש לה את ספריית Rails שזכתה להצלחה רבה. JRuby היא פשוט מאוד גרסת ה של רובי JVM, שילוב שגרם לרובי לרוץ מהר הרבה יותר. יש לה מומנטום חזק כ”כ בעולם ה web – כך שנראה שהיא כאן בכדי להשאר. השאלה בעיקר היא האם תתפשט מחוץ ל Web UI לכיוונים אחרים.
Closure– מין LISP מודרני, דינאמי ופונקצינאלי. גמישה מאוד ביכולת הביטוי. משפט אחד בלתי-קריא יכול להיות שקול ל 10 שורות בכל שפה אחרת. האם זה ייתרון? אם אתם באקדמיה, אוהבים קדרים וקודרים (המבין יבין) – לבריאות. אני לא נהנה לקרוא אותה ואיני מבין על מה המהומה. 
Jython – פייטון (ע”ש להקת מונטי-פייטון, כדרך אגב) היא הותיקה בשפות, אפילו ותיקה מ Java. מאז הצלחת Java ירדה מהכותרות אך חזרה אליהן לאחרונה, אולי גם בגלל Jython ה porting ל JVM. היא פחות סקסית וחדישה, אך יש בעולם הרבה מאוד קוד פייטון ומתכנתי פייטון (יותר מרובי, למשל) בעוד שרובי תפסה את הנישה הוובית, פייטון נשארה general purpose. באופן אישי, אני מכיר בעיקר סקריפטים וכלים שכתובים בה ומעט מוצרים ולכן יש לי רושם שנתוני השימוש היבשים קצת מזייפים. כמו לשאול כמה מתכנתי Bash יש בעולם…המצב הקיים:

< הלינק מת… היה כאן תרשים של אחוזי השימוש בשפות JVM שונות + לאורך זמן >

 
לסיכום: קרב הירושה בעיצומו ועוד עשוי להמשך זמן רב. לא חייב להיות בהכרח מנצח אחד. הJVM  יאפשר למספר שפות לחיות זו לצד זו, כאשר כל אחת תוכל להתמקד בנישה שלה. 
Java עשתה את שלה, עכשיו ה JVM הוא העיקר.
* מאז שאורקל, חברה דיי כוחנית, לקחה שליטה על Java היא הצליחה בעיקר להבריח מפתחים מקהילת המפתחים של Java ולייצר תביעות שונות, בחשד להפרת פטנטים של Java. היא ניסתה לדלל את כוחה של הקהילה הפתוחה, אך עם הצלחה מוגבלת.
** Java לא הייתה המערכת הראשונה שרצה על מערכות שונות: פייטון הגיע לשם כמה שנים מוקדם ממנה עם Virtual Machine משלה. מה שהכריע את הכף הוא כנראה ש Java קסמה למפתחי ה C++ (שהיו אז הרוב) בכך שאימצה תחביר דומה וגם תמיכה גורפת מגופי ענק כמו IBM, אורקל, SUN ועוד.