Name Services

52
COMMON SERVICES FOR DISTRIBUTED ENTERPRISE COMMUNICATIONS Naming Services Directory and Trading Services Activation Services Messaging Services Transaction Services

description

 

Transcript of Name Services

COMMON SERVICES FOR DISTRIBUTEDENTERPRISE COMMUNICATIONS

Naming Services

Directory and Trading Services

Activation Services

Messaging Services

Transaction Services

Naming Services

• Naming Services in a Nutshell• JNDI Naming Services• Naming Files• CORBA Naming• RMI Naming• DNS• DCOM Naming

A naming service is the principal mechanism used in distributed and nondistributed systems for referring to objects from within your applications via a name identifying that object.

The term name used here typically means a name that is human readable or at least easily converted into a human-readable String format.

A file system uses filenames when doing out references associated with file media to programs requesting access to those files.

Similarly, CORBA clients can use object names to obtain handles to CORBA objects, which reference objects that may be sitting in some remote system process. These name-to-object associations are referred to as name bindings.

A name binding is always defined relative to a naming context. Here, a naming context encapsulates a domain of names in which each name binding in that naming context is unique.

use a naming service to either explicitly or implicitly bind object references to names and resolve names to objects. The Java Naming and Directory Interface (JNDI) component of the J2EE is described as the primary means for hooking into naming systems from enterprise Java applications.

To learn:Naming service–related concepts such as compound and

composite names, name bindings, naming contexts, and the common roles of a name service.

The architecture, API components, and use of Java's framework for commonly accessing various naming services via the Java Naming and Directory Interface.

Why a file system is a naming service and how to use JNDI to access your file system.

The architecture of a CORBA Naming Service (CosNaming) and the access of aCosNaming Service via JNDI.

How to access the RMI Registry via JNDI.How to use JNDI with RMI/IIOP.The architecture of the Internet's domain name system

(DNS) and how to look up an IP address given a DNS name.

The DCOM equivalent for implementing the role of a naming service.

Naming Services in a NutshellNaming services provide a way for you to

write code that refers to objects in a system using human-readable names. Names very often have a string form enabling you to write code that is more readable, as well as providing you with a simple way to obtain an initial handle to an object.

Handles, names, and the context in which names are scoped are all fundamental concepts relevant to an understanding of naming systems.

HandlesAn object in a system corresponds to an instance in

memory or some range of addresses relating to some discrete collection of functions or data. "Handles" to such objects are often referred to as references or pointers

Such handles can be associated with objects residing in a process local to your current execution environment or with distributed machine.

Handles are often not human readable, frequently are numeric by nature, perhaps have some embedded communications protocol-specific information, sometimes are platform-dependent, and usually are dependent on the current execution environment.

NamesA name is simply a logical and generally human-readable

value for referring to an object in both distributed and nondistributed systems. Here are some examples of what a name can be:A filename string referring to a file object reference.An Internet hostname string referring to a machine on the

Internet.An object service name referring to a CORBA server object on a

remote machine.Each name is expressed in a syntax understandable by the

naming system for which it is relevant (for example, the file system, the Internet, a CORBA Naming Service). Each naming system has its own naming convention syntax for which valid names are expressed.

Thus, for example, a Windows file-naming system requires absolute filenames to be expressed in terms of a root drive and semicolon with directory names separated by backslashes (\) and ending with a filename and extension (for example, C:\MyDir\myFile.txt)

Each name- to-object association is typically referred to as a name binding.

For example, given the object instance name hallwayPrinter from

NetworkPrinter hallwayPrinter = new NetworkPrinter();

Naming Contexts and Systems

Names always have some meaning in a specific context. For example, the name "Leesburg"designates a U.S. city in the states of Virginia, New Jersey, Florida, Georgia, Alabama, Indiana, and Ohio. The fully qualified name of "Leesburg, Virginia, USA" pinpoints the name "Leesburg" to the context of "Virginia, USA."

The same need for referring to names within some context also applies to computer systems.

Figure 1. Naming systems

