Table of Contents
This chapter describes basic concepts and terminologies of JEUS JNDI. It also describes how to set the environment configuration and develop applications.
Java Naming and Directory Interface™ (JNDI) is a standard API used by Java applications to find and get an object in the network by using the logical name of the object. From the user perspective, it provides an environment where applications can find an use objects more easily than in the previous enterprise environment.
JEUS JNDI is compatible with JNDI 1.2 API and supports Sun Microsystem's JNDI API standards. It also provides JNDI Service Provider Interface (SPI) for compatibility with the enterprise environment. This means that any product that implements JNDI SPI can use the objects of JEUS JNDI Tree.
The JEUS JNDI service is used through out JEUS system and can be seen whenever the EJB, servlet/JSP, JMS, and JDBC are used.
JEUS JNDI has a unique architecture that binds and looks up objects. This section will first describe the basic concepts and structure of JEUS JNDI.
When a managed server (MS) starts, JEUS automatically prepares JNDI Service that is provided by the JNDI naming server. When the service starts, the JEUS Naming Service Server (JNSServer) starts internally. JEUS Naming Service Client (JNSClient) acts as a client that communicate with the JNSServer.
When a JNSClient is connected to a JNSServer, objects are first bound and looked up in the JNS Client and then in the JNS Server. A JNSServer is connected to more than one JNSClient. A JNSServer is also connected to other JNSServers (especially in the clustering environment) in a tree like structure. This naming repository structure is called the JNDI Tree.
The JNDI Tree is used to bind or look up objects. All objects are looked up and bound to the JNDI Tree through the server. When an application requests to bind an object to a JNSClient, the object is sent and bound to the JNDI Tree. A JNSClient in the application can look up the bound objects.
The objects in the JNDI tree can only be accessed by using InitialContext. Therefore, an application must create the InitialContext object to use JNDI. The InitialContext object provides access to other objects through the JNDI Tree. In addition, it binds or looks up objects as well as gets and removes the object list.
Bound objects can be checked in WebAdmin or the console tool.
A bound object can be checked in WebAdmin or the console tool.
This section only describes how to check a bound object in WebAdmin. For information about using the console tool, refer to JEUS Reference Book. "4.2.3.19. jndi-info".
The following screenshot shows the JNDI list in WebAdmin.
Select [Monitoring] > [JNDI] from the left menu of WebAdmin to go to the JNDI list page. Select a server from the Server list to display the server's JNDI list.
Select a server from the JNDI list and click on the context to view detailed information about the bound object.
This section describes the operation of the JNDI Tree structure.
The JNDI Tree consists of JNSServers and JNSClients. A JNSServer is on the JVM of the MS, and a JNSClient is on the JVM of an MS or a client. As the main element of the JEUS JNDI architecture, the JNS server creates and manages the JNDI Tree. A JNSClient resides below the JNS Server and is managed by the JNSServer.
The following shows the relationship between a JNSServer and JNSClients.
To access the entire JNDI Tree, a JNSClient must send a request to the JNSServer.
A JNSServer is connected to other JNSServers on other MSs to form a cluster. A JNS client interacts with a JNSServer on an MS and handles client access requests. The client does not directly access the JNSServer, but instead binds and looks up objects through a JNSClient.
A JNSServer manages the JNDI Tree. It is an independent naming server that allows a JNSClient to access the JNDI Tree. Multiple JNSServers can be connected to expand the JNDI Tree. This is because a JNSServer can be directly connected to other JNSServers on other MSs. In JEUS, after an MS starts, the JNSServer automatically waits for JNSClient access requests.
The basic function of a JNSClient is to send application requests to a JNSServer and return the result from the JNSServer. On each JVM, there is one JNSClient singleton instance per server. Since only one JNSClient is used to lookup an object, it can be used effectively with an EJB or a servlet in the enterprise environment.
The following is a list of important JNSClient features.
Accessing a JNDI Tree
Provides a way to access the JNDI Tree that is managed by the MS accessing the JNSServer. The objects that are bound and looked up can be shared by the entire JNDI Tree or only by specific clients depending on the client configuration.
Caching looked up objects
A JNSClient caches frequently used objects for faster access. A JNSClient caches the objects while communicating with a JNSServer.
Managing JNSServer connections
A JNSClient receives a request from a client and sends it to JNSServer and returns the result from the server. Since a JNS client is on the JVM where the client exists, communication can be made efficiently without incurring additional IOs.
The following table describes the two types of JNS clients distinguished by where the JNSServer is.
The JNDI tree consists of connections between a JNSServer and JNSClients. This structure allows a JNS Client to let other JNSClients know about modified objects and supports multiple MSs (clustering).
In other words, individual JNDIs form an extensive JNDI tree through clustering. When there are any modified objects in a JNDI Tree, the changes are propagated to other JNDIs. Therefore, in the JNDI Naming clustered environment, objects bound to a naming server can be looked up from other naming servers.
For example, as shown in the following figure, a cluster environment is composed of four types of MSs (A,B,C,D). If an object called obj1 on MS A is bound as objName1, then this object is sent to all the other MSs (B,C,D). As a result, objName1 can also be looked up on MS B, C, and D to obtain obj1.
Not all bound objects can be replicated to other MSs in the cluster. Only the objects bound to the cluster can be replicated. For example, objects like data sources that are configured to a specific MS can only be bound to the JNSServer of each MS.
Each MS is responsible for managing each JNSServer. Each JNSServer starts when JEUS system starts and is connected to JNSServers on other MSs. When each JEUS engine gets an InitialContext object, a JNSClient connects to the JNSServer. When a client looks up a JNDI tree object, the request is sent to the JNSClient and then to the JNSServer on the MS. As a result, the client obtains the requested object.
Without a separate configuration, JNDI Lookup executes in the JEUS/JNDI cluster that it belongs to. Objects on a JNDI server of an MS that is not in the cluster can be looked up by creating a context by specifying the PROVIDER URL (refer to JEUS Reference Book. "1.4. JNDI System Properties") or by using the name that uses the jh (JEUS host) protocol created in JEUS. For more information, refer to "4.5. JNDI Programming".
Each JNSServer of JEUS is connected to other servers and waiting to interact with them. When a new MS joins an existing cluster, its JNSServer sends a notification to other connected JNSServers. Each JNSServer also sends its data to the new JNS server so that the existing bound objects can be looked up on the new JNS server.
Owing to such scalability, a JNS server that is restarted due to an error can continue to operate normally by receiving the JNDI Tree information from the other JNSServers.
A JNDI naming server consists of a JNSServer and a JNSClient, each with different configurations.
A JNSServer needs configurations to accept JNSClient connection requests and access other JNSServers. A JNSClient needs configurations to access the JNSServer and modify the JNDI tree.
This section describes how to configure the JNSServer and JNSClient.
Select [Servers] from the left menu of WebAdmin to go to the server list page.
Select a server from the list to go to the server configuration page. Select [Naming Server] to go to the JNSServer configuration page.
The following is the naming server configuration page.
A thread pool that is shared on the server can be configured in WebAdmin or the console tool. For basic information about thread pools, refer to "2.3.3. Thread Pool Configuration".
Using WebAdmin
The following is the common thread pool configuration page in WebAdmin. Check the Pooling checkbox and select the Shared button, and then configure the common thread pool and click [OK].
Using the console tool
A common thread pool can be configured using the console tool.
[DAS]domain1.adminServer>modify-system-thread-pool adminServer -service namingserver -r 10 Successfully performed the MODIFY operation for The namingserver thread pool of the server (adminServer)., but all changes were non-dynamic. They will be applie d after restarting. Check the results using "show-system-thread-pool adminServer -service namingserv er or modify-system-thread-pool adminServer -service namingserver" [DAS]domain1.adminServer>modify-system-thread-pool adminServer -service namingserver show the current configuration. The namingserver thread pool of the server (adminServer) ================================================================================ +----------------------------------------------------------------------+-------+ | Reserved Threads for the Service namingserver | 10 | +----------------------------------------------------------------------+-------+ ================================================================================
Configure the service thread pool in WebAdmin or the console tool.
Using WebAdmin
The following is the configuration page of the service thread pool in WebAdmin. Check the Pooling box and then select the Dedicated button. Configure the service thread pool items and then click [OK].
Stuck thread handling configuration
When a thread has been occupied for a certain period of time for a particular reason, use this configuration to handle the thread. Use the shared thread pool.
The following describes the configuration items related to stuck thread handling.
Item | Description |
---|---|
Max Stuck Thread Time | Used to detect a stuck thread. If a thread remains occupied for longer than this time, the thread is considered as stuck. [Default value: 3600000 (1hour), Unit: ms] |
Action On Stuck Thread | Action to perform when a thread is identified as stuck. Select one of the following options.
|
Stuck Thread Check Period | Interval for checking the status of a stuck thread. At this interval, thread status is checked to see if the thread is stuck. (Default value: 300000 (5min), Unit: ms) |
Using the console tool
The service thread pool can also be configured using the console tool.
[DAS]domain1.adminServer>modify-service-thread-pool server1 -service namingserver -min 0 -max 20 Successfully performed the MODIFY operation for The namingserver thread pool of the server (server1)., but all changes were non-dynamic. They will be applied af ter restarting. Check the results using "show-service-thread-pool server1 -service namingserver or modify-service-thread-pool server1 -service namingserver" [DAS]domain1.adminServer>modify-service-thread-pool server1 -service namingserver Shows the current configuration. The namingserver thread pool of the server (server1). =================================================================== +-------------------------------------------------------+---------+ | Min | 0 | | Max | 20 | | Keep-Alive Time | 60000 | | Queue Size | 4096 | | Max Stuck Thread Time | 3600000 | | Action On Stuck Thread | NONE | | Stuck Thread Check Period | 300000 | +-------------------------------------------------------+---------+ ===================================================================
Since the thread pool configuration can be changed dynamically, the server does not need to be restarted. However, the server must be restarted in order to change from a common thread pool to a dedicated thread pool.
The configuration of the JNSClient depends on where JNSClient is running.
Client-side JNSClient Configuration
A client-side JNSClient can access JNS servers on other JVMs. It is connected to a JNSServer and there is a thread that applies the JNDI tree information. The JEUS JNDI uses a thread pool to manage the threads. The thread pool is configured as a JEUS property, but the default value can be used.
Use the JVM system property or InitialContext hash table to configure a property of a client-side JNSClient.
The following are the properties of a client-side JNSClient.
If JNDI is used in server-side objects like an EJB, servlet, or JSP, a server-side JNSClient is used to bind or lookup the objects. Therefore, it is not necessary to configure these properties. For more information about the properties, refer to JEUS Reference Book. "1.4. JNDI System Properties".
When a clustered environment is configured for the MSs, each JNSServer becomes automatically clustered. Refer to JEUS Domain Guide. "Chapter 5. JEUS Clustering" about how to cluster MSs.
By default, a JNSClient connects to a local JNSServer.
The JNSClient recognizes the address of the MS's JNSServer as Context.PROVIDER_URL. Each MS address in the cluster must be added to Context.PROVIDER_URL as in the following.
JNSClients perform load balancing and failover by using the provided Context.PROVIDER_URL value.
Hashtable ht = new Hashtable(); ht.put(Context.PROVIDER_URL, "host1:9736,host2:9736"); //host1 and host2 participate in the cluster
When an MS that is assigned to Context.PROVIDER_URL fails, the JNSClient detects the failure when it tries to execute the JNSServer's JNDI operation on the failed MS and performs failover to another JNSServer. The JNSClient regularly checks the failed MS to see if it is in the RUNNING state. This configuration can be set by using the '-Djeus.jndi.cluster.recheckto' option (Default value: 5, Unit: min).
If a JNSClient runs on an MS managed by the Domain Admin Server (DAS), use the cluster name that was configured on DAS as in the following.
Hashtable ht = new Hashtable(); ht.put(Context.PROVIDER_URL, "jeus://cluster1"); //cluster1 is the cluster name configured on DAS
By using the cluster name, the latest status information of the MS can always be obtained from DAS to configure the cluster regardless of the "jeus.jndi.cluster.recheckto" setting on the JNSClient.
In other words, if an MS in the cluster is in a FAILED state or a new MS is added, the server is updated before performing JNDI operation on the JNSClient.
Therefore, it is recommended to use the cluster name when the JNSClient is running on an MS that is managed by DAS.
Any client in a cluster can look up any object that is bound to a JNDI Tree. When a client has an object bound to a JNSClient, the object is shared by all the MSs that are clustered through a JNSServer. Any data changes or deletions are also applied to the JNSClient of each MS.
Depending on the characteristics of each object, some objects are shared across the entire cluster (objects such as export name for lookup) while some objects are only visible on its own MS (MS-dependent objects such as data sources).
This section describes how to use JEUS JNDI for programming.
Java clients can access a JNDI Tree by using the InitialContext object. The InitialContext object uses the Standard JNDI standard properties and JEUS properties.
First, configure the JNDI environment, and then look up objects by using the InitialContext. Next, get the object reference. Finally, close the InitialContext after use.
The following are the steps used by a Java client to use the JEUS JNDI.
Configure the JEUS environment.
Configure properties for the InitialContext.
Use the context to look up the named object.
Use the named object to get the object reference.
Close the context.
The following is a detailed description of each step.
Set the path for JEUS Client modules, JEUS_CLIENT, in the classpath so that JNDI services can use the classes.
-classpath ${JEUS_CLIENT};
Java clients configure environment properties for the InitialContext before using JEUS JNDI services.
There are two configuration methods.
Using the '-D' option of the JVM.
Creating a hash table and sending it to the InitialContext constructor.
Using the '-D' option of the JVM is more preferable than creating a hash table.
The following are the properties that must be configured to create the InitialContext of JEUS JNDI.
Context.INITIAL_CONTEXT_FACTORY (required)
Context.URL_PKG_PREFIXES
Context.PROVIDER_URL
Context.SECURITY_PRINCIPAL
Context.SECURITY_CREDENTIALS
For more information about the properties, refer to JEUS Reference Book. "1.4. JNDI System Properties".
Add these properties to the hash table and use them to create an InitialContext. Use the default InitialContext if the InitialContext is only used in the objects on the server (EJBs, servlets or JSPs).
The following are the client program configurations.
Context ctx = null; Hashtable ht = new Hashtable(); ht.put(Context.INITIAL_CONTEXT_FACTORY, "jeus.jndi.JNSContextFactory”); ht.put(Context.URL_PKG_PREFIXES, “jeus.jndi.jns.url”); ht.put(Context.PROVIDER_URL, “<hostname>
”); ht.put(Context.SECURITY_PRINCIPAL, “<username>
”); ht.put(Context.SECURITY_CREDENTIALS, “<password>
”); try { ctx = new InitialContext(ht); // use the context } catch (NamingException ne) { // fail to get an InitialContext } finally { try{ ctx.close(); catch (Exception e) { // an error occurred } }
When JNDI is used in a cluster environment, additional environment properties for jeus.jndi.JNSContext can be used to create a JNDI Tree and effectively manage the internal operations of a JNSClient.
Creating a context using the hash table
To configure an environment property of the InitialContext, the property name is assigned to a hash table (java.util.Hashtable) key and the property data is assigned to the hash table (java.util.Hashtable) value. The key value pair is passed to the InitialContext constructor as a parameter.
Creating a Security Context
Multiple security-related environment properties can be used to allow a user of the JEUS security domain to access an execution thread. When the InitialContext is created, the following properties are configured for the Security Context.
User name property: java.naming.security.principal
Password property: java.naming.security.credentials
After a successful authentication, the authenticated user information is configured for an execution thread, and the user can access the resources that are managed by the JEUS Security Manager. If the authentication fails, the thread recognizes the user as a guest user.
Even when the Security Context is configured, the context is ignored when the JEUS security API is used to log on before the InitialContext is created. In this case, the already logged on subject is used for JNDI communication.
1. Refer to "JEUS Security guide" for more information about configuring the user information and JEUS security service.
2. Refer to JEUS Reference Book. "1.4. JNDI System Properties" for more information about the InitialContext properties and environment properties.
Objects that are bound to a JNDI Tree can be located by using the lookup() method of the JNDI context. In the following example, 'countermod' is the module name of the object that is going to be looked up, and the 'Count' is the EJB name.
try { Context ctx = new InitialContext(); Count count = (Count)ctx.lookup(“java:global/countermod/Count”); // Count count = (Count)ctx.lookup(“java:global/countermod/Count!my.ejb3.tx.Count”); // Count count = (Count)ctx.lookup(“Count”); // successfully got the object } catch (NameNotFoundException ex) { // no such binding exists } catch (NamingException e) { // an error occurred }
When there are multiple business interfaces, append '![interface name]' to the name to look up.
Count count = (Count)ctx.lookup(“java:global/countermod/Count!my.ejb3.tx.Count");
When there is an export name, use the export name to look up.
Count count = (Count)ctx.lookup(“Count”);
The following is an example of looking up an EJB 2.x object.
try { Context ctx = new InitialContext(); CountHome countHome = (CountHome)ctx.lookup(“Count”); // successfully got the object } catch (NameNotFoundException ex) { // no such binding exists } catch (NamingException e) { // an error occurred }
In EJB 3.x, a looked-up object can be used immediately as in the following.
count.service();
For EJB 2.x, get the reference of the EJB remote object by using the create() method of the looked-up EJB home object. Execute the create() method to get the home reference of the object and use it to execute a method as in the following.
Count count = countHome.create(); count.service();
When finished with using the context, close the context by executing the close() method as in the following.
try { cx.close(); } catch(Exception e) { // an error occurred }
To create a context that is usable in the clustered environment in JEUS, set multiple hosts in the Context.PROVIDER_URL property as in the following.
Hashtable ht = new Hashtable(); ht.put(Context.PROVIDER_URL, "host1:9736,host2:9736");
If the cluster name that is configured in the domain is known, then it can be configured for use as in the following.
Context.PROVIDER_URL에 'jeus://' + <The cluster name>
However, it is usable only on an MS in the cluster and cannot be used on a standalone client where the cluster information is unknown.
Hashtable ht = new Hashtable(); ht.put(Context.PROVIDER_URL, "jeus://cluster1");
In a context clustered environment, a policy can be configured for selecting an MS to look up.
Jeus.jndi.clusterlink.selection-policy property can be used to configure one of the following three available options. As well, these values can be configured with the System property, and in this case, configuration via Hashtable is given priority.
Option | Description |
---|---|
locallinkPreference | Use an object on the local MS. |
roundrobin | For the first request, randomly select an MS to look up the object. Use the round robin method to select an MS for any subsequent requests. |
random | Randomly select one of the clustered MSs. |
The following is a configuration example.
Hashtable ht = new Hashtable(); ht.put(Context.PROVIDER_URL, "host1:9736,host2:9736"); ht.put("jeus.jndi.clusterlink.selection-policy", "random");
When an application looks up from a JNDI server on an MS that is not in the cluster, it must create a context by specifying the PROVIDER URL or by using the name that uses the jh (JEUS host) protocol created by JEUS.
The following syntax can be used to look up an object on a remote JEUS JNDI cluster from a clustered environment in JEUS.
jh:<remote JEUS host name>:<remote JEUS base port>/<export name> ("jh" = JEUS host)
The following shows how to implement a lookup. Add the following code to the JNDI context string.
try { Context ctx = new InitialContext(); CountHome countHome = (CountHome)ctx.lookup("jh:dev:9736/Count"); // successfully got the object } catch (NameNotFoundException ex) { // no such binding exists } catch (NamingException e) { // an error occurred }