Naming.lookup
method call is the most common mechanism by which
clients initially obtain references to remote servers. Remote references
may be obtained by other means, for example: all remote method calls
can return remote references. This is what Naming.lookup
does;
it uses a well-known stub to make a remote method call to the rmiregistry
,
which sends back the remote reference to the object requested by the lookup
method.
Every remote reference contains a server hostname and port number that allow clients to locate the virtual machine that is serving a particular remote object. Once an RMI client has a remote reference, the client will use the hostname and port provided in the reference to open a socket connection to the remote server.
Please note that with RMI the terms "client" and "server" can refer to the same Java program. A Java program that acts as an RMI server contains an exported remote object. An RMI client is a program that invokes one or more methods on a remote object in another Java Virtual Machine (JVM). If a JVM performs both of these functions, it may be referred to as an RMI client and an RMI server.
Q2: Why does my remote method or "callback" routine
fail with a nested java.net.UnknownHostException
?
UnknownHostException.
In order to generate functional remote references, RMI servers must
be able to supply a fully-qualified hostname or IP address that is resolvable
from all RMI clients. If an RMI program provides a remote callback
operation then that program serves an RMI object and consequently, must
be able to determine a resolvable hostname to use as its server hostname
in the remote references it passes to RMI clients. JVM's that make
calls to applets that serve remote objects may throw UnknownHostException
s
because the applet has failed to provide useable server hostname.
If your RMI application throws an UnknownHostException
, you
can look at the resulting stack trace to see if the hostname that the client
is using to contact its remote server is incorrect or not fully-qualified.
If necessary, you can set the java.rmi.server.hostname
property
on the server to the correct IP address or hostname of the server machine
and RMI will use this property's value to generate remote references to
the server.
UnknownHostException
?
java.rmi.server.hostname
property to the correct IP address of the RMI server machine. You
can also specify that your server use a fully-qualified hostname obtained
from a name service by setting the property:
java.rmi.server.useLocalHostname=true
java.net.InetAddress.getLocalHost()
to return
a fully-qualified domain name. InetAddress
objects initialized
local hostnames in a static block of code, performing a reverse lookup
on the local IP address to retrieve a local hostname. However, on
machines that were not connected to the network, this behavior caused the
program to hang while InetAddress
looked for a hostname that could
not be found.
JDK1.1.1-1.1.6 & JDK1.2beta2-3
To work around the JDK1.1 problem on stand-alone systems, InetAddress
was modified in JDK1.1.1 to only retrieve the [potentially unqualified]
hostname returned from a native system call, which did not attempt to consult
a name service. RMI was not modified to compensate for this change
since the property java.rmi.server.hostname
allowed users to override
incorrect hostnames provided by InetAddress
. RMI made no
attempt to consult a name service and could default to using unqualified
hostnames.
Later versions
To compensate for the many problems that were generated by the 1.1.1
change in functionality of InetAddress
, the following behavior
has been integrated into the most recent versions of the JDK:
A. By default, RMI uses the IP address of the server host as the server name for remote references.
B. If the property, java.rmi.server.hostname
is set, RMI will
use its value as the server hostname, and will not attempt to find a fully-qualified
domain name through any other method. This property takes precedence
over all other means of finding an RMI server name.
C. If the property, java.rmi.server.useLocalHostname
is set
to true
(by default, the value of this property is false),
RMI applies the following routine to obtain a hostname for the RMI server:
InetAddress.getLocalHost().getHostName()
method contains a "." character, then RMI will assume that
this value is the server's fully-qualified domain name and will use it
as the server hostname.
2. Otherwise, RMI will spawn a thread to query the local name
service for the fully-qualified domain name of the RMI server.
If the name service takes too long to return, or the name service returns
but its response does not contain a "." then RMI will use the server's
IP address obtained from InetAddress.getLocalHost().getHostAddress()
.
Users can override the default time (10 seconds or 10000 milliseconds) that RMI will look for a fully-qualified domain name by setting the following property:
sun.rmi.transport.tcp.localHostnameTimeOut=
<timeOutMillis>
where timeOutMillis is the time that RMI will wait in milliseconds.
For example:
java -Dsun.rmi.transport.tcp.localHostnameTimeOut=2000
MyServerApp
java.rmi.server.useLocalHostname
property
to true
. In general, hostnames are more stable than IP addresses.
Activatable remote objects tend to last longer than transient remote objects
(for example, survive a reboot). An RMI client will be more
likely to locate a remote object over a long period of time if it uses
a qualified hostname rather than an explicit IP address.