In Figure 1, whereas the name index.html on your computer hosting a Web server refers to a specific file you have created in the directory C:\public_html, this same filename in your Web server's directory C:\public_html\sales refers to an entirely different file object. The name index.html has to be put in context to determine what specific file object is being referenced.

Each context thus holds a set of name-to-object bindings in which the object may be an actual system resource (for example, file object) or perhaps another context (that is, a subcontext). Each context will have its own standard for naming the objects and subcontexts to which it binds names.

A naming system serves to provide a standard for managing a set of contexts with the same naming convention and with similar means for binding names to objects and resolving objects to names.

Many systems such as the Lightweight Directory Access Protocol (LDAP), the Network Information System (NIS), and the Novell Directory Service (NDS) provide the name binding and resolving functionality of naming services

JNDI Naming Services

The Java Naming and Directory Interface (JNDI) provides a standard Java interface-to- naming system that can be used with various types of underlying naming systems. JNDI can also be used to name and reference objects that lie outside of a particular naming system.

Furthermore, JNDI also provides interfaces for encapsulating and handling events that can be generated from a naming service.

JNDI Architecture

As depicted in Figure 2, JNDI is a Java extension and a fundamental component of the

J2EE, providing a standard way to interface with many naming services and directory services.

JNDI provides a Java API for commonly interfacing with any naming or directory service for which there exists an adapter to map JNDI API calls to the specific calls provided by the particular naming or directory service provider.

All calls to the JNDI API are properly delegates to the particular service via the adapter. This adapter is referred to as a Service Provider Interface (SPI). SPIs are provided by Sun Microsystems

The JNDI class libraries are included as a core component of the J2EE and the J2SE v1.3.

The JNDI class libraries are partitioned into the following packages:

• javax.naming: Contains all the core JNDI API classes and interfaces used by Java applications needing access to various naming services.

• javax.naming.directory: Contains the JNDI API classes for performing more sophisticated directory-service functionality extending the basic naming-service functionality.

• javax.naming.event: Contains the JNDI API classes and interfaces for providing event notification services for naming and directory systems.

• javax.naming.ldap: Contains the JNDI API classes and interfaces for specific support of the more advanced management features of the LDAPv3 standard when using the LDAP SPI.

• javax.naming.spi: Contains the JNDI SPI classes and interfaces for implementers of SPIs to map standard JNDI API calls to a particular naming or directory service.

Naming ObjectsBefore a naming service can be utilized, JNDI clients need

to obtain handles to an initial JNDI context. Names can then be bound to objects, and objects can be looked up relative to such a context using standard JNDI interfaces.

Names have a syntax that can be described using regular Java String objects or using some of the interfaces provided by JNDI to encapsulate names.

JNDI Contexts The JNDI client API user will first be required to create a

reference to an initial context of the naming service of interest.

This initial context creation process establishes a connection with the service when constructed with a set of properties describing the specific naming or directory service provider library to use, the URL of the naming or directory service process, and perhaps a username and user credentials.

Other properties may also be set whose names are defined as static public attributes in the javax.naming.Context interface. A javax.naming.InitialContext class implementing the Context interface can be used to create an actual handle to a particular naming service. The valid static public properties are defined in Table 1.

Out of all properties defined in Table 1, the first two properties (INITIAL_CONTEXT_FACTORY and PROVIDER_URL) will probably be the most commonly used properties in your programs. The creation of an InitialContext is therefore typically straightforward:

