<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>Java(TM) Language Basics, Part 1, Lesson 8: Remote Method Invocation</TITLE>
<META NAME="AUTHOR" CONTENT="Monica Pawlan">
<META NAME="KEYWORDS" CONTENT="programming, basics, Java 2">
<META NAME="OWNER" CONTENT="Editorial/JDC">
<META NAME="revision" CONTENT="@(#)rmi.src 1.26 03/09/00 JDC">
<STYLE TYPE="text/css">
<!--
CODE {font-family: Courier, Monospace;
font-size: 12pt}
PRE {font-family: Courier, Monospace;
font-size: 11pt}
-->
</STYLE>
</HEAD>
<!-- Start Body Insert-->
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" ALINK="#FF0000" VLINK="#660066">
<!-- End Body Insert-->
<!-- Start PageTop Insert -->
<TABLE BORDER="0" CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR ALIGN="CENTER" VALIGN="TOP">
<TD WIDTH="157" ALIGN="LEFT">
<IMG SRC="/images/pixel.gif" HEIGHT="40" WIDTH="40" ALT="">
<A HREF="
http://java.sun.com/index.html"><IMG SRC="/images/javalogo52x88.gif" WIDTH="52" HEIGHT="88" ALT="Java Technology Home Page" BORDER="0"></A>
<BR>
<IMG SRC="/images/pixel.gif" WIDTH="157" HEIGHT="1" ALT=""></TD>
<TD>
<FORM NAME="seek1" METHOD="GET" ACTION="
http://search.java.sun.com/query.html">
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" WIDTH="100%">
<TR>
<TD ALIGN="RIGHT">
<IMG SRC="/images/stripelt.gif" WIDTH="6" HEIGHT="14" ALT=""></TD>
<TD WIDTH="100%">
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" WIDTH="100%">
<TR>
<TD BGCOLOR="#CC9966" WIDTH="100%">
<IMG SRC="/images/pixel.gif" HEIGHT="2" WIDTH="1" ALT=""></TD>
</TR>
<TR>
<TD>
<IMG SRC="/images/pixel.gif" HEIGHT="2" WIDTH="1" ALT=""></TD>
</TR>
<TR>
<TD BGCOLOR="#CC9966">
<IMG SRC="/images/pixel.gif" HEIGHT="2" WIDTH="1" ALT=""></TD>
</TR>
<TR>
<TD>
<IMG SRC="/images/pixel.gif" HEIGHT="2" WIDTH="1" ALT=""></TD>
</TR>
<TR>
<TD BGCOLOR="#CC9966">
<IMG SRC="/images/pixel.gif" HEIGHT="2" WIDTH="1" ALT=""></TD>
</TR>
<TR>
<TD>
<IMG SRC="/images/pixel.gif" HEIGHT="2" WIDTH="1" ALT=""></TD>
</TR>
<TR>
<TD BGCOLOR="#CC9966">
<IMG SRC="/images/pixel.gif" HEIGHT="2" WIDTH="1" ALT=""></TD>
</TR>
</TABLE>
</TD>
<TD ALIGN="LEFT">
<IMG SRC="/images/stripert.gif" WIDTH="6" HEIGHT="14" ALT=""></TD>
<TD>
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0">
<TR>
<TD VALIGN="CENTER">
<A HREF="
http://java.sun.com/a-z/index.html"><IMG SRC="/images/azindex.gif" BORDER="0" WIDTH="72" HEIGHT="11" ALT="A-Z Index"></A></TD>
<TD VALIGN="CENTER">
<FONT FACE="Helvetica" SIZE="1">
<INPUT TYPE="text" SIZE="15" MAXLENGTH="128" NAME=qt></FONT></TD>
<TD VALIGN="CENTER">
<INPUT TYPE="image" SRC="/images/search.button.gif" WIDTH="55" HEIGHT="14" ALT="Search" value="search" BORDER="0"></TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
</FORM>
<P>
<TABLE BORDER="0" WIDTH="100%" CELLPADDING="0" CELLSPACING="0">
<TR VALIGN="TOP">
<TD WIDTH="100%"><IMG SRC="/images/chiclet.row.gif" WIDTH="55"
HEIGHT="18" ALT=""></TD>
<TD ROWSPAN="4" ALIGN="RIGHT" WIDTH="152">
<A HREF="/developer/index.html"><IMG SRC="/images/developer.connection.header.gif" BORDER="0" HEIGHT="42" WIDTH="319" ALT="Java Developer Connection(SM)"></A></TD>
</TR>
<TR VALIGN="TOP">
<TD BGCOLOR="#FFFFFF" HEIGHT="1" WIDTH="100%">
<IMG SRC="/images/pixel.gif" HEIGHT="1" WIDTH="1" ALT=""></TD>
</TR>
<TR VALIGN="TOP">
<TD BGCOLOR="#CC9966" HEIGHT="1" WIDTH="100%">
<IMG SRC="/images/pixel.gif" HEIGHT="1" WIDTH="1" ALT=""></TD>
</TR>
<TR VALIGN="TOP">
<TD><A HREF="/developer/onlineTraining/"><IMG SRC="/images/online-training.gif" WIDTH="165" HEIGHT="22" ALT="Online Training" BORDER=0></A></TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
<!-- End PageTop Insert -->
<!-- Start NavBar Insert -->
<TABLE BORDER="0" CELLSPACING="0" CELLPADDING="3" BGCOLOR="#FFFFFF" WIDTH="157" ALIGN="LEFT">
<!-- tab categories -->
<TR>
<TD><A HREF="
http://java.sun.com/products/"><IMG SRC="/images/side.tab.products.gif" HEIGHT="15" WIDTH="130" BORDER="0" ALT="Downloads, APIs, Documentation"></A></TD>
</TR>
<TR>
<TD><A HREF="/developer/index.html"><IMG SRC="/images/side.tab.developer.gif" HEIGHT="15" WIDTH="130" BORDER="0" ALT="Java Developer Connection"></A></TD>
</TR>
<TR>
<TD><A HREF="/developer/infodocs/index.shtml"><IMG SRC="/images/side.tab.docs.gif" HEIGHT="15" WIDTH="130" BORDER="0" ALT="Tutorials, Tech Articles, Training"></A></TD>
</TR>
<TR>
<TD><A HREF="/developer/support/index.html"><IMG SRC="/images/side.tab.support.gif" HEIGHT="15" WIDTH="130" BORDER="0" ALT="Online Support"></A></TD>
</TR>
<TR>
<TD><A HREF="/developer/community/index.html"><IMG SRC="/images/side.tab.community.gif" HEIGHT="15" WIDTH="130" BORDER="0" ALT="Community Discussion"></A></TD>
</TR>
<TR>
<TD><A HREF="
http://java.sun.com/industry/"><IMG SRC="/images/side.tab.news.gif" HEIGHT="15" WIDTH="130" BORDER="0" ALT="News & Events from Everywhere"></A></TD>
</TR>
<TR>
<TD><A HREF="
http://java.sun.com/solutions"><IMG SRC="/images/side.tab.solutions.gif" HEIGHT="15" WIDTH="130" BORDER="0" ALT="Products from Everywhere"></A></TD>
</TR>
<TR>
<TD><A HREF="
http://java.sun.com/casestudies"><IMG SRC="/images/side.tab.case.gif" HEIGHT="15" WIDTH="130" BORDER="0" ALT="How Java Technology is Used Worldwide"></A></TD>
</TR>
<TR>
<TD> <DIV ALIGN="RIGHT">
<A HREF="/servlet/PrintPageServlet"><IMG SRC="/images/printbutton.gif" WIDTH="155" HEIGHT="25" ALT="Print Button" BORDER="0"></A>
</DIV>
</TD>
</TR>
<TR><TD> </TD></TR>
<!-- End NavBar Insert -->
<!-- START SUB-NAV -->
<TR>
<TD><!-- INSERT SUB-NAV INFO -->
</TD>
</TR>
<!-- END SUB-NAV -->
</TABLE>
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0">
<TR>
<TD>
<FONT FACE="Verdana, Arial, Helvetica, sans-serif">
<!-- Template Version 2.0 -->
<!-- ================== -->
<!-- Start Main Content -->
<!-- ================== -->
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0">
<TR>
<TD VALIGN="TOP">
<FONT FACE="Verdana, Arial, Helvetica, sans-serif">
<A NAME="top"></A>
<DIV ALIGN="RIGHT">
<FONT SIZE="-1"><A HREF="/developer/onlineTraining/index.html">Training Index</A></FONT>
<H2>Java<FONT SIZE="-2"><SUP>TM</SUP></FONT> Programming Language Basics, Part 1<BR>
<FONT SIZE="3">Lesson 8: Remote Method Invocation</FONT></H2>
<FONT SIZE="-1">[<A HREF="dba.html"><<BACK</A>] [<A HREF="index.html#contents">CONTENTS</A>] [<A HREF="end.html">NEXT>></A>]</FONT></DIV>
<P>
The Java<FONT SIZE="-2"><SUP>TM</SUP></FONT> Remote Method Invocation (RMI) application
programming interface (API) enables client and server
communications over the net. Typically, client
programs send requests to a server program, and the server
program responds to those requests.
<P>
A common example is sharing a word processing program
over a network. The word processor is installed on a server, and
anyone who wants to use it starts it from his or her machine by
double clicking an icon on the desktop or typing at the command line.
The invocation sends a request to a server program
for acess to the software, and the server program responds
by making the software available to the requestor.
<P>
<IMG SRC ="./Art/remote.gif" WIDTH="232" HEIGHT="97" ALT="" ALIGN="LEFT" HSPACE=10 VSPACE=10>
The RMI API lets you create a publicly accessible remote server object
that enables client and server communications through simple
method calls on the server object. Clients can easily communicate
directly with the server object and indirectly with each other through
the server object using Uniform Resource Locators (URLs) and
HyperText Transfer Protocol (HTTP).
<P>
This lesson explains how to use the RMI API to establish client and
server communications.
<UL>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">
<A HREF="#about">About the Example</A></FONT>
<UL>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">
<A HREF="#behave">Program Behavior</A></FONT>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">
<A HREF="#file">File Summary</A></FONT>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">
<A HREF="#compile">Compile the Example</A></FONT>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">
<A HREF="#regis">Start the RMI Registry</A></FONT>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">
<A HREF="#remote">Run the RemoteServer Server Object</A></FONT>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">
<A HREF="#1">Run the RMIClient1 Program</A></FONT>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">
<A HREF="#2">Run the RMIClient2 Program</A></FONT>
</UL>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">
<A HREF="#send">RemoteServer Class</A></FONT>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">
<A HREF="#int">Send Interface</A></FONT>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">
<A HREF="#first">RMIClient1 Class</A></FONT>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">
<A HREF="#second">RMIClient2 Class</A></FONT>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">
<A HREF="#more">More Information</A></FONT>
</UL>
<HR>
<A NAME="about"></A>
<H3>About the Example</H3>
This lesson converts the
<A HREF="./Code/FileIO.java">File Input and Output</A>
application from <A HREF="data.html">Lesson 6: File Access
and Permissions</A> to the RMI API.
<A NAME="behave"></A>
<H4>Program Behavior</H4>
The <A HREF="./Code/RMIClient1.java">RMIClient1</A> program presents
a simple user interface and prompts for text
input. When you click the <CODE>Click Me</CODE>
button, the text is sent to the
<A HREF="./Code/RMIClient2.java">RMIClient2</A> program
by way of the remote server object.
When you click the <CODE>Click Me</CODE> button on the
<CODE>RMIClient2</CODE> program, the text sent from
<CODE>RMIClient1</CODE> appears.
<P>
<IMG SRC="./Art/client1a.gif" WIDTH="199" HEIGHT="129" ALT="">
<IMG SRC="./Art/client2a.gif" WIDTH="199" HEIGHT="131" ALT="">
<P>
<DIV ALIGN="LEFT">First Instance of Client 1</DIV>
<P>
If you start a second instance of <CODE>RMIClient1</CODE> and
type in some text, that text is sent to <CODE>RMIClient2</CODE>
when you click the <CODE>Click Me</CODE> button. To see the text
received by <CODE>RMIClient2</CODE>, click its <CODE>Click Me</CODE>
button.
<P>
<IMG SRC="./Art/client1b.gif" WIDTH="199" HEIGHT="129" ALT="">
<IMG SRC="./Art/client2b.gif" WIDTH="199" HEIGHT="131" ALT="">
<P>
<DIV ALIGN="LEFT">Second Instance of Client 1</DIV>
<P>
<A NAME="file"></A>
<H4>File Summary</H4>
The example program consists of the RMIClient1 program,
remote object and interface, and the RMIClient2 program
as illustrated in the diagram. The corresponding
source code files for these executables are described
in the bullet list below.
<P>
<IMG SRC="./Art/rmi.gif" WIDTH="394" HEIGHT="161" ALT="">
<UL>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">
<A HREF="./Code/RMIClient1.java">RMIClient1.java</A>:
Client program that calls the <CODE>sendData</CODE>
method on the <CODE>RemoteServer</CODE> server object.</FONT>
<P>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">
<A HREF="./Code/RMIClient2.java">RMIClient2.java</A>:
Client program that calls the <CODE>getData</CODE>
method on the <CODE>RemoteServer</CODE> server object.</FONT>
<P>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">
<A HREF="./Code/RemoteServer.java">RemoteServer.java</A>:
Remote server object that implements <CODE>Send.java</CODE> and
the <CODE>sendData</CODE> and <CODE>getData</CODE>
remote methods.</FONT>
<P>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">
<A HREF="./Code/Send.java">Send.java</A>:
Remote interface that declares the <CODE>sendData</CODE> and
<CODE>getData</CODE> remote server methods.</FONT>
</UL>
In addition, the following
<A HREF="./Code/java.policy">java.policy</A>
security policy file grants the permissions needed to
run the example.
</FONT>
<PRE>
grant {
permission java.net.SocketPermission
"*:1024-65535",
"connect,accept,resolve";
permission java.net.SocketPermission
"*:80", "connect";
permission java.awt.AWTPermission
"accessEventQueue";
permission java.awt.AWTPermission
"showWindowWithoutWarningBanner";
};
</PRE>
<FONT FACE="Verdana, Arial, Helvetica, sans-serif">
<A NAME="compile"></A>
<H4>Compile the Example</H4>
These instructions assume development is in the <CODE>zelda</CODE>
home directory. The server program is compiled in the home directory
for user <CODE>zelda</CODE>, but copied to the <CODE>public_html</CODE>
directory for user <CODE>zelda</CODE> where it runs.
<P>
Here is the command sequence for
the Unix and Win32 platforms; an explanation follows.
</FONT>
<PRE>
<STRONG>Unix:</STRONG>
cd /home/zelda/classes
javac Send.java
javac RemoteServer.java
javac RMIClient2.java
javac RMIClient1.java
rmic -d . RemoteServer
cp RemoteServer*.class /home/zelda/public_html/classes
cp Send.class /home/zelda/public_html/classes
</PRE>
<FONT FACE="Verdana, Arial, Helvetica, sans-serif">
</FONT>
<PRE>
<STRONG>Win32:</STRONG>
cd \home\zelda\classes
javac Send.java
javac RemoteServer.java
javac RMIClient2.java
javac RMIClient1.java
rmic -d . RemoteServer
copy RemoteServer*.class \home\zelda\public_html\classes
copy Send.class \home\zelda\public_html\classes
</PRE>
<FONT FACE="Verdana, Arial, Helvetica, sans-serif">
The first two <CODE>javac</CODE> commands compile the
<CODE>RemoteServer</CODE> and <CODE>Send</CODE> class and
interface. The third <CODE>javac</CODE> command compiles the
<CODE>RMIClient2</CODE> class. The last <CODE>javac</CODE> command
compiles the <CODE>RMIClient1</CODE> class.
<P>
The next line runs the <CODE>rmic</CODE> command on the
<CODE>RemoteServer</CODE> server class. This command produces output
class files of the form <CODE>ClassName_Stub.class</CODE>
and <CODE>ClassName_Skel.class</CODE>. These output classes
let clients invoke methods on the <CODE>RemoteServer</CODE>
server object.
<P>
The first copy command moves the <CODE>RemoteServer</CODE>
class file with its associated <CODE>skel</CODE> and
<CODE>stub</CODE> class files to a publicly accessible
location in the <CODE>/home/zelda/public_html/classes</CODE>
directory, which is on the server machine,
so they can be publicly accessed and downloaded.
They are placed in the <CODE>public_html</CODE> directory to be
under the web server running on the server machine because
these files are accessed by client programs using URLs.
<P>
The second copy command moves the <CODE>Send</CODE> class file
to the same location for the same reason. The
<CODE>RMIClient1</CODE> and <CODE>RMIClient2</CODE> class files
are not made publicly accessible; they communicate from their
client machines using URLs
to access and download the remote object files in the
<CODE>public_html</CODE> directory.
<UL>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">
<CODE>RMIClient1</CODE> is invoked from a client-side directory
and uses the
server-side web server and client-side Java VM to download the
publicly accessible files. </FONT>
<P>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif"><CODE>RMIClient2</CODE> is invoked from a client-side directory
and uses the server-side web server and client-side Java VM to
download the publicly accessible files. </FONT>
</UL>
<P>
<IMG SRC="./Art/web.gif" WIDTH="372" HEIGHT="327" ALT="">
<A NAME="regis"></A>
<H4>Start the RMI Registry</H4>
Before you start the client programs, you must start the
RMI Registry, which is a server-side naming repository
that allows remote clients to get a reference to the remote
server object.
<P>
Before you start the RMI Registry, make sure the
shell or window in which you run the <CODE>rmiregistry</CODE>
command does not have a <CODE>CLASSPATH</CODE> environment variable
that points to the remote object classes, including
the <CODE>stub</CODE> and <CODE>skel</CODE> classes, anywhere
on your system. If the RMI Registry finds these classes
when it starts, it will not load them from the server-side Java
VM, which will create problems when clients try to download the
remote server classes.
<P>
<A NAME="registry"></A>
The following commands unset the <CODE>CLASSPATH</CODE> and
start the RMI Registry on the default
1099 port. You can specify a different port by
adding the port number as follows:
<CODE>rmiregistry 4444 &</CODE>. If you specify a different
port number, you must specify the same port number in
your <A HREF="#port">server-side</A> code as well.
</FONT>
<PRE>
<STRONG>Unix:</STRONG>
cd /home/zelda/public_html/classes
unsetenv CLASSPATH
rmiregistry &
</PRE>
<PRE>
<STRONG>Win32:</STRONG>
cd \home\zelda\public_html\classes
set CLASSPATH=
start rmiregistry
</PRE>
<FONT FACE="Verdana, Arial, Helvetica, sans-serif">
<BLOCKQUOTE>
<HR>
<STRONG>Note:</STRONG> You might want to set the
<CODE>CLASSPATH</CODE> back to its original
setting at this point.
<HR>
</BLOCKQUOTE>
<A NAME="remote"></A>
<H4>Run the RemoteServer Server Object</H4>
To run the example programs, start <CODE>RemoteServer</CODE>
first. If you start either <CODE>RMIClient1</CODE>
or <CODE>RMIClient2</CODE> first, they will not be able
to establish a connection because the remote
server object is not running.
<P>
In this example, <CODE>RemoteServer</CODE> is started from the
<CODE>/home/zelda/public_html/classes</CODE> directory.
<P>
The lines beginning at <CODE>java</CODE> should be all on
one line with spaces where the lines break. The properties
specified with the <CODE>-D</CODE>
option to the <CODE>java</CODE> interpreter command
are program attributes that manage the behavior of the program
for this invocation.
</FONT>
<PRE>
<STRONG>Unix:</STRONG>
cd /home/zelda/public_html/classes
java
-Djava.rmi.server.codebase=
http://kq6py/~zelda/classes
-Djava.rmi.server.hostname=kq6py.eng.sun.com
-Djava.security.policy=java.policy RemoteServer
</PRE>
<PRE>
<STRONG>Win32:</STRONG>
cd \home\zelda\public_html\classes
java -Djava.rmi.server.codebase=file:
c:\home\zelda\public_html\classes
-Djava.rmi.server.hostname=kq6py.eng.sun.com
-Djava.security.policy=java.policy RemoteServer
</PRE>
<FONT FACE="Verdana, Arial, Helvetica, sans-serif">
<UL>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">The
<CODE>java.rmi.server.codebase</CODE> property specifies
where the publicly accessible classes are located.</FONT>
<P>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">The
<CODE>java.rmi.server.hostname</CODE> property is the
complete host name of the server where the publicly accessible
classes reside.</FONT>
<P>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">The
<CODE>java.rmi.security.policy</CODE> property specifies
the <A HREF="./Code/java.policy">policy file</A>
with the permissions needed to run the remote server object and
access the remote server classes for download.</FONT>
<P>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">The class to execute
(<CODE>RemoteServer</CODE>).</FONT>
</UL>
<A NAME="1"></A>
<H4>Run the RMIClient1 Program</H4>
Here is the command sequence for the Unix and Win32 platforms;
an explanation follows.
<P>
In this example, <CODE>RMIClient1</CODE> is started from the
<CODE>/home/zelda/classes</CODE> directory.
<P>
The lines beginning at <CODE>java</CODE> should be all on
one line with spaces where the lines break.
Properties specified with the
<CODE>-D</CODE> option to the <CODE>java</CODE> interpreter
command are program attributes that manage the behavior of the program
for this invocation.
</FONT>
<PRE>
<STRONG>Unix:</STRONG>
cd /home/zelda/classes
java -Djava.rmi.server.codebase=
http://kq6py/~zelda/classes/
-Djava.security.policy=java.policy
RMIClient1 kq6py.eng.sun.com
</PRE>
<PRE>
<STRONG>Win32:</STRONG>
cd \home\zelda\classes
java -Djava.rmi.server.codebase=
file:c:\home\zelda\classes\
-Djava.security.policy=java.policy
RMIClient1 kq6py.eng.sun.com
</PRE>
<FONT FACE="Verdana, Arial, Helvetica, sans-serif">
<UL>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">The
<CODE>java.rmi.server.codebase</CODE> property specifies
where the publicly accessible classes for downloading are located.</FONT>
<P>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">The
<CODE>java.security.policy</CODE> property specifies
the <A HREF="./Code/java.policy">policy file</A>
with the permissions needed to run the client program and access
the remote server classes.</FONT>
<P>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">The client program
class to execute (<CODE>RMIClient1</CODE>),
and the host name of the server (<CODE>Kq6py</CODE>) where
the remote server classes are.</FONT>
</UL>
<A NAME="2"></A>
<H4>Run RMIClient2</H4>
Here is the command sequence for the Unix and Win32
platforms; an explanation follows.
<P>
In this example, <CODE>RMIClient2</CODE> is started from the
<CODE>/home/zelda/classes</CODE> directory.
<P>
The lines beginning at <CODE>java</CODE> should be all on
one line with spaces where the lines break. The properties
specified with the <CODE>-D</CODE>
option to the <CODE>java</CODE> interpreter command
are program attributes that manage the behavior of the program
for this invocation.
</FONT>
<PRE>
<STRONG>Unix:</STRONG>
cd /home/zelda/classes
java -Djava.rmi.server.codebase=
http://kq6py/~zelda/classes
-Djava.security.policy=java.policy
RMIClient2 kq6py.eng.sun.com
</PRE>
<PRE>
<STRONG>Win32:</STRONG>
cd \home\zelda\classes
java -Djava.rmi.server.codebase=
file:c:\home\zelda\public_html\classes
-Djava.security.policy=java.policy
RMIClient2 kq6py.eng.sun.com
</PRE>
<FONT FACE="Verdana, Arial, Helvetica, sans-serif">
<UL>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">The
<CODE>java.rmi.server.codebase</CODE> property specifies
where the publicly accessible classes are located.</FONT>
<P>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">The
<CODE>java.rmi.server.hostname</CODE> property is the
complete host name of the server where the publicly accessible
classes reside.</FONT>
<P>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">The
<CODE>java.rmi.security.policy</CODE> property specifies
the <A HREF="./Code/java.policy">policy file</A>
with the permissions needed to run the remote server object and
access the remote server classes for download.</FONT>
<P>
<LI><FONT FACE="Verdana, Arial, Helvetica, sans-serif">The class to
execute (<CODE>RMIClient2</CODE>).</FONT>
</UL>
<A NAME="send"></A>
<H3>RemoteServer Class</H3>
The <A HREF="./Code/RemoteServer.java">RemoteServer</A> class
extends <CODE>UnicastRemoteObject</CODE> and implements the
<CODE>sendData</CODE> and <CODE>getData</CODE> methods
declared in the <CODE>Send</CODE> interface. These
are the remotely accessible methods.
<P>
<CODE>UnicastRemoteObject</CODE> implements a number of
<CODE>java.lang.Object</CODE> methods for remote objects
and includes constructors and static methods to make
a remote object available to receive method calls from
client programs.
</FONT>
<PRE>
class RemoteServer extends UnicastRemoteObject
implements Send {
String text;
public RemoteServer() throws RemoteException {
super();
}
public void sendData(String gotText){
text = gotText;
}
public String getData(){
return text;
}
</PRE>
<FONT FACE="Verdana, Arial, Helvetica, sans-serif">
The <CODE>main</CODE> method installs the
<CODE>RMISecurityManager</CODE> and opens
a connection with a port on the machine
where the server program runs.
The security manager determines whether there is a policy file
that lets downloaded code perform tasks that require permissions.
<A NAME="port"></A>
The <CODE>main</CODE> method creates a name for the
the <CODE>RemoteServer</CODE> object that includes the
server name (<CODE>kq6py</CODE>) where the RMI Registry
and remote object run, and the name, <CODE>Send</CODE>.
<P>
By default the server name uses port 1099. If you
want to use a different port number, you can add it
with a colon as follows: <CODE>kq6py:4444</CODE>.
If you change the port here, you must start the
<A HREF="#registry">RMI Registry</A> with the same port number.
<P>
The <CODE>try</CODE> block creates an instance of
the <CODE>RemoteServer</CODE> class and binds the <CODE>name</CODE>
to the remote object to the RMI Registry with the
<CODE>Naming.rebind(name, remoteServer);</CODE> statement.
</FONT>
<PRE>
public static void main(String[] args){
if(System.getSecurityManager() == null) {
System.setSecurityManager(new
RMISecurityManager());
}
String name = "//kq6py.eng.sun.com/Send";
try {
Send remoteServer = new RemoteServer();
Naming.rebind(name, remoteServer);
System.out.println("RemoteServer bound");
} catch (java.rmi.RemoteException e) {
System.out.println("Cannot create
remote server object");
} catch (java.net.MalformedURLException e) {
System.out.println("Cannot look up
server object");
}
}
}
</PRE>
<FONT FACE="Verdana, Arial, Helvetica, sans-serif">
<BLOCKQUOTE>
<HR>
<STRONG>Note:</STRONG>
The <CODE>remoteServer</CODE> object is type
<CODE>Send</CODE> (see instance declaration at top of class)
because the interface available to clients is the
<CODE>Send</CODE> interface and its methods;
not the <CODE>RemoteServer</CODE> class and its
methods.
<HR>
</BLOCKQUOTE>
<A NAME="int"></A>
<H3>Send Interface</H3>
The <A HREF="./Code/Send.java">Send</A> interface declares the
methods implemented in the <CODE>RemoteServer</CODE>
class. These are the remotely accessible methods.
</FONT>
<PRE>
public interface Send extends Remote {
public void sendData(String text)
throws RemoteException;
public String getData() throws RemoteException;
}
</PRE>
<FONT FACE="Verdana, Arial, Helvetica, sans-serif">
<A NAME="first"></A>
<H3>RMIClient1 Class</H3>
The <A HREF="./Code/RMIClient1.java">RMIClient1</A> class establishes
a connection to the remote server program and sends
data to the remote server object. The code to do these things
is in the <CODE>actionPerformed</CODE> and <CODE>main</CODE> methods.
<H4>actionPerformed Method</H4>
The <CODE>actionPerformed</CODE> method calls the
<CODE>RemoteServer.sendData</CODE> method to send
text to the remote server object.
</FONT>
<PRE>
public void actionPerformed(ActionEvent event){
Object source = event.getSource();
if(source == button){
//Send data over socket
String text = textField.getText();
try{
send.sendData(text);
} catch (java.rmi.RemoteException e) {
System.out.println("Cannot send data to server");
}
textField.setText(new String(""));
}
}
</PRE>
<FONT FACE="Verdana, Arial, Helvetica, sans-serif">
<H4>main Method</H4>
The <CODE>main</CODE> method installs the
<CODE>RMISecurityManager</CODE> and creates a
<CODE>name</CODE> to use to look up the
<CODE>RemoteServer</CODE> server object.
The client uses
the <CODE>Naming.lookup</CODE> method to look up
the <CODE>RemoteServer</CODE> object in the
RMI Registry running on the server.
<P>
The security manager determines whether there is a policy file
that lets downloaded code perform tasks that require permissions.
</FONT>
<PRE>
RMIClient1 frame = new RMIClient1();
if(System.getSecurityManager() == null) {
System.setSecurityManager(new RMISecurityManager());
}
try {
//args[0] contains name of server where Send runs
String name = "//" + args[0] + "/Send";
send = ((Send) Naming.lookup(name));
} catch (java.rmi.NotBoundException e) {
System.out.println("Cannot look up
remote server object");
} catch(java.rmi.RemoteException e){
System.out.println("Cannot look up
remote server object");
} catch(java.net.MalformedURLException e) {
System.out.println("Cannot look up
remote server object");
}
</PRE>
<FONT FACE="Verdana, Arial, Helvetica, sans-serif">
<A NAME="second"></A>
<H3>RMIClient2 Class</H3>
The <A HREF="./Code/RMIClient2.java">RMIClient2</A> class
establishes a connection with the remote server program and
gets the data from the remote server object
and displays it. The code to do this is in the
<CODE>actionPerformed</CODE> and <CODE>main</CODE> methods.
<H4>actionPerformed Method</H4>
The <CODE>actionPerformed</CODE> method calls the
<CODE>RemoteServer.getData</CODE> method to retrieve
the data sent by the client program.
This data is appended to the <CODE>TextArea</CODE>
object for display to the end user on the server side.
</FONT>
<PRE>
public void actionPerformed(ActionEvent event) {
Object source = event.getSource();
if(source == button){
try{
String text = send.getData();
textArea.append(text);
} catch (java.rmi.RemoteException e) {
System.out.println("Cannot send data
to server");
}
}
}
}
</PRE>
<FONT FACE="Verdana, Arial, Helvetica, sans-serif">
<H4>main Method</H4>
The <CODE>main</CODE> method installs the
<CODE>RMISecurityManager</CODE> and creates a
<CODE>name</CODE> to use to look up the
<CODE>RemoteServer</CODE> server object. The
<CODE>args[0]</CODE> parameter provides the
name of the server host. The client uses
the <CODE>Naming.lookup</CODE> method to look up
the <CODE>RemoteServer</CODE> object in the
RMI Registry running on the server.
<P>
The security manager determines whether there is a policy file
that lets downloaded code perform tasks that require permissions.
</FONT>
<PRE>
RMIClient2 frame = new RMIClient2();
if(System.getSecurityManager() == null) {
System.setSecurityManager(new RMISecurityManager());
}
try {
String name = "//" + args[0] + "/Send";
send = ((Send) Naming.lookup(name));
} catch (java.rmi.NotBoundException e) {
System.out.println("Cannot look up remote
server object");
} catch(java.rmi.RemoteException e){
System.out.println("Cannot look up remote
server object");
} catch(java.net.MalformedURLException e) {
System.out.println("Cannot look up remote
server object");
}
</PRE>
<FONT FACE="Verdana, Arial, Helvetica, sans-serif">
<A NAME="more"></A>
<H3>More Information</H3>
You can find more information on the RMI API in the
<A HREF="
http://java.sun.com/docs/books/tutorial/rmi/index.html">RMI</A>
trail of
<A HREF="
http://java.sun.com/docs/books/tutorial/index.html">The
Java Tutorial</A>.
<P ALIGN="RIGHT">
<FONT SIZE="-1">[<A HREF="#top">TOP</A>]</FONT>
</FONT>
</TD>
</TR>
</TABLE>
<!-- ================ -->
<!-- End Main Content -->
<!-- ================ -->
</FONT>
</TD>
</TR>
</TABLE>
<!-- Copyright Insert -->
<BR CLEAR="ALL">
<FORM ACTION="/cgi-bin/search.cgi" METHOD="POST">
<TABLE WIDTH="100%" CELLPADDING="0" BORDER="0" CELLSPACING="5">
<TR>
<TD VALIGN="BOTTOM">
</TD>
</TR>
<A HREF="/servlet/PrintPageServlet"><IMG SRC="/images/printbutton.gif" WIDTH="155" HEIGHT="25" ALT="Print Button" BORDER="0"></A>
<CENTER>
<FONT SIZE="-1" COLOR="#999999" FACE="Verdana, Arial, Helvetica, sans-serif">
[ This page was updated: <!-- new date --> 31-Mar-2000 ]
</font></CENTER>
</TD>
</TR>
<TR>
<TD BGCOLOR="#CCCCCC">
<IMG SRC="/images/pixel.gif" HEIGHT="1" WIDTH="1" ALT=""></TD>
</TR>
<TR>
<TD>
<CENTER>
<FONT SIZE="-2" FACE="Verdana, Arial, Helvetica, sans-serif">
<A HREF="
http://java.sun.com/products/">Products & APIs</A> |
<A HREF="/developer/index.html">Developer Connection</A> |
<A HREF="/developer/infodocs/index.shtml">Docs & Training</A> |
<A HREF="/developer/support/index.html">Online Support</A><BR>
<A HREF="/developer/community/index.html">Community Discussion</A> |
<A HREF="
http://java.sun.com/industry/">Industry News</A> |
<A HREF="
http://java.sun.com/solutions">Solutions Marketplace</A> |
<A HREF="
http://java.sun.com/casestudies">Case Studies</A>
</FONT>
</CENTER>
</TD>
</TR>
<TR>
<TD BGCOLOR="#CCCCCC">
<IMG SRC="/images/pixel.gif" HEIGHT="1" WIDTH="1" ALT=""></TD>
</TR>
<TR>
<TD ALIGN="CENTER">
<FONT SIZE="-2" FACE="Verdana, Arial, Helvetica, sans-serif">
<A HREF="
http://java.sun.com/docs/glossary.html">Glossary</A> -
<A HREF="
http://java.sun.com/applets/">Applets</A> -
<A HREF="
http://java.sun.com/docs/books/tutorial/">Tutorial</A> -
<A HREF="
http://java.sun.com/jobs/">Employment</A> -
<A HREF="
http://java.sun.com/nav/business/">Business & Licensing</A> -
<A HREF="
http://java.sun.com/javastore/">Java Store</A> -
<A HREF="
http://java.sun.com/casestudies/">Java in the Real World</A>
</FONT>
</TD>
</TR>
<TR>
<TD>
<CENTER>
<FONT SIZE="-2" FACE="Verdana, Arial, Helvetica, sans-serif">
<a href="/siteinfo/faq.html">FAQ</a> |
<a href="/feedback/index.html">Feedback</a> |
<a href="
http://www.dynamicdiagrams.net/mapa/cgi-bin/help.tcl?db=javasoft&dest=
http://java.sun.com/">Map</a> |
<A HREF="
http://java.sun.com/a-z/index.html">A-Z Index</A>
</FONT>
</CENTER>
</TD>
</TR>
<TR>
<TD>
<TABLE WIDTH="100%" CELLPADDING="0" BORDER="0" CELLSPACING="0">
<TR>
<TD WIDTH="50%">
<FONT SIZE="-2" FACE="Verdana, Arial, Helvetica, sans-serif">
For more information on Java technology<BR>
and other software from Sun Microsystems, call:<BR>
</FONT>
<FONT SIZE="-1" FACE="Verdana, Arial, Helvetica, sans-serif">
(800) 786-7638<BR></FONT>
<FONT SIZE="-2" FACE="Verdana, Arial, Helvetica, sans-serif">
Outside the U.S. and Canada, dial your country's
<A HREF="
http://www.att.com/business_traveler/attdirecttollfree/">AT&T Direct Access Number</A> first.<BR>
</FONT>
</TD>
<TD ALIGN="RIGHT" WIDTH="50%">
<A HREF="
http://www.sun.com"><IMG SRC="/images/lgsun.gif" width="64" height="30" border="0" ALT="Sun Microsystems, Inc."></A><BR>
<FONT SIZE="-2" FACE="Verdana, Arial, Helvetica, sans-serif">
Copyright © 1995-2000
<A HREF="
http://www.sun.com">Sun Microsystems, Inc.</A><BR>
All Rights Reserved.
<A HREF="
http://www.sun.com/share/text/termsofuse.html">Terms of Use</A>.
<A HREF="
http://www.sun.com/privacy/">Privacy Policy</A>.
</FONT>
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
</FORM>
<!-- End Copyright Insert -->
</BODY>
</HTML>