📄 lookup.html
字号:
rhome.findByPrimaryKey(rpk);
</PRE>
On the server side, the deployment descriptor for the <CODE>RegistrationBean</CODE>
has its <CODE>beanhomename</CODE> value set to <CODE>registration</CODE>.
Enterprise JavaBeans tools generate the rest of the naming code for the
server.
<P>
The server calls <CODE>ctx.bind</CODE>
to bind the name <CODE>registration</CODE> to the JNDI
context. The <CODE>this</CODE> parameter references the <CODE>_stub</CODE>
class that represents the <CODE>RegistrationBean</CODE>.
<PRE>
ctx.bind("registration", this);
</PRE>
<P>
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. JNDI allows the application to change the name service with
little effort. For example, here are the code changes to have the
<CODE>BidderBean.ejbCreate</CODE> method use the <CODE>org.omb.CORBA</CODE>
lookup services instead of the default BEA Weblogic lookup services.
<PRE>
Hashtable env = new Hashtable();
env.put("java.naming.factory.initial",
"com.sun.jndi.cosnaming.CNCtxFactory");
Context ic = new InitialContext(env);
</PRE>
<A NAME="corba"></A>
<H3>CORBA Naming Service</H3>
The Common Object Request Broker Architecture (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>
CORBA objects can be written
in any language with Interface Definition Language (IDL) mapping. These
languages include the Java programming language, C++, and many traditional
non-object-orientated languages.
<P>
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 <CODE>CosNaming</CODE>. Any platform with an IDL
mapping, such as the <CODE>idltojava</CODE> tool, 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 <CODE>org.omg.CosNaming</CODE> package.
<P>
The key interface in the <CODE>CosNaming</CODE> module is <CODE>NamingContext</CODE>.
The <CODE>NamingContext</CODE> interface defines methods to bind
objects to a name, list those bidding, and retrieve bound object references.
<P>
<IMG SRC="./Art/fullname.gif" ALIGN="LEFT">
In addition to these public interfaces are helper classes. The
<CODE>NameComponent</CODE>
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 <CODE>NameComponents</CODE> that indicates
where to find the objects. The naming scheme
can be application specific.
<P>
For example in the auction application, the full name can be defined
to use <CODE>auction</CODE> as the root naming context, and
<CODE>RegistrationBean</CODE> and <CODE>AuctionItemBean</CODE> as
children of the root context. This in effect employs a similar
naming scheme as that used for the application class packaging.
<P>
In this example, the auction application has adapted
<CODE>SellerBean</CODE> to a CORBA naming service to look up the
CORBA <CODE>RegistrationBean</CODE>.
The following code is extracted from the <CODE>SellerBean</CODE>,
which acts as the CORBA client, the and <CODE>RegistrationServer</CODE> CORBA server.
<P>
<H4>CORBA RegistrationServer</H4>
This code in the
<A HREF="./Code/lookup/RegistrationServer.java">RegistrationServer</A>
program creates a <CODE>NameComponent</CODE> object
that indicates where to locate the <CODE>RegistrationBean</CODE>
using <CODE>auction</CODE> and <CODE>RegistrationBean</CODE> as
the full name.
<PRE>
NameComponent[] fullname = new NameComponent[2];
fullname[0] = new NameComponent("auction", "");
fullname[1] = new NameComponent(
"RegistrationBean", "");
</PRE>
This next code binds the <CODE>fullname</CODE> as a new context.
The first elements in the full name (<CODE>auction</CODE> in this example)
are placeholders for building the context naming tree. The last element
of the full name (<CODE>RegistrationBean</CODE> in this example)
is the name submitted as the binding to the object.
<PRE>
String[] orbargs = { "-ORBInitialPort 1050"};
ORB orb = ORB.init(orbargs, null) ;
RegistrationServer rs= new RegistrationServer();
orb.connect(rs);
try{
org.omg.CORBA.Object nameServiceObj =
orb.resolve_initial_references("NameService");
NamingContext nctx =
NamingContextHelper.narrow(nameServiceObj);
NameComponent[] fullname = new NameComponent[2];
fullname[0] = new NameComponent("auction", "");
fullname[1] = new NameComponent(
"RegistrationBean", "");
NameComponent[] tempComponent =
new NameComponent[1];
for(int i=0; i < fullname.length-1; i++ ) {
tempComponent[0]= fullname[i];
try{
nctx=nctx.bind_new_context(tempComponent);
}catch (Exception e){}
}
tempComponent[0]=fullname[fullname.length-1];
// finally bind the object to the full context path
nctx.bind(tempComponent, rs);
</PRE>
Once the <CODE>RegistrationServer</CODE>
object is bound, it can be looked up with a JNDI
lookup using a <CODE>CosNaming</CODE> service provider as described at
the end of the section on JNDI, or using the CORBA name lookup service. Either way,
the CORBA name server must be started before any look ups can happen.
In the Java 2 platform, the CORBA <CODE>nameserver</CODE>
is started as follows:
<PRE>
tnameserv
</PRE>
This starts the CORBA <CODE>RegistrationServer</CODE> on the default TCP
port 900.
If you need to use a different port, you can start the server
like this. On Unix systems only root can access port numbers lower
than 1025,
<PRE>
tnameserv -ORBInitialPort 1091
</PRE>
<H4>CORBA SellerBean</H4>
On the client side, the CORBA lookup uses the
<CODE>NameComponent</CODE> object to construct the name.
Start the object server as follows:
<PRE>
java registration.RegistrationServer
</PRE>
The difference in the client is that this name is passed to
the <CODE>resolve</CODE> method which returns the CORBA object. The
following code from the
<A HREF="./Code/lookup/SellerBean.java">SellerBean</A> object
illustrates this point.
<PRE>
String[] args = { "-ORBInitialPort 1050"};
orb = ORB.init(args, null) ;
org.omg.CORBA.Object nameServiceObj =
orb.resolve_initial_references("NameService") ;
nctx= NamingContextHelper.narrow(nameServiceObj);
NameComponent[] fullname = new NameComponent[2];
fullname[0] = new NameComponent("auction", "");
fullname[1] = new NameComponent(
"RegistrationBean", "");
org.omg.CORBA.Object cobject= nctx.resolve(fullname);
</PRE>
The <CODE>narrow</CODE> method, from the object <CODE>Helper</CODE> method, is generated
by the IDL compiler, which provides a detailed mapping to translate each CORBA field into
its respective Java language field. For example, the
<CODE>SellerBean.insertItem</CODE> method looks up a registration CORBA object
using the name <CODE>RegistrationBean</CODE>, and returns a
<CODE>RegistrationHome</CODE> object. With the <CODE>RegistrationHome</CODE> object, you can
return a Registration record by calling its <CODe>findByPrimaryKey</CODE> method.
<PRE>
org.omg.CORBA.Object cobject= nctx.resolve(fullname);
RegistrationHome regHome=
RegistrationHomeHelper.narrow(cobject);
RegistrationHome regRef =
RegistrationHomeHelper.narrow(
nctx.resolve(fullname));
RegistrationPKImpl rpk= new RegistrationPKImpl();
rpk.theuser(seller);
Registration newseller =
RegistrationHelper.narrow(
regRef.findByPrimaryKey(rpk));
if((newseller == null)||
(!newseller.verifyPassword(password))) {
return(Auction.INVALID_USER);
}
</PRE>
<A NAME="ior"></A>
<H3>Interoperable Object References (IOR)</H3>
Using a CORBA name service works for most of CORBA applications especially
when the object request brokers (ORBs) are supplied by one vendor. However,
you might find the name service is not completely compatible among all
ORBs,
and you could get a frustrating <CODE>COMM_FAILURE</CODE> message when the
CORBA client tries to connect to the CORBA server.
<P>
The solution is to use an Interoperable Object Reference (IOR) instead. An
IOR
is available in ORBs that support the Internet Inter-ORB protocol (IIOP).
It
contains the information that a naming service would keep for each object such as the
host and port where the object resides, a unique lookup key for the object
on that host, and what version of IIOP is supported.
<P>
<H4>IOR Server</H4>
To create an IOR all you do is call the <CODE>object_to_string</CODE>
method from the <CODE>ORB</CODE> class and pass it an instance of the object.
For example, to convert
the <CODE>RegistrationServer</CODE> object to an IOR, you need to
add the line <CODE>String ref = orb.object_to_string(rs);</CODE>
to the following code in the <CODE>main</CODE> program:
<PRE>
String[] orbargs= {"-ORBInitialPort 1050"};
ORB orb = ORB.init(orbargs, null);
RegistrationServer rs = new RegistrationServer();
//Add this line
String ref = orb.object_to_string(rs);
</PRE>
So, instead of retrieving this object information from a naming service, there is
another way for the server to send information to the client.
You can register the returned <CODE>String</CODE> with a substitute name
server, which can be a simple HTTP web server because the object
is already in a transmittable format.
<H4>IOR Client</H4>
This example uses an HTTP connection to convert the IOR string back into
an object. You call the <CODE>string_to_object</CODE> method from the
<CODE>ORB</CODE> class. This method requests the IOR from the <CODE>RegistrationServer</CODE>
and returns the IOR string. The <CODE>String</CODE> is
passed to the ORB using the <CODE>ORB.string_to_object</CODE> method,
and the ORB returns the remote object reference:
<PRE>
URL iorserver = new URL(
"http://server.com/servlet?object=registration");
URLConnection con = ioserver.openConnection();
BufferedReader br = new BufferReader(
new InputStreamReader(con.getInputStream));
String ref = br.readLine();
org.omg.CORBA.Object cobj = orb.string_to_object(ref);
RegistrationHome regHome =
RegistrationHomeHelper.narrow(cobj);
</PRE>
The substitute name server can keep persistent IOR records that
can survive a restart if needed.
<A NAME="rmi"></A>
<H3>Remote Method Invocation (RMI)</H3>
The Remote Method Invocation (RMI) API originally used its own communication
protocol called Java Remote Method Protocol (JRMP), which resulted in having its
own lookup service. Newer releases of RMI can now use the more ubiquitous IIOP protocol,
in addition to JRMP. RMI-IIOP is covered in the next section.
<P>
The JRMP RMI naming service is similar to other lookup and naming
services. The actual lookup is achieved by calling <CODE>Naming.lookup</CODE>
and passing a URL parameter to that method. The URL specifies the machine
name, an optional port where the RMI naming server, <CODE>rmiregistry</CODE>,
that knows about that object is running, and the remote object you want
to reference and call methods on.
<P>
For example:
<PRE>
SellerHome shome =
(SellerHome)Naming.lookup(
"rmi://appserver:1090/seller");
</PRE>
This code returns the remote <CODE>SellerHome</CODE> reference
<CODE>_stub</CODE>
from the object bound to the name <CODE>seller</CODE> on the machine called
<CODE>appserver</CODE>. The <CODE>rmi</CODE> part of the URL is optional
and you may have seen RMI URLs without it, but if you are using JNDI or
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -