סקירת JNDI, חלק 1: מבוא לשירותי שמות

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

TEXTBOX: TEXTBOX_HEAD: סקירה JNDI: קרא את כל הסדרה!

  • חלק 1. מבוא לשירותי שמות
  • חלק 2. השתמש בשירותי ספריית JNDI כדי לנהל טוב יותר את היישומים המופצים שלך

  • חלק 3. השתמש ב- JNDI לאחסון אובייקטים של היישום המבוזר שלך

  • חלק 4. חבר יחד את מה שלמדת עם יישום התומך ב- JNDI: END_TEXTBOX

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

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

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

החודש אני מציג את ממשק Java Naming and Directory (JNDI). JNDI מספק ממשק מכנה משותף להרבה שירותי שמות קיימים. ככזו, JNDI לא תוכננה להחליף את הטכנולוגיה הקיימת; במקום זאת, הוא מספק ממשק משותף לשירותי שמות קיימים. נתחיל במבט על כמה משירותים אלה.

מבוא לשירותי שמות

האיור שלהלן מתאר את הארגון של שירות שמות כללי.

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

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

  • שמות COS (Common Object Services): שירות שמות ליישומי CORBA; מאפשר ליישומים לאחסן ולגשת להפניות לאובייקטים של CORBA.

  • DNS (מערכת שמות תחומים): שירות שמות האינטרנט; ממפה שמות ידידותיים לאנשים (כגון www.etcee.com) לכתובות IP ידידותיות למחשב (פרוטוקול אינטרנט) בסימון מרובע מנוקד (207.69.175.36). מעניין ש- DNS הוא שירות שמות מבוזר , כלומר השירות ומסד הנתונים הבסיסי שלו מפוזרים על פני מארחים רבים באינטרנט.

  • LDAP (פרוטוקול גישה קלה לספריות): פותח על ידי אוניברסיטת מישיגן; כשמו כן הוא, מדובר בגרסה קלה של DAP (Directory Access Protocol), שבתורו הוא חלק מ- X.500, תקן לשירותי ספריות רשת. נכון לעכשיו, למעלה מ- 40 חברות תומכות ב- LDAP.

  • NIS (מערכת מידע רשת) ו- NIS +: שירותי שמות רשת שפותחו על ידי Sun Microsystems. שניהם מאפשרים למשתמשים לגשת לקבצים ויישומים בכל מארח עם מזהה וסיסמא יחיד.

תכונות נפוצות

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

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

JNDI מספק ממשק התומך בכל הפונקציונליות הנפוצה הזו. אציג ממשק זה בהמשך מאמר זה.

ההבדלים ביניהם

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

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

ב- DNS שמות בנויים מרכיבים המופרדים באמצעות נקודות ("."). הם קראו מימין לשמאל. השם "www.etcee.com" מכנה מכונה בשם "www" בתחום "etcee.com". כמו כן, השם "etcee.com" שם הדומיין "etcee" בתחום העליון "com".

ב- LDAP המצב מעט יותר מורכב. שמות בנויים מרכיבים המופרדים באמצעות פסיקים (","). כמו שמות DNS, הם קוראים מימין לשמאל. עם זאת, יש לציין רכיבים בשם LDAP כצמדי שם / ערך. השם "cn = טוד סונדסטד, o = ComFrame, c = US" שם את האדם "cn = Todd Sundsted" בארגון "o = ComFrame, c = US." כמו כן, השם "o = ComFrame, c = US" שם את הארגון "o = ComFrame" במדינה "c = US."

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

JNDI solves this problem with the Name class and its subclasses and helper classes. The Name class represents a name composed of an ordered sequences of subnames, and provides methods for working with names independent of the underlying naming service.

A look at JNDI naming

As I mentioned above, it's important to remember that JNDI is an interface rather than an implementation. This fact has some disadvantages -- you need access to an existing naming service (such as an LDAP service) and you need to understand something about how it works in order to play with JNDI. On the other hand, it does allow JNDI to integrate seamlessly into an existing computing environment where an established naming service holds sway.

JNDI naming revolves around a small set of classes and a handful of operations. Let's take a look at them.

Context and InitialContext

The Context interface plays a central role in JNDI. A context represents a set of bindings within a naming service that all share the same naming convention. A Context object provides the methods for binding names to objects and unbinding names from objects, for renaming objects, and for listing the bindings.

Some naming services also provide subcontext functionality. Much like a directory in a filesystem, a subcontext is a context within a context. This hierarchical structure permits better organization of information. For naming services that support subcontexts, the Context class also provides methods for creating and destroying subcontexts.

JNDI performs all naming operations relative to a context. To assist in finding a place to start, the JNDI specification defines an InitialContext class. This class is instantiated with properties that define the type of naming service in use and, for naming services that provide security, the ID and password to use when connecting.

For those of you familiar with the RMI Naming class, many of the methods provided by the Context interface outlined below will look familiar. Let's take a look at Context's methods:

  • void bind(String stringName, Object object): Binds a name to an object. The name must not be bound to another object. All intermediate contexts must already exist.

  • void rebind(String stringName, Object object): Binds a name to an object. All intermediate contexts must already exist.

  • Object lookup(String stringName): Returns the specified object.

  • void unbind(String stringName): Unbinds the specified object.

The Context interface also provides methods for renaming and listing bindings.

  • void rename(String stringOldName, String stringNewName): Changes the name to which an object is bound.
  • NamingEnumeration listBindings(String stringName): Returns an enumeration containing the names bound to the specified context, along with the objects and the class names of the objects bound to them.

  • NamingEnumeration list(String stringName): Returns an enumeration containing the names bound to the specified context, along with the class names of the objects bound to them.

Each of these methods has a sibling that takes a Name object instead of a String object. A Name object represents a generic name. The Name class allows a program to manipulate names without having to know as much about the specific naming service in use.

The example

The example below illustrates how to connect to a naming service, list all of the bindings, or list a specific binding. It uses the filesystem service provider, which is one of the reference JNDI service-provider implementations provided by Sun. The filesystem service provider makes the filesystem look like a naming service (which it is, in many ways -- filenames like /foo/bar/baz are names and are bound to objects like files and directories). I selected it because everyone has access to a filesystem (as opposed to, say, an LDAP server).

import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.Binding; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import java.util.Hashtable; public class Main { public static void main(String [] rgstring) { try { // Create the initial context. The environment // information specifies the JNDI provider to use // and the initial URL to use (in our case, a // directory in URL form -- file:///...). Hashtable hashtableEnvironment = new Hashtable(); hashtableEnvironment.put( Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory" ); hashtableEnvironment.put( Context.PROVIDER_URL, rgstring[0] ); Context context = new InitialContext(hashtableEnvironment); // If you provide no other command line arguments, // list all of the names in the specified context and // the objects they are bound to. if (rgstring.length == 1) { NamingEnumeration namingenumeration = context.listBindings(""); while (namingenumeration.hasMore()) { Binding binding = (Binding)namingenumeration.next(); System.out.println( binding.getName() + " " + binding.getObject() ); } } // Otherwise, list the names and bindings for the // specified arguments. else { for (int i = 1; i < rgstring.length; i++) { Object object = context.lookup(rgstring[i]); System.out.println( rgstring[i] + " " + object ); } } context.close(); } catch (NamingException namingexception) { namingexception.printStackTrace(); } } } 

The program in the listing above first creates an initial context from the specified JNDI provider (in this case, Sun's filesystem provider) and a URL specifying a local directory. If no additional command-line arguments are specified, the program lists the objects and names of every entity in the specified directory. Otherwise, it lists the objects and names of only those items specified on the command line.

Conclusion

You should now have both an understanding of and an appreciation for naming services in general and JNDI in particular. In distributed environments, they are valuable tools for locating information and resources. JNDI makes it possible to work with a variety of naming services without having to master a multitude of APIs. Next month, we'll take a look at the other half of JNDI -- its directory functions.

טוד סונדסטד כותב תוכניות מאז שהמחשבים זמינים בדגמי שולחן עבודה נוחים. אף על פי שבמקור היה מעוניין לבנות יישומים מבוזרים ב- C ++, עבר טוד לשפת התכנות ג'אווה כשהפכה לבחירה המתבקשת לסוג כזה. בנוסף לכתיבה, טוד עובד גם כארכיטקט ג'אווה עם תוכנת ComFrame.

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

  • הורד את קוד המקור השלם למאמר זה, בפורמט zip

    //images.techhive.com/downloads/idge/imported/article/jvw/2000/01/jw-01-howto.zip

  • כל הדברים JNDI

    //java.sun.com/products/jndi/

  • תיעוד JNDI

    //java.sun.com/products/jndi/docs.html

  • ספקי שירות זמינים כרגע

    //java.sun.com/products/jndi/serviceproviders.html

  • רשימה מלאה של עמודות הוראות Java קודמות

    //www.javaworld.com/javaworld/topicalindex/jw-ti-howto.html

סיפור זה, "סקירת JNDI, חלק 1: מבוא לשירותי שמות" פורסם במקור על ידי JavaWorld.