📄 ch04.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"><HTML><HEAD><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1"><META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css"><META NAME="GENERATOR" CONTENT="Adobe FrameMaker 6.0/HTML Export Filter"><LINK REL="STYLESHEET" HREF="CH04.css" CHARSET="ISO-8859-1" TYPE="text/css"><TITLE> Covered in this Chapter</TITLE></HEAD><BODY BGCOLOR="#ffffff"><P CLASS="CT"><A NAME="pgfId-1087399"></A>4</P><P CLASS="CT"><A NAME="pgfId-1087400"></A>Distributed Computing</P><P CLASS="Body"><A NAME="pgfId-1087401"></A>As recently as 10 years ago, distributed computing generally meant you had client PCs in one room with a server in another room. The problem here is if the server machine is down, the clients cannot update the payroll, sales, or other distributed company databases. Preventing this kind of down-time requires different distributed models. One example is the master and slave model in which, if the master fails, the slaves take over. </P><P CLASS="Body"><A NAME="pgfId-1087402"></A>The problem with the different distributed network models is they all require some form of manual intervention and are often tied to one operating system or language. And while these approaches meet some of the short-term requirements for decreasing down-time, they do not apply to heterogeneous distributed systems with mixed network protocols and machines.</P><P CLASS="Body"><A NAME="pgfId-1087403"></A>The Java platform and other advances such as Common Object Request Broker Architecture (CORBA), multitiered servers, and wireless networks have brought the realization of fully distributed computing another step ahead of the traditional client and server approach. Today, you can build applications that include service redundancy by default. If one server connection fails, you can seamlessly use a service on another server. CORBA and Distributed Component Object Model (DCOM) bridges mean that objects can be transferred between virtually all machines and languages. And with the new Jini™ System software, the distributed computing environment can soon be part of everything in your home, office or school. In short, distributed computing has never been as important as it is today. </P><P CLASS="Body"><A NAME="pgfId-1087404"></A>The first part of this chapter shows you how to write lookup code using JNDI, CORBA, Interoperable Object Reference (IOR), and RMI over Internet Inter-ORB Protocol (RMI-IIOP). The second part describes how to use lookup code with RMI and CORBA, and concludes with a discussion of JDBC and servlet technologies.</P><DIV><H4 CLASS="A"><A NAME="pgfId-1087405"></A>Covered in this Chapter</H4><UL><LI CLASS="BL"><A NAME="pgfId-1087406"></A>Lookup Services (page 58)</LI><LI CLASS="BL"><A NAME="pgfId-1087407"></A>Java Naming and Directory Interface (page 59)</LI><LI CLASS="BL"><A NAME="pgfId-1087408"></A>RMI Lookup Service (page 64) </LI><LI CLASS="BL"><A NAME="pgfId-1087409"></A>RMI Registration Server (page 67)</LI><LI CLASS="BL"><A NAME="pgfId-1087410"></A>Common Object Request Broker Architecture (page 83)</LI><LI CLASS="BL"><A NAME="pgfId-1087411"></A>JDBC Technology (page 103)</LI><LI CLASS="BL"><A NAME="pgfId-1087412"></A>Servlets (page 118)</LI></UL></DIV><DIV><H4 CLASS="A"><A NAME="pgfId-1087414"></A><A NAME="24156"></A>Lookup Services</H4><P CLASS="Body"><A NAME="pgfId-1087416"></A><A NAME="marker-1087415"></A>Lookup (naming) services enable communications over a network. A client program can use a lookup protocol to get information on remote programs or machines and use that information to establish a communication. </P><UL><LI CLASS="BL"><A NAME="pgfId-1087419"></A><A NAME="marker-1087417"></A>One common lookup service you might already be familiar with is <A NAME="marker-1087418"></A>Directory Name Service (DNS). It maps Internet Protocol (IP) addresses to machine names. Programs use the DNS mapping to look up the IP address associated with a machine name and use the IP address to establish a communication.</LI><LI CLASS="BL"><A NAME="pgfId-1087420"></A>In the same way, the AuctionServlet presented in Chapter 2, Auction House Application, uses the naming service built into the Enterprise JavaBeans architecture to look up and reference enterprise beans registered with the Enterprise JavaBeans server.</LI></UL><P CLASS="Body"><A NAME="pgfId-1087422"></A>In addition to naming services, some <A NAME="marker-1087421"></A>lookup protocols provide directory services. Directory services such as <A NAME="marker-1087423"></A>Lightweight Directory Access Protocol (LDAP) and Sun's <A NAME="marker-1087424"></A>NIS+ provide other information and services beyond what is available with simple naming services. For example, NIS+ associates a workgroup attribute with a user account. This attribute can be used to restrict access to a machine so only the users in the specified workgroup have access. </P><P CLASS="Body"><A NAME="pgfId-1087425"></A>This chapter describes how JNDI is used in the auction application to look up enterprise beans. It also explains how to use some of the many other lookup services that have become available over time. The code to use these other services is not as simple as the lookup code in the auction application in Chapter 2, but the advantages to these other services can outweigh the need for more complex code in some situations. </P></DIV><DIV><H4 CLASS="A"><A NAME="pgfId-1087427"></A><A NAME="45774"></A>Java Naming and Directory Interface</H4><P CLASS="Body"><A NAME="pgfId-1087430"></A><A NAME="marker-1087428"></A><A NAME="marker-1087429"></A>The JNDI API makes it easy to plug lookup services from various providers into a program written in the Java programming language. As long as the client and server both use the same lookup service, the client can easily look up information registered with the server and establish communication. </P><P CLASS="Body"><A NAME="pgfId-1087431"></A>The auction application session beans use JNDI and a special JNDI naming factory from BEA Weblogic to look up entity beans. JNDI services normally initialize the naming factory as a property on the command line or as an initialization value. First, the naming factory <EM CLASS="CODE">weblogic.jndi.TengahInitialContextFactory</EM><A NAME="marker-1087432"></A> is put into a <EM CLASS="CODE">java.util.Property</EM><A NAME="marker-1087433"></A> object, then the <EM CLASS="CODE">Property</EM> object is passed as a parameter to the <EM CLASS="CODE">InitialContext</EM><A NAME="marker-1087434"></A> constructor. Here is an example <EM CLASS="CODE">ejbCreate</EM><A NAME="marker-1087435"></A> method. </P><PRE CLASS="CODE"><A NAME="pgfId-1087436"></A>Context ctx; //JNDI context</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087437"></A>public void ejbCreate() throws CreateException, RemoteException {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087438"></A> Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.TengahInitialContextFactory");</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087439"></A> try { ctx = new InitialContext(env);</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087440"></A> } catch(Exception e) {</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087441"></A> System.out.println("create exception: "+e);</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087442"></A> } </PRE><PRE CLASS="CODE"><A NAME="pgfId-1087443"></A>}</PRE><P CLASS="Body"><A NAME="pgfId-1087444"></A>Once created, the JNDI context is used to look up enterprise bean home interfaces. In this example, a reference to the enterprise bean bound to the name <EM CLASS="CODE">registration</EM> is retrieved and used for further operations. </P><PRE CLASS="CODE"><A NAME="pgfId-1087445"></A>RegistrationHome rhome = (RegistrationHome) ctx.lookup("registration");</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087446"></A>RegistrationPK rpk=new RegistrationPK();</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087447"></A>rpk.theuser=buyer;</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087448"></A>Registration newbidder = rhome.findByPrimaryKey(rpk);</PRE><P CLASS="Body"><A NAME="pgfId-1087450"></A>On the server side, the <A NAME="marker-1087449"></A>deployment descriptor for the <EM CLASS="CODE">RegistrationBean</EM> has its bean <EM CLASS="CODE">homename</EM> value set to <EM CLASS="CODE">registration</EM>. Enterprise JavaBeans tools generate the rest of the naming code for the server. </P><P CLASS="Body"><A NAME="pgfId-1087452"></A>The server calls <EM CLASS="CODE">ctx.bind</EM><A NAME="marker-1087451"></A> to bind the name <EM CLASS="CODE">registration</EM> to the JNDI context. The <EM CLASS="CODE">this</EM> parameter references the <EM CLASS="CODE">_stub</EM><A NAME="marker-1087453"></A> class that represents the <EM CLASS="CODE">RegistrationBean</EM>. </P><PRE CLASS="CODE"><A NAME="pgfId-1087454"></A>ctx.bind("registration", this);</PRE><P CLASS="Body"><A NAME="pgfId-1087455"></A>JNDI is not the only way to look up remote objects. Lookup services are also available in the RMI, JINI, and CORBA platforms. You can use these platform-specific lookup services directly or from the JNDI API. </P><P CLASS="Body"><A NAME="pgfId-1087457"></A><A NAME="marker-1087456"></A>JNDI allows the application to change the name service with little effort. For example, here are the code changes to have the <EM CLASS="CODE">BidderBean.ejbCreate</EM> method use the <EM CLASS="CODE">org.omb.CORBA</EM><A NAME="marker-1087458"></A> lookup services instead of the default BEA Weblogic lookup services. </P><PRE CLASS="CODE"><A NAME="pgfId-1087459"></A>Hashtable env = new Hashtable();</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087460"></A>env.put("java.naming.factory.initial", "com.sun.jndi.cosnaming.CNCtxFactory");</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087461"></A>Context ic = new InitialContext(env)<EM CLASS="CODE">;</EM></PRE><DIV><H5 CLASS="B"><A NAME="pgfId-1087463"></A><A NAME="87419"></A>CORBA Naming Service</H5><P CLASS="Body"><A NAME="pgfId-1087466"></A><A NAME="marker-1087464"></A><A NAME="marker-1087465"></A>CORBA defines a specification for objects in a distributed system to communicate with each other. Objects that use the CORBA specification to communicate are called CORBA objects, and consist of client and server objects. </P><P CLASS="Body"><A NAME="pgfId-1087468"></A>CORBA objects can be written in any language with <A NAME="marker-1087467"></A>Interface Definition Language (IDL) mapping. These languages include the Java programming language, C++, and many traditional non-object-orientated languages. </P><P CLASS="Body"><A NAME="pgfId-1087469"></A>The naming lookup service, like all other CORBA specifications, is defined in terms of IDL. The IDL module for the CORBA lookup service is called <EM CLASS="CODE">CosNaming</EM><A NAME="marker-1087470"></A><A NAME="marker-1087471"></A>. Any platform with an IDL mapping can use this service to look up and discover CORBA objects. The IDL module for the CORBA lookup service is available in the Java 2 Platform in the <EM CLASS="CODE">org.omg.CosNaming</EM> package and the mapping to the Java programming language is created by a tool called <EM CLASS="CODE">idltojava</EM>.</P><P CLASS="Body"><A NAME="pgfId-1087473"></A>The key interface in the <EM CLASS="CODE">CosNaming</EM> module is <EM CLASS="CODE">NamingContext</EM><A NAME="marker-1087472"></A>. The <EM CLASS="CODE">NamingContext</EM> interface defines methods to bind objects to a name, list those bidding, and retrieve bound object references. </P><P CLASS="Body"><A NAME="pgfId-1087475"></A>In addition to these public interfaces are helper classes. The <EM CLASS="CODE">NameComponent</EM><A NAME="marker-1087474"></A> helper class is used in CORBA client and server programs to build the full name for the object reference name. The full name is an array of one or more <EM CLASS="CODE">NameComponents</EM> that indicate where to find the objects. The naming scheme can be application specific. </P><P CLASS="Body"><A NAME="pgfId-1087476"></A>Figure 4.1 shows how the full name for the auction application can be defined to use <EM CLASS="CODE">auction</EM> as the root naming context with <EM CLASS="CODE">RegistrationBean</EM> and <EM CLASS="CODE">AuctionItemBean</EM> as children of the root context. This, in effect, employs a similar naming scheme as that used for the application class packaging. </P><DIV><H6 CLASS="FC"><A NAME="pgfId-1087481"></A>Figure 4.1 <A NAME="12884"></A>Full name and root naming context</H6><DIV><IMG SRC="CH04-1.gif"></DIV><P CLASS="Body"><A NAME="pgfId-1087482"></A>In this example, the auction application has adapted <EM CLASS="CODE">SellerBean</EM> to a CORBA naming service to look up the CORBA <EM CLASS="CODE">RegistrationBean</EM>. The following code is extracted from the <EM CLASS="CODE">SellerBean</EM> class, which acts as the CORBA client, and the <EM CLASS="CODE">RegistrationServer</EM> CORBA server. </P><P CLASS="Body"><A NAME="pgfId-1087484"></A><EM CLASS="Bold">CORBA RegistrationServer. </EM><A NAME="marker-1087483"></A>The <EM CLASS="CODE">RegistrationServer</EM> (lookup) code creates a <EM CLASS="CODE">NameComponent</EM> object that uses the <EM CLASS="CODE">auction</EM> and <EM CLASS="CODE">RegistrationBean</EM> strings as a full name indicating where to locate the <EM CLASS="CODE">RegistrationBean</EM>. </P><PRE CLASS="CODE"><A NAME="pgfId-1087485"></A>NameComponent[] fullname = new NameComponent[2];</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087486"></A>fullname[0] = new NameComponent("auction", "");</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087487"></A>fullname[1] = new NameComponent( "RegistrationBean", "");</PRE><P CLASS="Body"><A NAME="pgfId-1087489"></A><A NAME="marker-1087488"></A>This next code binds the <EM CLASS="CODE">fullname</EM> as a new name context. The first elements in the full name (<EM CLASS="CODE">auction</EM>, in this example) are placeholders for building the context-naming tree. The last element of the full name (<EM CLASS="CODE">RegistrationBean</EM>, in this example) is the name submitted as the binding to the object.</P><PRE CLASS="CODE"><A NAME="pgfId-1087490"></A>public static void main(String args[]) {String[] orbargs = { "-ORBInitialPort 1050"};</PRE><PRE CLASS="CODE-caption"><A NAME="pgfId-1087492"></A>//API Ref: <A NAME="93940"></A>status ORB init(String[] args, Properties props)</PRE><PRE CLASS="CODE"><A NAME="pgfId-1087497"></A><A NAME="marker-1087493"></A><A NAME="org.omg.CORBA.ORB class"></A><A NAME="ORB class"></A><A NAME="init method"></A>ORB orb = ORB.init(orbargs, null) </PRE><PRE CLASS="CODE"><A NAME="pgfId-1087498"></A>RegistrationServer rs= new RegistrationServer(); </PRE><PRE CLASS="CODE"><A NAME="pgfId-1087499"></A>try{</PRE><PRE CLASS="CODE-caption"><A NAME="pgfId-1087501"></A>//API Ref: <A NAME="81628"></A>void connect(Object object)</PRE>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -