טיפ 105 של ג'אווה: שליטה על מסלול הכיתה עם JWhich

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

יסודות שביל

המכונה הווירטואלית של ג'אווה (JVM) מעסיקה מטעין כיתות כדי לטעון שיעורים המשמשים יישום על בסיס הצורך. CLASSPATHמשתנה הסביבה מוסר למטען בכיתה איפה למצוא צד שלישי וכיתות המוגדרים על ידי המשתמש. ניתן גם לציין את מסלול הכיתה על בסיס יישום בעזרת -classpathהארגומנט שורת הפקודה JVM , העוקף את מסלול הכיתה שצוין CLASSPATHבמשתנה הסביבה.

ערכי מסלול כיתה יכולים להיות ספריות המכילות קבצי מחלקה עבור כיתות שאינן בחבילה, ספריית שורש החבילה עבור כיתות בחבילה, או קבצי ארכיון (כגון קבצי ZIP או .jar) המכילים כיתות. ערכי מסלול כיתות מופרדים במעי הגס במערכות מסוג יוניקס ומופרדים בנקודה-פסיק במערכות MS Windows.

מעמיסי כיתות מסודרים בהיררכיית משלחות, כאשר לכל מטעין כיתות יש מטעין כיתת אב. כאשר מעמיס כיתה מתבקש למצוא כיתה, הוא מאציל תחילה את הבקשה למעמיס כיתות האם לפני שהוא מנסה למצוא את הכיתה עצמה. מעמיס מחלקות המערכת, מטעין המחלקות המוגדר כברירת מחדל המסופק על ידי JDK או JRE המותקן במערכת שלך, טוען מחלקות צד שלישי ומוגדרות על ידי משתמש באמצעות CLASSPATHמשתנה הסביבה או -classpathארגומנט שורת הפקודה JVM. מטעין מחלקות המערכת נציג למחלקת התוספות לטעינת כיתות המשתמשות במנגנון Java Extension. מעמיס מחלקות ההרחבה נציג למעמיס המחלקה bootstrap (הכסף עוצר כאן!) כדי לטעון את שיעורי הליבה JDK.

אתה יכול לפתח מעמיסי כיתה מיוחדים כדי להתאים אישית את האופן שבו JVM טוען באופן דינמי שיעורים. לדוגמא, רוב מנועי ה- servlet משתמשים במעמיס מחלקה מותאמת אישית כדי לטעון מחדש באופן דינמי כיתות servlet שהשתנו בספריות שצוינו בנתיב מחלקה מותאם אישית.

בעל חשיבות מיוחדת, וחשש רב, מטעין הכיתות יטען שיעורים לפי הסדר שהם מופיעים בכיתת הכיתה. החל מהכניסה הראשונה לכביש, מטעין הכיתה מבקר בכל ספרייה או קובץ ארכיון שצוין ומנסה למצוא את הכיתה לטעינה. המחלקה הראשונה שהיא מוצאת עם השם הנכון נטענת, ומתעלמים מכל ערכי שביל הכיתה שנותרו.

נשמע פשוט, נכון?

תחבולה בכיתה

בין אם היו מודים בכך ובין אם לאו, מפתחי ג'אווה מתחילים וותיקים כאחד נקלעו בשלב מסוים (בדרך כלל ברגע הגרוע ביותר!) על ידי שביל הכיתה המכביד. מכיוון שמספר המחלקות התלויות המוגדרות על ידי צד שלישי ומוגדר על ידי משתמש עבור יישום, ודרך הכיתה הופכת לשטח השלכה לכל ספרייה וקובץ ארכיון שאפשר להעלות על הדעת, לא תמיד ברור מאיזה מחלקה יטען תחילה מטעין המחלקות. זה נכון במיוחד במקרה האומלל כי שביל הכיתה מכיל ערכי כיתה כפולים. זכרו, מטעין הכיתה טוען את הכיתה הראשונה ששמה כהלכה שהוא מוצא בשביל הכיתה ובאופן "מסתיר" את כל שאר המחלקות בעלי השמות הנכונים בעלי עדיפות תחתונה.

קל מדי ליפול קורבן לתחבולות השבילים האלה. אחרי יום ארוך של עבדות על מקלדת חמה, אתה מצרף ספרייה לשביל הכיתה בניסיון להשיג את הגרסה האחרונה והגדולה ביותר של מחלקה לטעינה ביישום, תוך שאינך מודע לכך שגרסה אחרת של הכיתה ממוקמת בספריה של עדיפות גבוהה יותר בכיתה. Gotcha!

JWich: כלי פשוט של מסלול כיתה

בעיית הקדימות הטמונה בהצהרת מסלול שטוח אינה ייחודית בשביל הכיתה ג'אווה. כדי למצוא פיתרון לבעיה נדרש רק שתעמוד על כתפי ענקיות התוכנה האגדיות. whichהפקודה של מערכת ההפעלה יוניקס לוקחת שם ומציגה את שם הנתיב של הקובץ שיבוצע לו הוצא השם כפקודה. למעשה הוא חוצה את PATHמשתנה הסביבה כדי לאתר את המופע הראשון של הפקודה. זה נשמע כמו כלי רב עוצמה לניהול שביל Java בכיתה. בהשראת הרעיון הזה, התחלתי לכתוב כלי עזר של Java שיכול לקחת שם מחלקה של Java ולהציג את שם הנתיב המוחלט של קובץ הכיתה שנטען מחלק הכיתה, כפי שנקבע על ידי שביל הכיתה.

השימוש בדוגמה הבאה JWhichמציג את שם הנתיב המוחלט של ההתרחשות הראשונה של com.clarkware.ejb.ShoppingCartBeanהמחלקה שנטען המחלקה, שבמקרה נמצא בספריה:

 > java JWhich com.clarkware.ejb.ShoppingCartBean Class 'com.clarkware.ejb.ShoppingCartBean' נמצא ב '/home/mclark/classes/com/clarkware/ejb/ShoppingCartBean.class' 

השימוש הבא בדוגמה JWhichמציג את שם הנתיב המוחלט של ההתרחשות הראשונה של javax.servlet.http.HttpServletהמחלקה שנטען על ידי מטען המחלקות, שבמקרה ארוז בקובץ ארכיון:

 > java JWich javax.servlet.http.HttpServlet Class 'javax.servlet.http.HttpServlet' נמצא 'קובץ: /home/mclark/lib/servlet.jar! /javax/servlet/http/HttpServlet.class' 

איך JWhich עובד

כדי לקבוע באופן חד משמעי איזו מחלקה תוטען תחילה בכיתה, עליכם להיכנס למוחו של מעמיס הכיתה. זה לא כל כך קשה כמו שזה נשמע - אתה פשוט שואל את זה! קוד המקור הרלוונטי JWhichלהלן. לקבלת קוד המקור המלא, ראה משאבים.

1: מחלקה ציבורית JWhich {2: 3: / ** 4: * מדפיס את שם הנתיב המוחלט של קובץ הכיתה 5: * המכיל את שם המחלקה שצוין, כפי שנקבע 6: * על ידי שביל הכיתה הנוכחי. 7: * 8: * @param class שם שם הכיתה. 9: * / 10: חלל סטטי ציבורי אשר (String className) {11: 12: if (! ClassName.startsWith ("/")) {13: className = "/" + className; 14:} 15: className = className.replace ('.', '/'); 16: className = className + ".class"; 17: 18: java.net.URL classUrl = 19: JWhich חדש (). GetClass (). GetResource (className); 20: 21: אם (classUrl! = Null) {22: System.out.println ("\ nClass '" + className + 23: "' נמצא ב- \ n '" + classUrl.getFile () + "'"); 24:} אחר {25: System.out.println ("\ nClass '" + className + 26: "' לא נמצא ב- \ n '"+ 27: System.getProperty (" java.class.path ") +" '"); 28:} 29:} 30: 31: main static public ריק (String args []) {32: if (args.length > 0) {33: JWhich.which (args [0]); 34:} אחר {35: System.err.println ("שימוש: java JWhich"); 36:} 37:} 38:}

ראשית, עליך לעסות מעט את שם הכיתה כדי לקבל קבלה של מעמיסי כיתה (שורות 12-16). הצבת "/" לשם הכיתה מורה למטען הכיתה להתאים את שם הכיתה במילה במסלול הכיתה, במקום לנסות לתלות באופן מרומז את שם החבילה של הכיתה המזמינה. ממיר כל מופע של "." כדי "/" מעצב את שם הכיתה כשם משאב URL חוקי הנדרש על ידי מטעין הכיתה.

לאחר מכן, מעמיס הכיתה נחקר (שורות 18-19) עבור המשאב התואם לשם הכיתה המעוצב כהלכה. כל Classאובייקט שומר על התייחסות לאובייקט שטען ClassLoaderאותו, ולכן מטעין הכיתה שהעמיס את JWhichהמחלקה עצמה נחקר כאן. Class.getResource()השיטה בעצם צירי המטעין בכיתה שנטען הכיתה, חזרת URL לקריאת משאב הקובץ בכיתה, או nullאם משאב קובץ בכיתה עם שם מחלקה שצוין לא נמצא בבית classpath הנוכחי.

לבסוף, שם הנתיב המוחלט של קובץ המחלקה המכיל את שם המחלקה שצוין, אם הוא נמצא בנתיב הכיתה הנוכחי (שורות 21-24). כעזר ניפוי באגים, אם קובץ המחלקה לא נמצא בנתיב הכיתה הנוכחי, אתה מקבל את הערך של java.class.pathמאפיין המערכת כדי להציג את שביל הכיתה הנוכחי (שורות 24-28).

קל לדמיין כיצד ניתן להפעיל נתח קוד פשוט זה ב- servlet Java באמצעות מסלול הכיתה של מנוע ה- servlet או ב- Enterprise JavaBean (EJB) באמצעות מסלול הכיתה של שרת EJB. אם JWhichהמחלקה הועמסה על ידי מטעין המחלקה המותאמת אישית במנוע סרוולט, למשל, מטעין המחלקות של מנוע הסרוולט ישמש למציאת מחלקות. אם מעמיס הכיתה של מנוע הסרוולט אינו מצליח לאתר מחלקה, הוא יאציל למעמיס האם שלו. באופן כללי, כאשר JWhichהוא נטען על ידי מטעין כיתות, הוא מסוגל למצוא את כל הכיתות הנטענות על ידי מטעין הכיתות שלו או כל מטעין כיתת אב.

סיכום

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

מייק קלארק הוא יועץ עצמאי של Clarkware Consulting, המתמחה בארכיטקטורה מבוססת Java, עיצוב ופיתוח באמצעות טכנולוגיות J2EE. לאחרונה סיים פיתוח ופריסה של שרת חילופי XML בין עסקים לעסקים (B2B) וכיום הוא יועץ לפרויקט לבניית מוצר לניהול ביצועים J2EE.

למידע נוסף על נושא זה

  • השג את קוד המקור המלא של מאמר זה

    //images.techhive.com/downloads/idge/imported/article/jvw/2000/12/jwhich.zip

  • גרסה כוללת של JWhich, כולל מאמת מסלול כיתה, זמינה בכתובת

    //www.clarkware.com/software/jwhich.zip

  • ניתן למצוא תיעוד רשמי ל- Sun JDK וכיצד הוא מתמודד עם מסלול הכיתה לפלטפורמות השונות הנתמכות רשמית

    //java.sun.com/j2se/1.3/docs/tooldocs/findingclasses.html

  • לפרטים על אופן הגדרת מסלול הכיתה בפלטפורמות יוניקס ו- Windows, ראה "הגדרת מסלול הכיתה" בכתובת:
  • יוניקס

    //java.sun.com/j2se/1.3/docs/tooldocs/solaris/classpath.html

  • חלונות

    //java.sun.com/j2se/1.3/docs/tooldocs/win32/classpath.html

  • צפו בכל הטיפים הקודמים של Java והגישו משלכם

    //www.javaworld.com/javatips/jw-javatips.index.html

  • במשך יותר טריקים Java, להירשם בחינם של ITworld.com Java מורה ניוזלטר

    //www.itworld.com/cgi-bin/subcontent12.cgi

  • התבטא בדיון למתחילים של Java בהנחיית סופר JavaWorld Geoff Friesen

    //www.itworld.com/jump/jw-javatip105/forums.itworld.com/[email protected]@.ee6b804/1195!skip=1125

סיפור זה, "Java Tip 105: Mastering the classpath with JWhich" פורסם במקור בהוצאת JavaWorld.