320 likes | 347 Views
Communicating in J2EE. Objectives. After completing this lesson, you should be able to do the following: Describe Remote Method Invocation (RMI) Define the role of RMI in Java 2, Enterprise Edition (J2EE) applications Describe Java Naming and Directory Interface (JNDI)
E N D
Objectives • After completing this lesson, you should be able to do the following: • Describe Remote Method Invocation (RMI) • Define the role of RMI in Java 2, Enterprise Edition (J2EE) applications • Describe Java Naming and Directory Interface (JNDI) • Define the role of JNDI in J2EE applications • Write code to look up a Java object by a JNDI name
Overview of RMI • Remote Method Invocation (RMI) is a framework for executing distributed objects in Java. RMI has the following characteristics: • It uses RPC-like communication mechanisms. • It is designed for client applications to invoke remote object methods, as easily as calling local methods. • It comprises the following components: • Remote interface • Implementation class • Server application/class • Client application/class • Stub (proxy) and skeleton classes
Role of RMI in J2EE • Distributed components or objects in J2EE are implemented as Enterprise JavaBeans (EJB). • Oracle Application Server 10g Containers for J2EE (OC4J) uses a custom form of the RMI wire protocol known as ORMI. The J2EE 1.3 specification requires support for the RMI-IIOP protocol as the type of communication used between the client and server object. • EJBs have a remote interface and implementation classes, which conform to RMI semantics: • They implement a remote interface. • Methods throw the java.rmi.RemoteException. • Object parameters or return values must be serializable.
Communication in a J2EE Environment J2EE server Naming Creation 1 3 Client 4 2 5 Interface Marshaled data Skeleton Stub Marshaled data 6 7 Local call Interface Network protocol (Java RMI) Server object
How Clients Locate a Distributed Component • In J2EE, a distributed component is bound to a name when deployed. • The server object run-time environment provides a naming service to help locate an object by a name: • In RMI, the RMI registry performs this task. • In J2EE, the container typically provides this service. • Clients use the Java Naming and Directory Interface (JNDI) API to locate a remote object by a name.
Java Naming and Directory Interface (JNDI) • What is JNDI? • JNDI is a standard API that provides access to the directory and naming functionality. • The JNDI Service Provider Interface (SPI) implementation provides the mapping between the naming servers and the JNDI APIs. JNDI API Client JNDI SPI RMI registry COS Naming LDAP Name and directory services
J2EE Container and JNDI Interface • The container implements the J2EE environment and makes the services and resources available through a JNDI interface. • The JNDI service obtains names from the Extensible Markup Language (XML) files and holds them in memory. • JNDI allows developers to write application code that is independent of vendor-specific underlying protocols, connections, and other resources. • The JNDI interface provides a common naming convention to access J2EE resources.
Naming Service • A naming service allows clients or objects to locate each other in a network by: • Storing objects published against their names, known as binding a name to an object • Maintaining a mapping of logical names to actual names of hierarchical objects • Using a directory service with a hierarchical structure to maintain logical names for its data • Examples: Java Naming and Directory Interface (JNDI), RMI registry, Lightweight Directory Access Protocol (LDAP), CORBA naming service (COS Naming)
env jdbc ejb JNDI Terminology JNDI client Initial context ormi://host/AppCtx Namespace Context Sub-context Atomic names Employee Cart oeCoreDS OracleDS Binding Objects java:comp/env/jdbc/OracleDS Compound name
Main JNDI Class and Interface • The javax.naming.InitialContext class: • Is used to obtain the initial context for JNDI lookup operations • Returns a reference to the object implementing the java.naming.Context interface • The javax.naming.Context interface: • Provides methods to bind names to objects • Provides methods to create subcontexts • Provides methods to navigate the JNDI name hierarchy • Looks up an object by a name that is relative to the initial context or a subcontext
Accessing an Object in JNDI Namespace • A client must perform the following steps to retrieve a • local object reference from the JNDI namespace: • Get the JNDI InitialContext object. Example: Context ic = new InitialContext(); • Form the URL for the bean home interface and call the lookup() method to get the reference to the local home interface object. Example: DepartmentLocalHome home = (DepartmentLocalHome) ic.lookup( "java:comp/env/ejb/Dept"); • lookup() returns an Object type that should be cast to a desired type.
Getting the JNDI InitialContext • When OC4J starts, a JNDI context is constructed for each application deployed in the server. • An initial context obtained by the client is used to access the subcontexts and objects. • Clients accessing objects in a remote OC4J container typically require a set of environment properties to obtain the InitialContext: • INITIAL_CONTEXT_FACTORY • PROVIDER_URL • SECURITY_PRINCIPAL • SECURITY_CREDENTIAL • dedicated.rmicontext
Getting the JNDI InitialContext • Set environment properties for initial context in: • The system properties, set either by the OC4J server or by the application container • A jndi.properties file contained in the application EAR file, as part of the application-client.jar file • An environment specified explicitly in a Hashtable • The JNDI InitialContext has two constructors: • A no-arg constructor used by local clients to execute code in the same J2EE container • A constructor with a Hashtable argument used by remote clients to execute code in a remote J2EE container
Initial Context Factories • There are three JNDI initial context factories: • ApplicationClientInitialContextFactory • ApplicationInitialContextFactory • RMIInitialContextFactory • An initial context factory is used to construct an InitialContext object. • The initial context factory class name is the string value for the INITIAL_CONTEXT_FACTORY JNDI property.
lookup() Method • The lookup() method obtains a reference to the required resource. • To reference a local resource, pass the URL with the object name as parameter:java:comp/env/subContext/resourceName Examples: • java:comp/env/ejb/Dept • jdbc/oeCoreDS • Retrieve a reference to target EJB by using: • The actual bean name specified in the <ejb-name> element or the <ejb-ref-name> element of ejb-jar.xml • The logical bean name specified in the <ejb-ref-name> element of application-client.xml
Obtaining a Reference to a Local Resource • Using the default InitialContext: 1. Obtain InitialContext:Context ic = new InitialContext(); 2. Obtain reference to a resource using lookup(): • An EJB client referencing another local EJB Object obj = ic.lookup("java:comp/env/ejb/Dept"); • An EJB client referencing a data source Object obj = ic.lookup("jdbc/oeCoreDS"); 3. Cast reference obtained from lookup(): DepartmentLocalHome dlh = (DepartmentLocalHome) obj;DataSource ds = (DataSource) obj;
Obtaining a Reference to a Remote Resource • Use initial context with appropriate JNDI properties: 1. Set JNDI properties for application:Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, ...); 2. Obtain the InitialContext:Context ic = new InitialContext(env); 3. Obtain a reference to a resource by using lookup():Object obj = ic.lookup("Dept"); 4. Cast the reference to the returned Object type:DepartmentHome dh = (DepartmentHome) PortableRemoteObject.narrow(obj, DepartmentHome.class);
Setting JNDI Environment Properties • Do not set JNDI properties if: • The client exists in the same application as the target • The target exists in the parent application of the client • Setting JNDI properties: • Supply the properties through the jndi.properties file. The path of the file must be in the CLASSPATH, or JAVA_HOME/lib. • Supply properties in the client code by using a Hashtable.
Setting JNDI Environment Properties • Using the jndi.properties file: • Factory: Initial context factory to be used java.naming.factory.initial =com.evermind.server. ApplicationClientInitialContextFactory • Location: URL used to look up the objects java.naming.provider.url = ormi://<hostname>:23891/<application-name> • Security: Valid credentials of the client to this container java.naming.security.principal=<username> java.naming.security.credentials=<password>
Setting JNDI Environment Properties • Specify the JNDI properties in the client code by: • Using jndi.properties • Declaring properties in a Hashtable and passing them to the InitialContext constructor Hashtable env = new Hashtable(); env.put(Context.PROVIDER_URL, "ormi://myhost/J2EECourse"); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.evermind.server. ApplicationClientInitialContextFactory"); env.put(Context.SECURITY_PRINCIPAL, "guest"); env.put(Context.SECURITY_CREDENTIALS, "welcome"); Context ic = new InitialContext (env);
Using RMI over HTTP Tunneling • OC4J supports tunneling of RMI over HTTP or HTTP-S. • Allows clients to communicate with remote objects through a firewall • Makes the connection appear as if it is stateful • Clients use RMI over HTTP in JNDI requests by prefixing PROVIDER_URL with http: as in the following example: • Port used is the HTTP server port (by default 80) Hashtable env = new Hashtable(); env.put(Context.PROVIDER_URL, "http:ormi://<host>:<port>/Application");
Using Environment References with JNDI • An environment reference is: • A static element accessible to applications at run time • Defined as: • An environment variable • A resource manager (JDBC data source, JMS services, or a URL) • An EJB reference (logical name for the EJB) • Bound in JNDI namespace at deployment time • Defined in the J2EE deployment descriptors • Mapped through OC4J-specific descriptor • Referenced by using the JNDI lookup() method of an InitialContext
Configuring Environment Variables • Environment variables are defined in the <env-entry> section of the deployment descriptor (DD). • One entry for each variable; case-sensitive • Types can be the following classes: String, Integer, Boolean, Double, Byte, Short, Long, or Float <env-entry> Deployment Descriptor <env-entry-name>minBalance</env-entry-name> <env-entry-type>java.lang.Integer</env-entry-type> <env-entry-value>500</env-entry-value> </env-entry> InitialContext ic = new InitialContext(); Client Integer minBal = (Integer) ic.lookup("java:comp/env/minBalance");
Configuring Environment Variables • The J2EE name can be mapped to a different value in the OC4J-specific deployment descriptor (DD). • The OC4J-specific DD overrides the value in the J2EE deployment descriptor. <env-entry> J2EE DD <env-entry-name>minBalance</env-entry-name> <env-entry-type>java.lang.Integer</env-entry-type> <env-entry-value>500</env-entry-value> </env-entry> <env-entry-mapping OC4J DD name="minBalance">300 </env-entry-mapping>
Specifying an EJB Reference • Specify an EJB reference by using an <ejb-ref> element in a J2EE client application deployment descriptor: <ejb-ref> <ejb-ref-name>Employee</ejb-ref-name> <ejb-ref-type>Session</ejb-ref-type> <home>businesstier.EmployeeHome</home> <remote> businesstier.Employee</remote> </ejb-ref> • A logical name in an <ejb-ref-name> element must be mapped to a JNDI name in an <ejb-name> element of an EJB deployment descriptor. • The server side receives the JNDI name and resolves it in its JNDI tree.
Configuring EJB References • The <ejb-ref> element of a client J2EE deployment descriptor can provide: • The actual name of the bean in <ejb-ref-name> • A logical name of the bean in <ejb-ref-name> and the actual name in <ejb-link> • The logical name of the bean in <ejb-ref-name>, to be mapped to the actual name of the bean in the <ejb-ref-mapping> element in the OC4J-specific deployment descriptor • Other elements of the EJB reference are: • Type: Session or entity bean • Home/LocalHome: Qualified home interface name • Remote/Local: Qualified remote/local interface name
Configuring Data Source References • Create an environment reference to each data source that is used by a client through a JNDI reference. • These references can be used only by the J2EE application that defines these data sources. • The JNDI name is defined in the ejb-location attribute of a <data-source> element in the data-sources.xml file. • The J2EE deployment descriptor can use either the JNDI name or a logical name. • A logical name must be mapped to the JNDI name in the OC4J-specific deployment descriptor.
Configuring Data Source References 1. Define in data-sources.xml. <data-sources> <data-source class="com.evermind.sql.DriverManagerDataSource" name="OracleDS" location="jdbc/OracleCoreDS" ... ejb-location="jdbc/OracleDS" ... /> </data-sources> JNDI Name 2. Reference in J2EE Deployment Descriptor. <resource-ref> <res-ref-name>jdbc/oeCoreDB</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Application</res-auth> <resource-ref> 3. Map in OC4J-specific deployment descriptor. <resource-ref-mapping name="jdbc/oeCoreDB" location= "jdbc/OracleDS" /> Logical Name
Summary • In this lesson, you should have learned how to: • Describe Remote Method Invocation (RMI) • Recognize the role of RMI in a J2EE environment • Explain the concepts of JNDI • Access an EJB or a data source object by using JNDI techniques • Configure the JNDI names and environment properties, such as environment variables, EJB references, and data sources
Practice 10-1: Overview • This practice covers the following topics: • Creating a JSP Java client to connect to and invoke a remote Hello World EJB (the EJB is provided) by using the ORMI protocol • Creating a stand-alone client to obtain a reference to an EJB and JDBC data source