Properties properties = new Properties();properties.setProperty(Context.INITIAL_CONTE

XT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");

properties.setProperty("PROVIDER_URL", "file:C:\\public_html"); Context context = new InitialContext(properties);

Surround the context closing within a finally block to ensure that it is called:

try{…}catch(…){…}finally{try{context.close();}catch(NamingException ex){…}}

Subcontexts can be created and removed using the InitialContext createSubcontext() and destroySubcontext() methods, respectively. Subcontexts can be looked up by using the lookup() method, with the subcontext name defined according to whatever naming convention is employed to separate components of the name,such as this:

Context salesBrochureContext = context.lookup("sales\\brochures");

JNDI Binding and Lookup After a context reference is obtained, an object from the

server side can be bound to the context in a standard fashion using the bind() and rebind() methods.

The difference between bind() and rebind() is simply that rebind() overwrites any existing bindings, whereas bind() throws an exception. As an example of a rebind call, we have this:

String eProducts = "eProducts.html";Brochure eProductBrochure = new Brochure();…salesBrochureContext.rebind(eProducts, eProductBrochure);

From the client side, a lookup of a particular object yields a reference to that object which is simply cast to the object of the appropriate type:

String eProductsName = "sales\\brochures\\eProducts.html"; Brochure brochure = (Brochure) context.lookup(eProductsName);

JNDI NamesBinding objects to names and looking up objects given a

name can be accomplished using a String form of a name, as well as using a class implementing the javax.naming.Name interface.

A Name is composed of a sequence of name components. Name objects provide a more type-safe means to manipulate names according to the syntax convention of the particular naming system with which the name is associated.

One can add and remove name components as well as accomplish other helper operations on names given a Name interface implementation.

The CompoundName class implements the Name interface for names that are confined within a single hierarchical naming system.

A set of properties can be passed into the CompoundName constructor. These are the valid properties that can be passed into the CompoundName constructor:

jndi.syntax.direction: Parsing direction such as left_to_right, right_to_left, or flat.

jndi.syntax.separator: Separator to use between name components (for example, / or .).

jndi.syntax.ignorecase: Name components are case-insensitive if true. jndi.syntax.escape: Escape string for overriding separators (for

example, /). jndi.syntax.beginquote: Beginning of quote delimiter. jndi.syntax.endquote: Ending of quote delimiter. jndi.syntax.beginquote2: Alternative begin quote. jndi.syntax.endquote2: Alternative end quote. jndi.syntax.separator.typeval: Name-value separators (for example, = as

in mfg=Dodge). jndi.syntax.separator.ava: Name-value pair separator (for example, , as

in mfg=Dodge,make=Raider,color=red). jndi.syntax.trimblanks: Leading and trailing whitespace of a name is

trimmed if true.

For example, the following String may be parsed into a compound name using theCompoundName class:

String name = "PrinterPublicGroup.Printer19";CompoundName cName = new CompoundName(name,

rmiNamingProperties);

JNDI Context ListingsThe contents of a JNDI naming service may also be listed using

the list() and listBinding() methods defined by the Context interface and implemented by InitialContext.

The list() method requires a name parameter identifying the particular context level at which to search for name service bindings. The list() method returns a javax.naming.NamingEnumeration of javax.naming.NameClassPair objects in which each NameClassPair represents an object name and its classname of an object bound at the desired context level. For example (exception handling excluded)

NamingEnumeration namesList = context.list(someContextName);

…while(namesList.hasMore()){NameClassPair pair = (NameClassPair) namesList.next();

String objectName = pair.getName();String className = pair.getClassName();…}

In addition to returning the object name and its associated classname, the listBindings() method call on a context returns the actual bound object as well. Given the particular context level to list, the listBindings() method returns a NamingEnumeration of javax.naming.

Binding objects that extend NameClassPair objects with the capability to store and retrieve the object bound at the listed context level.

For example, to retrieve each name, classname, and bound object from a NamingEnumeration returned from a listBindings() call, we would use this:

NamingEnumeration namesList = context.listBindings(someContextName);

…while(namesList.hasMore()){Binding binding = (Binding) namesList.next();String objectName = binding.getName(); String className =

binding.getClassName();MyObject obj = (MyObject) binding.getObject();…}

Referenceable ObjectsAside from binding and looking up object references in a

naming system using names via JNDI, JNDI also provides support for binding and looking up references to objects that sit somewhere outside of the naming system (that is, referenceable objects).

A referenceable object, in JNDI lingo, is an object with a reference that can be stored in a JNDI service with information telling JNDI how to associate lookups for that object to the object itself.

Referenceable objects can be useful when an object not belonging to any particular naming system needs to be bound to a naming service for ease of lookup. Referenceable objects are also useful when an object from one naming system needs to be bound to an entirely different naming system.

A referenceable object is first created by implementing the javax.naming.Referenceable interface. The Referenceable interface has one method called getReference(), which returns a handle to a javax.naming.Reference object.

For example, some com.beeshirts.customer.Customer class that you've defined may implement the getReference() method as shown here:

public javax.naming.Reference getReference()throws NamingException{String className = "com.beeshirts.customer.Customer";String factoryName =

"com.beeshirts.customer.CustomerFactory"; String contents = this.getAsString(); // Get state as a String

javax.naming.StringRefAddr refAddr= new javax.naming.StringRefAddr("Customer",

contents);return new javax.naming.Reference(className, refAddr,

factoryName, null);}

After binding the Customer referenceable object, the naming service can reconstruct the object during a lookup by consulting the com.beeshirts.customer.CustomerFactory object factory implementing the getObjectInstance() method like this (excluding error handling):

public Object getObjectInstance(Object obj, Name objName,Context objContext, Hashtable objEnv) throws Exception{ javax.naming.Reference reference = (javax.naming.Reference)

obj; javax.naming.StringRefAddr refAddr= (javax.naming.StringRefAddr) reference.get("Customer");String contents = (String) refAddr.getContent(); Customer

customer= new Customer();customer.setAsString(contents); // Reconstructs state from a

String

return customer;}

Naming Events JNDI also now provides (as of JNDI v1.2) an infrastructure for

encapsulating and handling naming and directory service events. Naming and directory services can generate naming- related events such as the renaming of an object, the removal or addition of an object from or to the naming service, and the state change of an object registered with the naming service.

The javax.naming.event.NamingEvent class represents an event that can be generated from a naming service when one of its registered objects changes. NamingEvent objects extend the standard java.util.EventObject; they have a type and contain an event source, SPI-specific change information, and a reference to binding information both before and after the event.

The source of an event is a context implementing the javax.naming.event.EventContext interface. An EventContext is simply a type of Context that allows for the addition and removal of listeners interested in naming events. A special javax.naming.event.

NamingExceptionEvent event object can also be generated in the event of a failure during the generation of a normal naming event for notifying naming listeners

EventContext eventContext = // Construct an event context NamespaceChangeListener customerManager = // Construct a listener eventContext.addNamingListener("AllisonPerrone",EventContext.OBJECT_SCOPE, customerManager);

Either the javax.naming.event.ObjectChangeListener or the javax.naming.event. NamespaceChangeListener sub-interfaces of NamingListener typically is implemented to handle generated naming events.

The ObjectChangeListener interface is implemented to handle events associated with an object's state change (NamingEvent.OBJECT_CHANGED), such as attribute addition, deletion, or modification, as well as the replacement of an object in the naming system.

The NamespaceChangeListener interface is implemented by those objects wanting to handle the addition (NamingEvent.OBJECT_ADDED), removal (NamingEvent. OBJECT_REMOVED), or renaming (NamingEvent.OBJECT_RENAMED) of objects registered with the naming service.

As an example of a naming event listener, the following skeleton structure implements methods for handling both object change and namespace change naming events:

import javax.naming.event.NamespaceChangeListener; import javax.naming.event.ObjectChangeListener; import javax.naming.event.NamingEvent; import javax.naming.event.NamingExceptionEvent; public class SampleNamingListener implements NamespaceChangeListener, ObjectChangeListener {public void objectAdded(NamingEvent namingEvent) { // Handle object addition }public void objectRemoved(NamingEvent namingEvent) { // Handle object removal }public void objectRenamed(NamingEvent namingEvent) { // Handle object renaming }public void objectChanged(NamingEvent namingEvent) { // Handle object attribute changing }public void namingExceptionThrown(NamingExceptionEvent namingExceptionEvent) {// Handle naming exception }}

Naming Files

The file-naming system is the most basic and common naming system that computer users encounter. In a file-naming system, filenames correspond to the names of the naming service, file-system directories correspond to the contexts that make up names, and the file objects and descriptors correspond to the handles of the system resource of interest.

Different file systems will have different naming syntax conventions. Thus, whereas Windows-based file systems use the backslash (\) to separate context-space (that is, directories) and components of a name, UNIX-based systems use the forward slash (/). Similarly, Windows- based systems ignore differences between upper- and lowercase, whereas UNIX-based systems are case-sensitive.

File-System Interfaces

Figure 19.6. Traditional Java file-system interfaces.Before JNDI, the most common and obvious way to

interact with a file system was to use the classes available in the java.io package, as shown in Figure 6. The Java 2.0 platform has provided many enhancements to the java.io package, including a host of new methods added to the java.io.File class.

The File class encapsulates an interface to a file system's files and directory paths. Operations such as file renaming and deleting, as well as directory listing, can be achieved via the File class. The FileInputStream and FileOutputStream classes can be used to create new files, as well as populate such files with data or reading files. The FileReader and FileWriter classes can also be used to read and write character files.

JNDI File SPI

A file-system SPI exists for use with the JNDI API and is freely downloadable from the Sun Web site. Many developers may still elect to use the core Java support for file manipulation via use of the file streaming and reader/writer APIs provided in the java.io package.

In fact, the JNDI file SPI provided by Sun actually heavily depends on the java.io.File class. However, use of a JNDI file-system SPI has its advantages by providing classes and interfaces for making file management more flexibly independent across different file-system types (depending on your underlying SPI implementation), as well as providing a standard interface to the file system that can be used even in a composite naming scheme.

CORBA NamingThe OMG's CORBA Naming Service (also called Object

Naming Service and CosNaming) presents the primary and standard way for mapping between names and objects on a CORBA ORB.

The Object Naming Service was proposed by the OMG as a means to provide a standard interface to various underlying naming services.

It serves as the language-independent and standard way to wrap existing name servers for connectivity from various clients.

Although the JNDI API has some similarities to the Java mapping of the CORBA Naming Service API, it is not identical. your Java client will use JNDI with a CORBA SPI that maps calls to a CORBA name server. The server in turn actually maps CORBA Naming calls to a naming service that could have been directly communicated with from your Java application

CosNaming IDLNames in CORBA are sequences of name components. A name with a single component is referred to as a simple name,

whereas a name with more components is called a compound name.

Name components are defined by an ID and a kind. The "kind" attribute of a name simply serves to classify names for use by application software. Each ID is unique within a particular naming context.

Naming contexts in CORBA contain a list of names that are all unique to that context in which each binding has a binding type indicating whether the name is bound to either a CORBA object or another naming context, do not need to be associated with logical names.

Operations on naming contexts include binding and rebinding names to objects, resolving objects given a name, unbinding objects, creating subcontexts, and listing names associated with the context.

The CosNaming module shown in Listing 4 defines the CORBA Naming Service IDL interfaces.

The CORBA Naming Service specification also provides for the efficient representation of names with a names library pseudo-IDL (PIDL) specification as shown in Listing 5.

The names library is implemented in the CORBA client's native language. These client-side libraries provide the client with a lightweight means for manipulating names in which the names actually refer to CORBA pseudo-objects

CosNaming Service Implementations

The CORBA name service used "CORBA Communications," and "RMI Communications," was the transient name service that comes equipped with Java IDL and RMI/IIOP.

The command tnameserv is used to start the CosNaming-compliant name service on a particular machine on the default port 900.

The command-line flag -ORBInitialPort <PortNum> may also be used to run the name service on a different port number.

From within your CORBA client and server applications, a handle to the name service can be retrieved using the org.omg.CORBA.ORB.resolve_initial_references() method.

If the name service is run on a new port number other than the default, naming-service clients must set the org.omg.CORBA.InitialPort property associated with the ORB object.

The term transient is used in referring to the tnameserv naming service to highlight the fact that all name/object binding information is lost whenever the naming service terminates. Other naming-service options do exist, however.

Most commercial CORBA vendors provide Java- based, CosNaming-compliant naming services such as these:

IONA Technologies'OrbixWeb Orbix Names(http://www.iona.com/products/orbix/names.html)Inprise's VisiBroker Naming Service(http://www.borland.com/visibroker/cosservices/)Prism Technologies'OpenFusion Naming Service(http://www.prismtechnologies.com/products/

openfusion/products/naming -service.html)

CORBA Naming InterfacesFigure 7 presents the key programmatic interfaces

to a CosNaming service. Only key components are shown; the helpers and holders associated with the various interfaces are not shown to simplify the diagram.

By narrowing an initial reference to the NameService returned from the ORB, we can obtain a handle to a NamingContext interface like this:

ORB orb = ORB.init(args,null);org.omg.CORBA.Object namingRef =orb.resolve_initial_references("NameService");NamingContext namingContext =

NamingContextHelper.narrow(namingRef);

A CORBA server can then be registered from the server side by first creating a

NameComponent array (that is, a CORBA name) and calling bind() or rebind() on the NamingContext reference as such:

MyMessageImpl server = new MyMessageImpl();NameComponent nameComponent = new NameComponent("SampleServer", "");NameComponent nameComponent1 = new NameComponent("SampleServer2", ""); NameComponent path[] = {nameComponent , nameComponent1 }; namingContext.rebind(path, server);

A CORBA client obtains an initial reference to a naming service in the same fashion as a CORBA server. The CORBA client can then use the naming context to look up the object reference given the CORBA name as shown here:

NameComponent nameComponent = new NameComponent("SampleServer", ""); NameComponent nameComponent1 = new NameComponent("SampleServer2", ""); NameComponent path[] = { nameComponent , nameComponent1 };MyMessage obj = MyMessageHelper.narrow(namingContext.resolve(path));

JNDI CosNaming SPIA CosNaming JNDI SPI exists as part of the J2EE v1.2 and can

also be downloaded separately for use with the J2SE v1.2. When you interface with the CosNaming service directly, you need to understand a host of CosNaming-specific APIs.

By using JNDI with a CosNaming SPI, you are provided with a standard way (as a Java developer) to interact with a host of naming-service interfaces, and thus it is not necessary to learn all the semantics specific to CosNaming.

The Sample.idl file in Listing 6 exports a simple "Hello-World" sample method embedded inside of a Message interface. The SampleCosNamingServer of Listing 7 implements this interface and also registers the server with a CosNaming server via JNDI.

After a Message server is bound to two different names from within the SampleCosNamingServer.bindWithDifferentNames() method, the SampleLookupExample, SampleListAndSearchExample, and SampleBindingExample programs are all run to illustrate usage of the generic JNDI API with a CosNaming system.

RMI NamingRMI also has a means to bind objects to names and look up object

references via a name. As we saw "RMI Registration" and "RMI Lookup," both RMI/JRMP and RMI/IIOP had distinct ways to communicate with a naming service. Of course, RMI/IIOP used the CosNaming service interfaces. RMI/JRMP used the built-in RMI Registry interfaces.

RMI Naming System InterfacesThe RMI Registry provides a simple mechanism for interfacing with

a naming service, but it is dependent on RMI/JRMP, which is a Java-centric means for distributing objects.

RMI/IIOP uses a CosNaming server, and thus you can both create RMI/IIOP clients to communicate with CORBA servers implemented in another language and implement RMI/IIOP servers that can offer their services to a language-independent community of CORBA clients.

The CosNaming service that implements the CORBA Naming Service interface and supports the special ORB extensions required of RMI/IIOP.

JNDI RMI SPIAn RMI Registry JNDI SPI that works with RMI/JRMP is

shipped with J2EE products and is separately downloadable for use with the J2SE v1.2.

RMI/IIOP-based applications can use a CosNaming JNDI SPI. Because our sample RMI/IIOP applications are dependent on the tnameserv CosNaming service provided with RMI/IIOP, our RMI/IIOP applications also depend on use of the CosNaming SPI provided by Sun to work with the tnameserv CosNaming service.

The Sample.java RMI interface in Listing 8 exports a simple "Hello-World" example RMI method implemented by both the RMI/JRMP server (SampleJRMPServerUsingNamingContext) of Listing 9 and the RMI/IIOP server (SampleRMIIIOPServer) of Listing 10.

DNS No JNDI SPI for the domain name service existed. This section thus

focuses on a description of the DNS and describes existing intermediate means for Java applications to perform some minimal DNS name management functionality. The level of support via Java is currently limited to half-baked, simple lookups.

The Domain Name System The DNS provides a translation of the hierarchically defined

machine hostnames that we are all familiar with (for example, www.yahoo.com) to and from IP addresses (for example, 204.71.200.68).

DNS names have a syntax convention and map to IP addresses that are logical addresses of network devices or hosts. These IP addresses are used by network routing elements to determine how to deliver IP-based messages to a host machine.

By using human-readable and structured names, the task of the developer is simplified and less dependent on a priori knowledge of the internals of routing tables and machine configurations.

The names in DNS adhere to the syntax convention of case-insensitive name components separated by dots (.). Parsing of the names occurs from right to left with the rightmost name component corresponding to a top-level domain context. Many organizations use the set of top-level domain names presented in Table 2.

Additionally, a country code can also serve as a top-level domain name, such as the code US for United States–based organizations. Names are then created according to this standard format:

<Entity Name>.<Locality>.<State Code>.USFor example AssuredTech.Leesburg.VA.US

A subdomain is prepended to a top-level domain name with a dot as a separator to formulate a "registered" domain name. Thus, yahoo.com is a registered domain with yahoo as the subdomain and com as the top-level domain.

Regionally designated authority to grant "registered" domain names is provided by Internet Resource Registries such as with Network Solutions, Inc.'s management of all .com, .net, and .org top-level domains.

An organization that has registered a domain name with an Internet Resource Registry can then create various subdomains for the registered domain name. These subdomains can be organized in any way according to the organization's liking such as sales.myCorp.com and products.myCorp.com. Hostnames for machines within these subdomains can then be assigned. Thus, joeSalesman.sales.myCorp.com and elPresidente.myCorp.com

<Hostname>.< Optional One or More Dot-Separated SubDomains>.<Registered Domain Name>

A DNS server can run DNS software offered by various COTS packages on various platforms.

A popular implementation for UNIX systems is the Berkley Internet Name Domain (BIND) package, which has also been ported to Windows platforms (http://www.isc.org/bind.html).

Each host in the domain must be configured to know the IP addresses of the local DNS servers or be configured to refer to a Dynamic Host Configuration Protocol (DHCP) to help locate the local DNS servers.

When a TCP/IP request is made with a hostname, the TCP/IP protocol consults the DNS server with which it has been configured to look up the IP address with the associated hostname. If a DNS server cannot resolve a hostname to an IP address, it forwards the request to another DNS server.

Java-Based DNS Interfacing

The primary way to interact with the DNS via Java right now is by use of the java.net.InetAddress class to look up an IP address given a hostname. Three static methods defined on InetAddress can be used to return InetAddress object instances:

InetAddress getByName(String hostName) returns a handle to an InetAddress object given an IP Address in the form X.X.X.X (for example, 209.207.135.133) or a machine name String (for example, http://www.assuredtech.com).

InetAddress[] getAllByName(String hostName) returns a handle to an array of all known InetAddress objects for a particular hostName defined as in the getByName() call.

InetAddress getLocalHost() returns a handle to an InetAddress object for your local host machine.

After an InetAddress object is returned, the following calls can be used to obtain host naming and IP address information for use by your applications:

String getHostName() returns a String defining the hostname associated with this IP address by performing a DNS lookup.

String getHostAddress() returns a String containing the IP address in the form X.X.X.X.

byte[] getAddress() returns a byte array of the IP address in network order with byte[0] as the most significant byte.

Thus, the InetAddress.getHostName() call is where the DNS lookup really transpires. All three static InetAddress methods and the getHostName() method map to native calls from your Java platform implementation to your specific machine's DNS TCP/IP client libraries.

DCOM NamingAlthough DCOM provides APIs that do support naming of DCOM

classes and some support for stateful DCOM object naming, the mapping of these APIs to Java-based programs has produced a somewhat cumbersome, DCOM-equivalent naming service interface.

DCOM Class Naming with CLSIDs and ProgIDs DCOM Class Identifiers (CLSIDs) are used to uniquely identify a

particular DCOM class. The DCOM class identified by a CLSID refers to a collection of DCOM interfaces implemented by that class.

The DCOM com.ms.win32.Ole32.CoCreateInstance() API call uses this CLSID when looking up and registering DCOM objects with the Microsoft Windows Registry.

Java-based DCOM server objects can be registered for distributed access using the javareg utility with the /surrogate parameter.

The Java-based DCOM server also needs to be defined with a static final CLSID String . General DCOM clients can obtain a pointer to the DCOM object using the CLSID passed as a parameter to the CoCreateInstance() DCOM API call.

Java-based DCOM clients using the Microsoft JVM can simply instantiate an instance of the DCOM object (for example, QueryManager ) with the new operator and then cast the object to a DCOM interface (for example, IQueryManager ):

IQueryManager query = (IQueryManager) new com.beeshirts.QueryManager();

The casting to a particular interface by the client also cues the Microsoft JVM to call QueryInterface() to determine whether such an interface is supported by this DCOM class and to obtain the interface reference.

The Windows Registry stores the hostname of the remote implementation, as well as the remote implementation classname used during a call to CoCreateInstance(). Direct calls to the CoCreateInstanceEx() call permit passing of a particular hostname.

The COM libraries make calls to the Service Control Manager (SCM) to activate the remote object. The SCM on the client machine makes a call to the SCM on the server machine. The server SCM then uses COM libraries to activate the remote object and return the remote reference.

Program identifiers (ProgIDs) can be used to define a human-readable name for a DCOM class. ProgIDs follow the format <Program>.<Component>.<Version>.

The DCOM com.ms.win32.Ole32. CLSIDFromProgID() API call takes ProgIDs that map to CLSIDs. Such a CLSID can then be used with the CoCreateInstance() API call to obtain a handle to the object as shown here:String name = "QueryManager.Application";myGuid = // set appropriate Guid typetype = // set type of COM Servercom.ms.com._Guid objCLSID = com.ms.win32.Ole32.CLSIDFromProgID(name);Object comObject =

com.ms.win32.Ole32.CoCreateInstance(objCLSID, null, type, myGUID);

DCOM Object Naming with MonikersCLSIDs and ProgIDs are useful only for registering and

looking up DCOM classes and interfaces. Because DCOM objects are stateless by default, a different mechanism is needed in order to register actual stateful object instances to be retrieved later by a distributed DCOM client. To a certain extent, DCOM monikers provide this capability.

Monikers in DCOM can be used to obtain a handle to an object previously created.The interface used to define a moniker is the com.ms.com.IMoniker interface, as shown in Listing 11.

If a client has a handle to an IMoniker interface, the client can refer to an existing server. The IMoniker object consults the COM libraries'running object table (ROT) to find an underlying reference to the actual running server. If IMoniker can not find a server in the ROT, it will create a handle to a new one from a persistent store. IMoniker objects derive from a com.ms.com.IPersistStream object and can be persisted themselves.

The BindToObject() call on an IMoniker object executes the bind to a stateful DCOM object. Some predefined IMoniker objects are equipped with the COM libraries. Of course, the semantics of the BindToObject() call are specific to the object implementing the IMoniker interface.

IMonikers can also be associated with a binding context similar to the fashion in which names can belong to a naming context. IMoniker objects have human-readable display names retrievable from the GetDisplayName() call. Displayed moniker names are of this general form:<TypeName>:<InstanceName>.

The ParseDisplayName() API call can be used to parse a moniker's display name into a DCOM object instance IMoniker interface. The ProgID used in the display name is converted to a CLSID, and then an IMoniker reference associated with this CLSID type is returned.

ConclusionsNaming services fulfill a basic distributed enterprise

Communications need for mapping between names in a context and object references. Given an object reference, a server can bind this object to a name in a naming service, and given that name, a client can look up the object reference in the naming service.

JNDI is a core component of the J2EE that provides a standard interface for enterprise Java applications to access naming services. JNDI naming- service providers exist for file systems, RMI applications, and CORBA programs.

Mapping Internet DNS names to IP addresses is also possible from within Java. Finally, DCOM also provides a means for mapping between names and object references using its communications paradigm. Beyond mere mapping between names and objects, characteristics about such objects can also be associated with an extended form of naming system known as a directory or trading system.