<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Designing RMI Applications</title>
<link rel="stylesheet" type="text/css" href="../xslides-summary.css"></link>
<meta name="AUTHOR" content="Jose M Vidal"></meta>
<meta name="GENERATOR" content="xslides.el, written by J.M. Vidal"></meta>
</head>
<!--HEADER LEFT "http://jmvidal.cse.sc.edu/talks/rmidesign/" --> 
<body>  
<h1 class="slidelist">Designing RMI Applications</h1><div class="slidebody">
      We present some of the ideas from:
    <ul>
      <li>William Grosso, <span><a href="http://www.amazon.com/exec/obidos/ASIN/1565924525/multiagentcom/">Java
      RMI</a> [1]</span>, 2002. Chapters 5-10, 12-17, 19-20, 22.</li>
    </ul> 

      Code examples were downloaded from and belong to <span><a href="http://www.oreilly.com/catalog/javarmi/">O'Reilly</a> [2]</span>.
    </div><h2 id="sketch">1 Sketch a Rough Architecture</h2><div class="slidebody">
    <ul>

      <li>The first step in designing a distributed system is to
      sketch a rough architecture of your system.</li>
    </ul>
    <ol>
      <li>Figure out what you are going to build. Do your requirements
      analysis.</li>

      <li>Find a basic use case that will motivate the rough
      architecture.</li>

      <li>Figure out what you can safely ignore for now (often
      scalability and security).</li>

      <li>Determine which design decisions are forced by the
      environment.</li>

      <li>Narrow down the servers to as few as possible.</li>

    </ol>
  </div><h2 id="bankex">2 Bank Example</h2><div class="slidebody">
    <ul>
      
      <li>We will use as an example the construction of an ATM
      application.</li>

      <li>The basic use case is
	<ol>
	  <li>User walks up to ATM and enters password.</li>

	  <li>If password is correct user is allowed to make
	  transactions until card is removed.</li>

	  <li>User is given choices: get balance, withdraw money,
	  deposit money, transfer money.</li>

	  <li>After choosing an action the user is given a list of
	  valid accounts for that choice.</li>

	  <li>After a few transactions the user leaves.</li>

	</ol>
      </li>

      <li>The environmental constraints are that we must use the legacy
      database and the ATMs are physically distributed.</li>

    </ul>
    <center>
      <img src="bankex.png" alt="Bank example"/>
    </center>
    <ul>
      <li><b>Client</b> responsible for managing interaction with user,
	via GUI.</li>
      
      <li><b>Stub</b> implicitly handles connection.</li>
      
      <li><b>Registry</b> maintains mapping of human-readable names to
	server stubs and returns them when asked.</li>
      
      <li><b>Skeletons and launch code</b> do the work on the
	database.</li>
      
      <li><b>Servers</b> handle the business logic by running the
	skeletons, communicate with database.</li>
      
      <li><b>Database system</b> is responsible for long-term
	persistence and integrity of important data.</li>
    </ul>
  </div><h2 id="choices">3 Two Choices</h2><div class="slidebody">
    <ul>
      <li>We will consider two possible design choices. Which one is
      better?</li>
    </ul>
    <pre>

<span class="comment">//One instance of Bank for all clients
</span><span class="keyword">class</span> <span class="type">Bank</span> {
  <span class="jde-java-font-lock-modifier">public</span> <span class="type">Money</span> <span class="function-name">getBalance</span>(<span class="type">Account</span> <span class="variable-name">account</span>) <span class="keyword">throws</span> <span class="type">RemoteException</span>;
  <span class="jde-java-font-lock-modifier">public</span> <span class="type">void</span> <span class="function-name">makeDeposit</span>(<span class="type">Account</span> <span class="variable-name">account</span>)
    <span class="keyword">throws</span> <span class="type">RemoteException</span>, <span class="type">NegativeAmountException</span>;
  <span class="jde-java-font-lock-modifier">public</span> <span class="type">void</span> <span class="function-name">makeWithdrawal</span>(<span class="type">Account</span> <span class="variable-name">account</span>, <span class="type">Money</span> <span class="variable-name">amount</span>)
    <span class="keyword">throws</span> <span class="type">RemoteException</span>, <span class="type">OverdraftException</span>, <span class="type">NegativeAmountException</span>;
}

<span class="comment">//One instance of Account for each account
</span><span class="keyword">class</span> <span class="type">Account</span> {
  <span class="jde-java-font-lock-modifier">public</span> <span class="type">Money</span> <span class="function-name">getBalance</span>() <span class="keyword">throws</span> <span class="type">RemoteException</span>;
  <span class="jde-java-font-lock-modifier">public</span> <span class="type">void</span> <span class="function-name">makeDeposit</span>(<span class="type">Money</span> <span class="variable-name">amount</span>)
    <span class="keyword">throws</span> <span class="type">RemoteException</span>, <span class="type">NegativeAmountException</span>;
  <span class="jde-java-font-lock-modifier">public</span> <span class="type">void</span> <span class="function-name">makeWithdrawal</span>(<span class="type">Money</span> <span class="variable-name">amount</span>)
    <span class="keyword">throws</span> <span class="type">RemoteException</span>, <span class="type">OverdraftException</span>, <span class="type">NegativeAmountException</span>;
}
  
</pre>
  </div><h2 id="deciding">4 Choosing</h2><div class="slidebody">
    <ul>
      
      <li><a href="allslides.xml#c1">Does each instance of the server require
      a shared or scarce resource?</a></li>

      <li><a href="allslides.xml#c2">How well does the server replicate or
      scale to multiple machines?</a></li>

      <li><a href="allslides.xml#c3">Can a single server handle a typical
      client interaction?</a></li>

      <li><a href="allslides.xml#c4">How easy is it to make a server handle
      multiple simultaneous clients?</a></li>

      <li><a href="allslides.xml#c5">How easy is it to tell whether the code
      is correct?</a></li>

      <li><a href="allslides.xml#c6">How fatal is server failure?</a></li>
      
      <li><a href="allslides.xml#c7">How easy is it to add new
      functionality?</a></li>
      
      <li>So, <code>Account</code> seems to be the preferred
      implementation for this problem</li>

    </ul>
  </div><h3 id="c1">4.1 Does Each Instance Require Shared Resource?</h3><div class="slidebody">
    <ul>
      <li>Memory, in general, is not an issue because the amount
	needed is linear with the number of clients active. Also,
	we can use a factory if needed.</li>
      
      <li>Sockets are not a problem because RMI re-uses sockets
	between two JVMs, even if different objects (thanks to
	<a href="http://java.sun.com/j2se/1.4.2/docs/api/java/rmi/server/RemoteRef.html" class="javadoc" title="javadoc:java/rmi/server/RemoteRef"><code>RemoteRef</code></a>).</li>
      
      <li>The only possibility might be a log file, but then both
	choices would have to share one logfile.</li>
      
      <li><em>Advantage: neither</em></li>
    </ul>
  </div><h3 id="c2">4.2 How Well Server Scales or Replicates to Multiple Machines?</h3><div class="slidebody">      
    <ul>
      <li>Applicable when our needs grow beyond one JVM.</li>
      
      <li>We can think of a load-balancing server which
	distributes clients among a set of machines. We would need
	to divide our objects among the machines. </li>
      
      <li>The <code>Account</code> is easy. Since there are many
	of them we can re-write our launcher to register some of
	them with one machine, some with another, and so on.</li>
      
      <li>The <code>Bank</code> is very hard to spread out since
	two clients with two Banks (from different servers) could be
	trying to access the same account.</li>
      
      
      <li><em>Advantage: Account</em></li>
    </ul>
  </div><h3 id="c3">4.3 Is Single Server Enough?</h3><div class="slidebody">
    <ul>
      <li>If the client accesses multiple accounts serially its
	not a problem because RMI shares sockets, so the costs are
	the same in either case.</li>
      
      <li>If the client does a transfer from one account to
	another the Account classes will have trouble (it will be
	hard to implement) performing the single database operation
	needed.</li>
      
      <li><em>Advantage: Bank</em></li>
    </ul>
  </div><h3 id="c4">4.4 How to Handle Multiple Simultaneous Clients?</h3><div class="slidebody">
    <ul>
      <li>The smaller and simpler the server is, the easier it is
	to make it safely handle multiple clients.</li>
      <li><em>Advantage: Account</em></li>
    </ul>
  </div><h3 id="c5">4.5 Is Code Correct?</h3><div class="slidebody">
    <ul>
      <li>In general, the smaller the server (code) the easier to
	tell whether it is correct.</li>
      <li><em>Advantage: Account</em></li>
    </ul>
  </div><h3 id="c6">4.6 How Fatal is Server Crash?</h3><div class="slidebody">
    <ul>
      <li>If Bank crashes, all clients are affected.</li>
      
      <li>If an Account crashes, only that client is
	affected.</li>
      <li><em>Advantage: Account</em></li>
    </ul>
  </div><h3 id="c7">4.7 How Easy Adding Functionality?</h3><div class="slidebody">
    <ul>
      <li>Requirements are constantly changing.</li>
      
      <li>Smaller server are easier to modify and extend.</li>
      
      <li><em>Advantage: Account</em></li>
    </ul>
  </div><h2 id="interface">5 Writing the Interface</h2><div class="slidebody">
    <ul>
      <li><a href="allslides.xml#i1">Should we pass method objects?</a></li>
      
      <li><a href="allslides.xml#i2">Should we pass objects as arguments or
	  use primitive values?</a></li>
      
      <li><a href="allslides.xml#i3">Should we receive objects as return values or receive primitive values?</a></li>
      
      <li><a href="allslides.xml#i4">Do individual method calls waste bandwidth?</a></li>
      
      <li><a href="allslides.xml#i5">Is each conceptual operation a single method call?</a></li>
      
      <li><a href="allslides.xml#i6">Does the interface expose the right amount of metadata?</a></li>
      
      <li><a href="allslides.xml#i7">Have we identified a reasonable set of distributed exceptions?</a></li>
      
    </ul>
  </div><h3 id="i1">5.1 Should We Pass Method Objects?</h3><div class="slidebody">
      <pre>
<span class="jde-java-font-lock-modifier">public</span> <span class="keyword">interface</span> <span class="type">Account</span> <span class="keyword">extends</span> <span class="type">Remote</span> {
  <span class="jde-java-font-lock-modifier">public</span> <span class="type">Money</span> <span class="function-name">getBalance</span>() <span class="keyword">throws</span> <span class="type">RemoteException</span>;
  <span class="jde-java-font-lock-modifier">public</span> <span class="type">void</span> <span class="function-name">postTransaction</span>(<span class="type">Transaction</span> <span class="variable-name">transaction</span>)
    <span class="keyword">throws</span> <span class="type">RemoteException</span>, <span class="type">TransactionException</span>;
}
</pre>
    <ul>
      <li>Passing a method object will allow the addition of new
	functionality without changing the interface.</li>
      
      <li>Using methods lets the compiler catch more errors.</li>
      
      <li>Using methods makes the code easier to read.</li>
      
      <li>Using methods allows us to introduced focused
	exceptions.</li>
    </ul>
  </div><h3 id="i2">5.2 Pass Objects As Arguments or Use Primitive Values?</h3><div class="slidebody">
    <ul>
      <li>Objects are bigger than primitive values.</li>
      
      <li>Adding another property (data member) to an existing
	object is easy. The only code that needs modification is the
	object.</li>

      <li>Using the <code>Money</code> class seems a bit silly since
	we end up just sending an integer number of cents.</li>

      <li>However, there is an implicit assumption that we are talking
      about dollars. To make our ATM work across borders we will need
      the <code>Money</code> class.</li>
    </ul>
  </div><h3 id="i3">5.3 Return Values: Objects or Primitive Values?</h3><div class="slidebody">
    <ul>
      
      <li>The reason for returning objects is that you only get to
      return one thing.</li>

      <li>Remember, no call-by-reference of non-remote types with
      remote objects.</li>

      <li>You should usually prefer to return objects, or
      nothing.</li>
      
      <li>boolean return values are a possible exception. But, first
      consider if there is something else that needs returning and if
      exceptions might be a better solution (they usually are, but
      people are lazy and don't want to write another class).</li>

    </ul>
  </div><h3 id="i4">5.4 Do Individual Method Calls Waste Bandwidth?</h3><div class="slidebody">
    <ul>
      
      <li>Serialization makes deep copies. This can lead to many
      objects being serialized and sent over.</li>

      <li>Object types that can be of arbitrary size (e.g., a <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/Vector.html" class="javadoc" title="javadoc:java/util/Vector"><code>Vector</code></a> or
	  <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/ArrayList.html" class="javadoc" title="javadoc:java/util/ArrayList"><code>ArrayList</code></a>)
	  are usually a bad choice for a return
      type.
	<ul>
	  <li>They degrade perceived client performance.</li>

	  <li>They increase performance variance.</li>

	  <li>They involve a large, all-at-once network hit.</li>

	  <li>They involve a larger single-client commitment on the
	  part of the server.</li>

	  <li>They penalize client mistakes.</li>
	</ul>
      </li>
    </ul>
  </div><h3 id="i5">5.5 Is Each Conceptual Operation A Single Method Call? </h3><div class="slidebody">
    <ul>
      
      <li>An interface that is good for a local object because it has
	many small methods might be awful for a remote object because
	method calls are expensive.</li>

      <li>For a remote object try to make a method call for each
	"usage" of the object by grouping together smaller
	methods into one.</li>

      <li>If implementing an iterator, it should have an argument that
      tells it how many to fetch at a time. These would be stored in
      the local iterator object and handed out one-by-one with
      <code>getNext</code> call.</li>

    </ul>
  </div><h3 id="i6">5.6 Does The Interface Expose The Right Amount Of Metadata? </h3><div class="slidebody">
    <ul>
      
      <li><b>Functional methods</b> make the server do something.</li>

      <li><b>Descriptive methods</b> give more information about the
      server.</li>

      <li>Descriptive methods are useful because they allow the client
      to validate that the server can handle an operation, and they
      help the client when choosing from among various servers.</li>

      <li>Our Account interface could give information about the
      owner, account number, type of account, etc.</li>

    </ul>
  </div><h3 id="i7">5.7 Have We Identified A Reasonable Set Of Distributed Exceptions?</h3><div class="slidebody">
    <ul>

      <li>You want to return all the information the client needs to
      proceed.</li>

      <li>In the bank example, could try to withdraw more money than
      he has, or he could try to withdraw a negative amount.</li>

      <li>We have handled these two cases explicitly with
      <code>OverdraftException</code> and
      <code>NegativeAmountException</code>.</li>

      <li><code>OverdraftException</code> can also tell if the
      withdrawal succeeded.
	<pre>
<span class="jde-java-font-lock-modifier">public</span> <span class="keyword">class</span> <span class="type">OverdraftException</span> <span class="keyword">extends</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Exception.html" class="javadoc" title="javadoc:java/lang/Exception"><span class="type">Exception</span></a> {
  <span class="jde-java-font-lock-modifier">public</span> <span class="type">boolean</span> <span class="variable-name">withdrawalSucceeded</span>;
  <span class="jde-java-font-lock-modifier">public</span> <span class="type">OverdraftException</span>(<span class="type">boolean</span> <span class="variable-name">withrawalSucceeded</span>){
    <span class="keyword">this</span>.withrawalSucceeded  = withrawalSucceeded;
  }
  <span class="jde-java-font-lock-modifier">public</span> <span class="type">boolean</span> <span class="function-name">didWithdrawalSucceed</span>(){
    <span class="keyword">return</span> withrawalSucceeded;
  }
}
</pre>
      </li>

      <li>We probably also need exception for when a null is sent as
      argument, and when the argument is exactly 0.</li>

      <li>In general, the server should throw as specific exceptions
      as possible, while the client will probably only catch the
      higher-level exceptions.</li>

    </ul>
  </div><h2 id="dataobjects">6 Building Data Objects</h2><div class="slidebody">
    <ul>

      <li>Once you have the interfaces, the data objects should be
      easy to discern.</li>

      <li>Data objects don't have many functional methods, mostly just
      descriptive (getX) methods.</li>

    </ul>
    <pre>
<span class="keyword">import</span> <span class="jde-java-font-lock-package">java</span>.<span class="jde-java-font-lock-package">io</span>.<span class="jde-java-font-lock-number">*</span>;


<span class="jde-java-font-lock-modifier">public</span> <span class="keyword">class</span> <span class="type">Money</span> <span class="keyword">extends</span> <span class="type">ValueObject</span> {
  <span class="jde-java-font-lock-modifier">protected</span> <span class="type">int</span> <span class="variable-name">_cents</span>;

  <span class="jde-java-font-lock-modifier">public</span> <span class="type">Money</span>(<a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Integer.html" class="javadoc" title="javadoc:java/lang/Integer"><span class="type">Integer</span></a> <span class="variable-name">cents</span>) {
    <span class="keyword">this</span> (<span class="reference">cents</span>.intValue());
  }

  <span class="jde-java-font-lock-modifier">public</span> <span class="type">Money</span>(<span class="type">int</span> <span class="variable-name">cents</span>) {
    <span class="keyword">super</span> (cents + "<span class="string"> cents.</span>");
    _cents = cents;
  }

  <span class="jde-java-font-lock-modifier">public</span> <span class="type">int</span> <span class="function-name">getCents</span>() {
    <span class="keyword">return</span> _cents;
  }

  <span class="jde-java-font-lock-modifier">public</span> <span class="type">void</span> <span class="function-name">add</span>(<span class="type">Money</span> <span class="variable-name">otherMoney</span>) {
    _cents += <span class="reference">otherMoney</span>.getCents();
  }

  <span class="jde-java-font-lock-modifier">public</span> <span class="type">void</span> <span class="function-name">subtract</span>(<span class="type">Money</span> <span class="variable-name">otherMoney</span>) {
    _cents -= <span class="reference">otherMoney</span>.getCents();
  }

  <span class="jde-java-font-lock-modifier">public</span> <span class="type">boolean</span> <span class="function-name">greaterThan</span>(<span class="type">Money</span> <span class="variable-name">otherMoney</span>) {
    <span class="keyword">if</span> (_cents &gt; <span class="reference">otherMoney</span>.getCents()) {
      <span class="keyword">return</span> <span class="jde-java-font-lock-constant">true</span>;
    }
    <span class="keyword">return</span> <span class="jde-java-font-lock-constant">false</span>;
  }

  <span class="jde-java-font-lock-modifier">public</span> <span class="type">boolean</span> <span class="function-name">isNegative</span>() {
    <span class="keyword">return</span> _cents &lt; <span class="jde-java-font-lock-number">0</span>;
  }

  <span class="jde-java-font-lock-modifier">public</span> <span class="type">boolean</span> <span class="function-name">equals</span>(<a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html" class="javadoc" title="javadoc:java/lang/Object"><span class="type">Object</span></a> <span class="variable-name">object</span>) {
    <span class="keyword">if</span> (object <span class="keyword">instanceof</span> <span class="type">Money</span>) {
      <span class="type">Money</span> <span class="variable-name">otherMoney</span> = (<span class="type">Money</span>) object;

      <span class="keyword">return</span> (_cents == <span class="reference">otherMoney</span>.getCents());
    }
    <span class="keyword">return</span> <span class="jde-java-font-lock-constant">false</span>;
  }
}
</pre>

  </div><h2 id="serverimp">7 Server Implementation</h2><div class="slidebody">
    <pre>
<span class="keyword">import</span> <span class="jde-java-font-lock-package">java</span>.<span class="jde-java-font-lock-package">rmi</span>.<span class="jde-java-font-lock-package">server</span>.<span class="jde-java-font-lock-number">*</span>;

<span class="jde-java-font-lock-modifier">public</span> <span class="keyword">class</span> <span class="type">Account_Impl</span> <span class="keyword">extends</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/rmi/server/UnicastRemoteObject.html" class="javadoc" title="javadoc:java/rmi/server/UnicastRemoteObject"><span class="type">UnicastRemoteObject</span></a> <span class="keyword">implements</span> <span class="type">Account</span> {
  <span class="jde-java-font-lock-modifier">private</span> <span class="type">Money</span> <span class="variable-name">_balance</span>;
  <span class="jde-java-font-lock-modifier">public</span> <span class="type">Account_Impl</span>(<span class="type">Money</span> <span class="variable-name">startingBalance</span>)
    <span class="keyword">throws</span> <span class="type">RemoteException</span> {
    _balance = startingBalance;
  }

  <span class="jde-java-font-lock-modifier">public</span> <span class="type">Money</span> <span class="function-name">getBalance</span>()
    <span class="keyword">throws</span> <span class="type">RemoteException</span> {
    <span class="keyword">return</span> _balance;
  }

  <span class="jde-java-font-lock-modifier">public</span> <span class="type">void</span> <span class="function-name">makeDeposit</span>(<span class="type">Money</span> <span class="variable-name">amount</span>)
    <span class="keyword">throws</span> <span class="type">RemoteException</span>, <span class="type">NegativeAmountException</span> {
    checkForNegativeAmount(amount);
    <span class="reference">_balance</span>.add(amount);
    <span class="keyword">return</span>;
  }

  <span class="jde-java-font-lock-modifier">public</span> <span class="type">void</span> <span class="function-name">makeWithdrawal</span>(<span class="type">Money</span> <span class="variable-name">amount</span>)
    <span class="keyword">throws</span> <span class="type">RemoteException</span>, <span class="type">OverdraftException</span>, <span class="type">NegativeAmountException</span> {
    checkForNegativeAmount(amount);
    checkForOverdraft(amount);
    <span class="reference">_balance</span>.subtract(amount);
    <span class="keyword">return</span>;
  }

  <span class="jde-java-font-lock-modifier">private</span> <span class="type">void</span> <span class="function-name">checkForNegativeAmount</span>(<span class="type">Money</span> <span class="variable-name">amount</span>)
    <span class="keyword">throws</span> <span class="type">NegativeAmountException</span> {
    <span class="type">int</span> <span class="variable-name">cents</span> = <span class="reference">amount</span>.getCents();

    <span class="keyword">if</span> (<span class="jde-java-font-lock-number">0</span> &gt; cents) {
      <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">NegativeAmountException</span>();
    }
  }

  <span class="jde-java-font-lock-modifier">private</span> <span class="type">void</span> <span class="function-name">checkForOverdraft</span>(<span class="type">Money</span> <span class="variable-name">amount</span>)
    <span class="keyword">throws</span> <span class="type">OverdraftException</span> {
    <span class="keyword">if</span> (<span class="reference">amount</span>.greaterThan(_balance)) {
      <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">OverdraftException</span>(<span class="jde-java-font-lock-constant">false</span>);
    }
    <span class="keyword">return</span>;
  }
} 

</pre>
    <ul>
      
      <li>Extends <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/rmi/server/UnicastRemoteObject.html" class="javadoc" title="javadoc:java/rmi/server/UnicastRemoteObject"><code>UnicastRemoteObject</code></a></li>
    </ul>
  </div><h2 id="serverimp2">8 Server Implementation 2</h2><div class="slidebody">
      <pre>
<span class="keyword">import</span> <span class="jde-java-font-lock-package">java</span>.<span class="jde-java-font-lock-package">rmi</span>.<span class="jde-java-font-lock-package">server</span>.<span class="jde-java-font-lock-number">*</span>;
<span class="comment">/*
 The only difference between this and Account_Impl is that
 Account_Impl extends UnicastRemote.
 */</span>
<span class="jde-java-font-lock-modifier">public</span> <span class="keyword">class</span> <span class="type">Account_Impl2</span> <span class="keyword">implements</span> <span class="type">Account</span> {
  <span class="jde-java-font-lock-modifier">private</span> <span class="type">Money</span> <span class="variable-name">_balance</span>;
  <span class="jde-java-font-lock-modifier">public</span> <span class="type">Account_Impl2</span>(<span class="type">Money</span> <span class="variable-name">startingBalance</span>)
    <span class="keyword">throws</span> <span class="type">RemoteException</span> {
    _balance = startingBalance;
  }

  <span class="jde-java-font-lock-modifier">public</span> <span class="type">Money</span> <span class="function-name">getBalance</span>()
    <span class="keyword">throws</span> <span class="type">RemoteException</span> {
    <span class="keyword">return</span> _balance;
  }

  <span class="jde-java-font-lock-modifier">public</span> <span class="type">void</span> <span class="function-name">makeDeposit</span>(<span class="type">Money</span> <span class="variable-name">amount</span>)
    <span class="keyword">throws</span> <span class="type">RemoteException</span>, <span class="type">NegativeAmountException</span> {
    checkForNegativeAmount(amount);
    <span class="reference">_balance</span>.add(amount);
    <span class="keyword">return</span>;
  }

  <span class="jde-java-font-lock-modifier">public</span> <span class="type">void</span> <span class="function-name">makeWithdrawal</span>(<span class="type">Money</span> <span class="variable-name">amount</span>)
    <span class="keyword">throws</span> <span class="type">RemoteException</span>, <span class="type">OverdraftException</span>, <span class="type">NegativeAmountException</span> {
    checkForNegativeAmount(amount);
    checkForOverdraft(amount);
    <span class="reference">_balance</span>.subtract(amount);
    <span class="keyword">return</span>;
  }

  <span class="comment">/** We must define this function */</span>
  <span class="jde-java-font-lock-modifier">public</span> <span class="type">boolean</span> <span class="function-name">equals</span>(<a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html" class="javadoc" title="javadoc:java/lang/Object"><span class="type">Object</span></a> <span class="variable-name">object</span>) {
    <span class="comment">// three cases. Either it's us, or it's our stub, or it's
</span>    <span class="comment">// not equal.
</span>
    <span class="keyword">if</span> (object <span class="keyword">instanceof</span> <span class="type">Account_Impl2</span>) {
      <span class="keyword">return</span> (object == <span class="keyword">this</span>);
    }
    <span class="keyword">if</span> (object <span class="keyword">instanceof</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/rmi/server/RemoteStub.html" class="javadoc" title="javadoc:java/rmi/server/RemoteStub"><span class="type">RemoteStub</span></a>) {
      <span class="keyword">try</span> {
        <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/rmi/server/RemoteStub.html" class="javadoc" title="javadoc:java/rmi/server/RemoteStub"><span class="type">RemoteStub</span></a> <span class="variable-name">ourStub</span> = (<a href="http://java.sun.com/j2se/1.4.2/docs/api/java/rmi/server/RemoteStub.html" class="javadoc" title="javadoc:java/rmi/server/RemoteStub"><span class="type">RemoteStub</span></a>) <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/rmi/server/RemoteObject.html" class="javadoc" title="javadoc:java/rmi/server/RemoteObject"><span class="type">RemoteObject</span></a>.toStub(<span class="keyword">this</span>);

        <span class="keyword">return</span> <span class="reference">ourStub</span>.equals(object);
      } <span class="keyword">catch</span> (<span class="type">NoSuchObjectException</span> <span class="variable-name">e</span>) {
        <span class="comment">// we're not listening on a port, therefore it's not our
</span>        <span class="comment">// stub
</span>      }
    }
    <span class="keyword">return</span> <span class="jde-java-font-lock-constant">false</span>;
  }

  <span class="comment">/** We must define this function */</span>
  <span class="jde-java-font-lock-modifier">public</span> <span class="type">int</span> <span class="function-name">hashCode</span>() {
    <span class="keyword">try</span> {
      <span class="type">Remote</span> <span class="variable-name">ourStub</span> = <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/rmi/server/RemoteObject.html" class="javadoc" title="javadoc:java/rmi/server/RemoteObject"><span class="type">RemoteObject</span></a>.toStub(<span class="keyword">this</span>);

      <span class="keyword">return</span> <span class="reference">ourStub</span>.hashCode();
    } <span class="keyword">catch</span> (<span class="type">NoSuchObjectException</span> <span class="variable-name">e</span>) {
    }
    <span class="keyword">return</span> <span class="keyword">super</span>.hashCode();
  }
    
  <span class="jde-java-font-lock-modifier">private</span> <span class="type">void</span> <span class="function-name">checkForNegativeAmount</span>(<span class="type">Money</span> <span class="variable-name">amount</span>)
    <span class="keyword">throws</span> <span class="type">NegativeAmountException</span> {
    <span class="type">int</span> <span class="variable-name">cents</span> = <span class="reference">amount</span>.getCents();

    <span class="keyword">if</span> (<span class="jde-java-font-lock-number">0</span> &gt; cents) {
      <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">NegativeAmountException</span>();
    }
  }

  <span class="jde-java-font-lock-modifier">private</span> <span class="type">void</span> <span class="function-name">checkForOverdraft</span>(<span class="type">Money</span> <span class="variable-name">amount</span>)
    <span class="keyword">throws</span> <span class="type">OverdraftException</span> {
    <span class="keyword">if</span> (<span class="reference">amount</span>.greaterThan(_balance)) {
      <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">OverdraftException</span>(<span class="jde-java-font-lock-constant">false</span>);
    }
    <span class="keyword">return</span>;
  }
} 

</pre>
    <ul>
      <li>We must call <code>exportObject</code> after creating one of
	these.</li>

      <li>We must implement <code>equals()</code> and
      <code>hashCode()</code>. These are tricky to implement. The code
      here gets around that by creating a stub of itself and letting
      that stub to the work.</li>

      <li>If you want to implement a remote object that must extend
	another class, but still want the ease of extending <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/rmi/server/UnicastRemoteObject.html" class="javadoc" title="javadoc:java/rmi/server/UnicastRemoteObject"><code>UnicastRemoteObject</code></a>,
	you can use a <b>tie
	  server</b>.</li>
      
      <li>A <b>tie server</b> extends <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/rmi/server/UnicastRemoteObject.html" class="javadoc" title="javadoc:java/rmi/server/UnicastRemoteObject"><code>UnicastRemoteObject</code></a>
	and implements the remote interface. The implementation, however,
	simply forwards all method calls to the real server (cf. <span><a class="remote" href="http://www.wikipedia.org/wiki/Adapter_pattern" title="wikipedia:Adapter_pattern">Adapter
	pattern</a> [3]</span>).</li>
      
      <li>The real server can then extend some other class.</li>
      
    </ul>

  </div><h2 id="launch">9 Launch Code</h2><div class="slidebody">
    <ul>
      
      <li>When should servers be launched?</li>

      <li>When should servers be shutdown?</li>

      <li>When should server save their state to a persistent
      store?</li>

      <li>The launch script looks like:<pre>
start rmiregistry
start java -Djava.security.manager -Djava.security.policy="d:\\java.policy" 
   com.ora.rmibook.chapter9.applications.ImplLauncher Bob 10000 Alex 1223
</pre></li>

      <li>The actual launcher is:</li>
    </ul>

    <pre>
<span class="jde-java-font-lock-modifier">public</span> <span class="keyword">class</span> <span class="type">ImplLauncher</span> {
  <span class="jde-java-font-lock-modifier">public</span> <span class="jde-java-font-lock-modifier">static</span> <span class="type">void</span> <span class="function-name">main</span>(<a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html" class="javadoc" title="javadoc:java/lang/String"><span class="type">String</span></a>[] args) {
    <span class="type">Collection</span> <span class="variable-name">nameBalancePairs</span> = getNameBalancePairs(args);
    <span class="type">Iterator</span> <span class="variable-name">i</span> = <span class="reference">nameBalancePairs</span>.iterator();

    <span class="keyword">while</span> (<span class="reference">i</span>.hasNext()) {
      <span class="type">NameBalancePair</span> <span class="variable-name">nextNameBalancePair</span> = (<span class="type">NameBalancePair</span>) <span class="reference">i</span>.next();

      launchServer(nextNameBalancePair);
    }
  }

  <span class="jde-java-font-lock-modifier">private</span> <span class="jde-java-font-lock-modifier">static</span> <span class="type">void</span> <span class="function-name">launchServer</span>(<span class="type">NameBalancePair</span> <span class="variable-name">serverDescription</span>) {
    <span class="keyword">try</span> {
      <span class="type">Account_Impl</span> <span class="variable-name">newAccount</span> = <span class="keyword">new</span> <span class="type">Account_Impl</span>(<span class="reference">serverDescription</span>.balance);

      <span class="type">Naming</span>.rebind(<span class="reference">serverDescription</span>.name, newAccount);
      <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/System.html" class="javadoc" title="javadoc:java/lang/System"><span class="type">System</span></a>.<span class="reference">out</span>.println("<span class="string">Account </span>" + <span class="reference">serverDescription</span>.name + "<span class="string"> successfully launched.</span>");
    } <span class="keyword">catch</span> (<a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Exception.html" class="javadoc" title="javadoc:java/lang/Exception"><span class="type">Exception</span></a> <span class="variable-name">e</span>) {
    }
  }

  <span class="jde-java-font-lock-modifier">private</span> <span class="jde-java-font-lock-modifier">static</span> <span class="type">Collection</span> <span class="function-name">getNameBalancePairs</span>(<a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html" class="javadoc" title="javadoc:java/lang/String"><span class="type">String</span></a>[] args) {
    <span class="type">int</span> <span class="variable-name">i</span>;
    <span class="type">ArrayList</span> <span class="variable-name">returnValue</span> = <span class="keyword">new</span> <span class="type">ArrayList</span>();

    <span class="keyword">for</span> (i = <span class="jde-java-font-lock-number">0</span>; i &lt; <span class="reference">args</span>.length; i += <span class="jde-java-font-lock-number">2</span>) {
      <span class="type">NameBalancePair</span> <span class="variable-name">nextNameBalancePair</span> = <span class="keyword">new</span> <span class="type">NameBalancePair</span>();

      <span class="reference">nextNameBalancePair</span>.name = args[i];
      <span class="type">int</span> <span class="variable-name">cents</span> = (<span class="keyword">new</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Integer.html" class="javadoc" title="javadoc:java/lang/Integer"><span class="type">Integer</span></a>(args[i + <span class="jde-java-font-lock-number">1</span>])).intValue();

      <span class="reference">nextNameBalancePair</span>.balance = <span class="keyword">new</span> <span class="type">Money</span>(cents);
      <span class="reference">returnValue</span>.add(nextNameBalancePair);
    }
    <span class="keyword">return</span> returnValue;
  }

  <span class="jde-java-font-lock-modifier">private</span> <span class="jde-java-font-lock-modifier">static</span> <span class="keyword">class</span> <span class="type">NameBalancePair</span> {
    <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html" class="javadoc" title="javadoc:java/lang/String"><span class="type">String</span></a> <span class="variable-name">name</span>;
    <span class="type">Money</span> <span class="variable-name">balance</span>;
  }
}
</pre>

  </div><h2 id="client">10 Building the Client</h2><div class="slidebody">
    <ul>

      <li>Client should consume as few server resources as possible,
      for as short a time as is reasonable.</li>

      <li>Don't host connections to a server you are not using. Set
      that remote reference to null as soon as possible.</li>

      <li>Validate arguments on the client side whenever
      possible. Increase response time. Reduce server load.</li>

      <li>Most of the client is usually GUI code.</li>
    </ul>

    <pre>
<span class="keyword">import</span> <span class="jde-java-font-lock-package">java</span>.<span class="jde-java-font-lock-package">awt</span>.<span class="jde-java-font-lock-number">*</span>;
<span class="keyword">import</span> <span class="jde-java-font-lock-package">java</span>.<span class="jde-java-font-lock-package">awt</span>.<span class="jde-java-font-lock-package">event</span>.<span class="jde-java-font-lock-number">*</span>;
<span class="keyword">import</span> <span class="jde-java-font-lock-package">javax</span>.<span class="jde-java-font-lock-package">swing</span>.<span class="jde-java-font-lock-number">*</span>;
<span class="keyword">import</span> <span class="jde-java-font-lock-package">java</span>.<span class="jde-java-font-lock-package">rmi</span>.<span class="jde-java-font-lock-number">*</span>;

<span class="jde-java-font-lock-modifier">public</span> <span class="keyword">class</span> <span class="type">BankClient</span> {
  <span class="jde-java-font-lock-modifier">public</span> <span class="jde-java-font-lock-modifier">static</span> <span class="type">void</span> <span class="function-name">main</span>(<a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html" class="javadoc" title="javadoc:java/lang/String"><span class="type">String</span></a>[] args) {
    (<span class="keyword">new</span> <span class="type">BankClientFrame</span>()).show();
  }
}

<span class="jde-java-font-lock-modifier">public</span> <span class="keyword">class</span> <span class="type">BankClientFrame</span> <span class="keyword">extends</span> <span class="type">ExitingFrame</span> {
  <span class="jde-java-font-lock-modifier">private</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JTextField.html" class="javadoc" title="javadoc:javax/swing/JTextField"><span class="type">JTextField</span></a> <span class="variable-name">_accountNameField</span>;
  <span class="jde-java-font-lock-modifier">private</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JTextField.html" class="javadoc" title="javadoc:javax/swing/JTextField"><span class="type">JTextField</span></a> <span class="variable-name">_balanceTextField</span>;
  <span class="jde-java-font-lock-modifier">private</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JTextField.html" class="javadoc" title="javadoc:javax/swing/JTextField"><span class="type">JTextField</span></a> <span class="variable-name">_withdrawalTextField</span>;
  <span class="jde-java-font-lock-modifier">private</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JTextField.html" class="javadoc" title="javadoc:javax/swing/JTextField"><span class="type">JTextField</span></a> <span class="variable-name">_depositTextField</span>;
  <span class="jde-java-font-lock-modifier">private</span> <span class="type">Account</span> <span class="variable-name">_account</span>;

  <span class="jde-java-font-lock-modifier">protected</span> <span class="type">void</span> <span class="function-name">buildGUI</span>() {
    <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JPanel.html" class="javadoc" title="javadoc:javax/swing/JPanel"><span class="type">JPanel</span></a> <span class="variable-name">contentPane</span> = <span class="keyword">new</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JPanel.html" class="javadoc" title="javadoc:javax/swing/JPanel"><span class="type">JPanel</span></a>(<span class="keyword">new</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/awt/BorderLayout.html" class="javadoc" title="javadoc:java/awt/BorderLayout"><span class="type">BorderLayout</span></a>());

    <span class="reference">contentPane</span>.add(buildActionPanel(), <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/awt/BorderLayout.html" class="javadoc" title="javadoc:java/awt/BorderLayout"><span class="type">BorderLayout</span></a>.<span class="jde-java-font-lock-constant">CENTER</span>);
    <span class="reference">contentPane</span>.add(buildBalancePanel(), <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/awt/BorderLayout.html" class="javadoc" title="javadoc:java/awt/BorderLayout"><span class="type">BorderLayout</span></a>.<span class="jde-java-font-lock-constant">SOUTH</span>);
    setContentPane(contentPane);
    setSize(<span class="jde-java-font-lock-number">250</span>, <span class="jde-java-font-lock-number">100</span>);
  }

  <span class="jde-java-font-lock-modifier">private</span> <span class="type">void</span> <span class="function-name">resetBalanceField</span>() {
    <span class="keyword">try</span> {
      <span class="type">Money</span> <span class="variable-name">balance</span> = <span class="reference">_account</span>.getBalance();

      <span class="reference">_balanceTextField</span>.setText("<span class="string">Balance: </span>" + <span class="reference">balance</span>.toString());
    } <span class="keyword">catch</span> (<a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Exception.html" class="javadoc" title="javadoc:java/lang/Exception"><span class="type">Exception</span></a> <span class="variable-name">e</span>) {
      <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/System.html" class="javadoc" title="javadoc:java/lang/System"><span class="type">System</span></a>.<span class="reference">out</span>.println("<span class="string">Error occurred while getting account balance\n</span>" + e);
    }
  }

  <span class="jde-java-font-lock-modifier">private</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JPanel.html" class="javadoc" title="javadoc:javax/swing/JPanel"><span class="type">JPanel</span></a> <span class="function-name">buildActionPanel</span>() {
    <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JPanel.html" class="javadoc" title="javadoc:javax/swing/JPanel"><span class="type">JPanel</span></a> <span class="variable-name">actionPanel</span> = <span class="keyword">new</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JPanel.html" class="javadoc" title="javadoc:javax/swing/JPanel"><span class="type">JPanel</span></a>(<span class="keyword">new</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/awt/GridLayout.html" class="javadoc" title="javadoc:java/awt/GridLayout"><span class="type">GridLayout</span></a>(<span class="jde-java-font-lock-number">3</span>, <span class="jde-java-font-lock-number">3</span>));

    <span class="reference">actionPanel</span>.add(<span class="keyword">new</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JLabel.html" class="javadoc" title="javadoc:javax/swing/JLabel"><span class="type">JLabel</span></a>("<span class="string">Account Name:</span>"));
    _accountNameField = <span class="keyword">new</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JTextField.html" class="javadoc" title="javadoc:javax/swing/JTextField"><span class="type">JTextField</span></a>();
    <span class="reference">actionPanel</span>.add(_accountNameField);
    <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JButton.html" class="javadoc" title="javadoc:javax/swing/JButton"><span class="type">JButton</span></a> <span class="variable-name">getBalanceButton</span> = <span class="keyword">new</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JButton.html" class="javadoc" title="javadoc:javax/swing/JButton"><span class="type">JButton</span></a>("<span class="string">Get Balance</span>");

    <span class="reference">getBalanceButton</span>.addActionListener(<span class="keyword">new</span> <span class="type">GetBalanceAction</span>());
    <span class="reference">actionPanel</span>.add(getBalanceButton);
    <span class="reference">actionPanel</span>.add(<span class="keyword">new</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JLabel.html" class="javadoc" title="javadoc:javax/swing/JLabel"><span class="type">JLabel</span></a>("<span class="string">Withdraw</span>"));
    _withdrawalTextField = <span class="keyword">new</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JTextField.html" class="javadoc" title="javadoc:javax/swing/JTextField"><span class="type">JTextField</span></a>();
    <span class="reference">actionPanel</span>.add(_withdrawalTextField);
    <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JButton.html" class="javadoc" title="javadoc:javax/swing/JButton"><span class="type">JButton</span></a> <span class="variable-name">withdrawalButton</span> = <span class="keyword">new</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JButton.html" class="javadoc" title="javadoc:javax/swing/JButton"><span class="type">JButton</span></a>("<span class="string">Do it</span>");

    <span class="reference">withdrawalButton</span>.addActionListener(<span class="keyword">new</span> <span class="type">WithdrawAction</span>());
    <span class="reference">actionPanel</span>.add(withdrawalButton);
    <span class="reference">actionPanel</span>.add(<span class="keyword">new</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JLabel.html" class="javadoc" title="javadoc:javax/swing/JLabel"><span class="type">JLabel</span></a>("<span class="string">Deposit</span>"));
    _depositTextField = <span class="keyword">new</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JTextField.html" class="javadoc" title="javadoc:javax/swing/JTextField"><span class="type">JTextField</span></a>();
    <span class="reference">actionPanel</span>.add(_depositTextField);
    <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JButton.html" class="javadoc" title="javadoc:javax/swing/JButton"><span class="type">JButton</span></a> <span class="variable-name">depositButton</span> = <span class="keyword">new</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JButton.html" class="javadoc" title="javadoc:javax/swing/JButton"><span class="type">JButton</span></a>("<span class="string">Do it</span>");

    <span class="reference">depositButton</span>.addActionListener(<span class="keyword">new</span> <span class="type">DepositAction</span>());
    <span class="reference">actionPanel</span>.add(depositButton);
    <span class="keyword">return</span> actionPanel;
  }

  <span class="jde-java-font-lock-modifier">private</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JPanel.html" class="javadoc" title="javadoc:javax/swing/JPanel"><span class="type">JPanel</span></a> <span class="function-name">buildBalancePanel</span>() {
    <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JPanel.html" class="javadoc" title="javadoc:javax/swing/JPanel"><span class="type">JPanel</span></a> <span class="variable-name">balancePanel</span> = <span class="keyword">new</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JPanel.html" class="javadoc" title="javadoc:javax/swing/JPanel"><span class="type">JPanel</span></a>(<span class="keyword">new</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/awt/GridLayout.html" class="javadoc" title="javadoc:java/awt/GridLayout"><span class="type">GridLayout</span></a>(<span class="jde-java-font-lock-number">1</span>, <span class="jde-java-font-lock-number">2</span>));

    <span class="reference">balancePanel</span>.add(<span class="keyword">new</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JLabel.html" class="javadoc" title="javadoc:javax/swing/JLabel"><span class="type">JLabel</span></a>("<span class="string">Current Balance:</span>"));
    _balanceTextField = <span class="keyword">new</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JTextField.html" class="javadoc" title="javadoc:javax/swing/JTextField"><span class="type">JTextField</span></a>();
    <span class="reference">_balanceTextField</span>.setEnabled(<span class="jde-java-font-lock-constant">false</span>);
    <span class="reference">balancePanel</span>.add(_balanceTextField);
    <span class="keyword">return</span> balancePanel;
  }

  <span class="jde-java-font-lock-modifier">private</span> <span class="type">void</span> <span class="function-name">getAccount</span>() {
    <span class="keyword">try</span> {
      _account = (<span class="type">Account</span>) <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/rmi/Naming.html" class="javadoc" title="javadoc:java/rmi/Naming"><span class="type">Naming</span></a>.lookup(<span class="reference">_accountNameField</span>.getText());
    } <span class="keyword">catch</span> (<a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Exception.html" class="javadoc" title="javadoc:java/lang/Exception"><span class="type">Exception</span></a> <span class="variable-name">e</span>) {
      <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/System.html" class="javadoc" title="javadoc:java/lang/System"><span class="type">System</span></a>.<span class="reference">out</span>.println("<span class="string">Couldn't find account. Error was \n </span>" + e);
      <span class="reference">e</span>.printStackTrace();
    }
    <span class="keyword">return</span>;
  }

  <span class="jde-java-font-lock-modifier">private</span> <span class="type">void</span> <span class="function-name">releaseAccount</span>() {
    _account = <span class="jde-java-font-lock-constant">null</span>;
  }

  <span class="jde-java-font-lock-modifier">private</span> <span class="type">Money</span> <span class="function-name">readTextField</span>(<a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JTextField.html" class="javadoc" title="javadoc:javax/swing/JTextField"><span class="type">JTextField</span></a> <span class="variable-name">moneyField</span>) {
    <span class="keyword">try</span> {
      <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Float.html" class="javadoc" title="javadoc:java/lang/Float"><span class="type">Float</span></a> <span class="variable-name">floatValue</span> = <span class="keyword">new</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Float.html" class="javadoc" title="javadoc:java/lang/Float"><span class="type">Float</span></a>(<span class="reference">moneyField</span>.getText());
      <span class="type">float</span> <span class="variable-name">actualValue</span> = <span class="reference">floatValue</span>.floatValue();
      <span class="type">int</span> <span class="variable-name">cents</span> = (<span class="type">int</span>) (actualValue * <span class="jde-java-font-lock-number">100</span>);

      <span class="keyword">return</span> <span class="keyword">new</span> <span class="type">PositiveMoney</span>(cents);
    } <span class="keyword">catch</span> (<a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Exception.html" class="javadoc" title="javadoc:java/lang/Exception"><span class="type">Exception</span></a> <span class="variable-name">e</span>) {
      <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/System.html" class="javadoc" title="javadoc:java/lang/System"><span class="type">System</span></a>.<span class="reference">out</span>.println("<span class="string">Field doesn't contain a valid value</span>");
    }
    <span class="keyword">return</span> <span class="jde-java-font-lock-constant">null</span>;
  }

  <span class="jde-java-font-lock-modifier">private</span> <span class="keyword">class</span> <span class="type">GetBalanceAction</span> <span class="keyword">implements</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/awt/event/ActionListener.html" class="javadoc" title="javadoc:java/awt/event/ActionListener"><span class="type">ActionListener</span></a> {
    <span class="jde-java-font-lock-modifier">public</span> <span class="type">void</span> <span class="function-name">actionPerformed</span>(<a href="http://java.sun.com/j2se/1.4.2/docs/api/java/awt/event/ActionEvent.html" class="javadoc" title="javadoc:java/awt/event/ActionEvent"><span class="type">ActionEvent</span></a> <span class="variable-name">event</span>) {
      <span class="keyword">try</span> {
        getAccount();
        resetBalanceField();
        releaseAccount();
      } <span class="keyword">catch</span> (<a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Exception.html" class="javadoc" title="javadoc:java/lang/Exception"><span class="type">Exception</span></a> <span class="variable-name">exception</span>) {
        <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/System.html" class="javadoc" title="javadoc:java/lang/System"><span class="type">System</span></a>.<span class="reference">out</span>.println("<span class="string">Couldn't talk to account. Error was \n </span>" + exception);
        <span class="reference">exception</span>.printStackTrace();
      }
    }
  }


  <span class="jde-java-font-lock-modifier">private</span> <span class="keyword">class</span> <span class="type">WithdrawAction</span> <span class="keyword">implements</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/awt/event/ActionListener.html" class="javadoc" title="javadoc:java/awt/event/ActionListener"><span class="type">ActionListener</span></a> {
    <span class="jde-java-font-lock-modifier">public</span> <span class="type">void</span> <span class="function-name">actionPerformed</span>(<a href="http://java.sun.com/j2se/1.4.2/docs/api/java/awt/event/ActionEvent.html" class="javadoc" title="javadoc:java/awt/event/ActionEvent"><span class="type">ActionEvent</span></a> <span class="variable-name">event</span>) {
      <span class="keyword">try</span> {
        getAccount();
        <span class="type">Money</span> <span class="variable-name">withdrawalAmount</span> = readTextField(_withdrawalTextField);

        <span class="reference">_account</span>.makeWithdrawal(withdrawalAmount);
        <span class="reference">_withdrawalTextField</span>.setText("");
        resetBalanceField();
        releaseAccount();
      } <span class="keyword">catch</span> (<a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Exception.html" class="javadoc" title="javadoc:java/lang/Exception"><span class="type">Exception</span></a> <span class="variable-name">exception</span>) {
        <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/System.html" class="javadoc" title="javadoc:java/lang/System"><span class="type">System</span></a>.<span class="reference">out</span>.println("<span class="string">Couldn't talk to account. Error was \n </span>" + exception);
        <span class="reference">exception</span>.printStackTrace();
      }
    }
  }


  <span class="jde-java-font-lock-modifier">private</span> <span class="keyword">class</span> <span class="type">DepositAction</span> <span class="keyword">implements</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/awt/event/ActionListener.html" class="javadoc" title="javadoc:java/awt/event/ActionListener"><span class="type">ActionListener</span></a> {
    <span class="jde-java-font-lock-modifier">public</span> <span class="type">void</span> <span class="function-name">actionPerformed</span>(<a href="http://java.sun.com/j2se/1.4.2/docs/api/java/awt/event/ActionEvent.html" class="javadoc" title="javadoc:java/awt/event/ActionEvent"><span class="type">ActionEvent</span></a> <span class="variable-name">event</span>) {
      <span class="keyword">try</span> {
        getAccount();
        <span class="type">Money</span> <span class="variable-name">depositAmount</span> = readTextField(_depositTextField);

        <span class="reference">_account</span>.makeDeposit(depositAmount);
        <span class="reference">_depositTextField</span>.setText("");
        resetBalanceField();
        releaseAccount();
      } <span class="keyword">catch</span> (<a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Exception.html" class="javadoc" title="javadoc:java/lang/Exception"><span class="type">Exception</span></a> <span class="variable-name">exception</span>) {
        <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/System.html" class="javadoc" title="javadoc:java/lang/System"><span class="type">System</span></a>.<span class="reference">out</span>.println("<span class="string">Couldn't talk to account. Error was \n </span>" + exception);
        <span class="reference">exception</span>.printStackTrace();
      }
    }
  }
}
</pre>
  </div><h2 id="serialization">11 Serialization</h2><div class="slidebody">
      <ul>
	<li>In Java we <dfn>serialization</dfn> refers to the process
	of turning an object into something that can be written to a
	stream. </li>

	<li>More generally, we call it <dfn>marshalling</dfn>. </li>

      </ul>
    </div><h3 id="usingserialization">11.1 Using Serialization</h3><div class="slidebody">
      <ul>
	<li>You can place any object into a stream by simply
<pre>
<span class="type">FileOutputStream</span> <span class="variable-name">underlyingStream</span> = <span class="keyword">new</span> <span class="type">FileOutputStream</span>(&quot;<span class="string">/tmp/file</span>&quot;);
<span class="type">ObjectOutputStream</span> <span class="variable-name">serializer</span> = <span class="keyword">new</span> <span class="type">ObjectOutputStream</span>(underlyingStream);
<span class="reference">serializer</span>.writeObject(serializableObject);</pre>

 </li>

	<li>Later, you can read it with
<pre>
<span class="type">FileInputStream</span> <span class="variable-name">underlyingStream</span> = <span class="keyword">new</span> <span class="type">FileInputStream</span>(&quot;<span class="string">/tmp/file</span>&quot;);
<span class="type">ObjectInputStream</span> <span class="variable-name">deserializer</span> = <span class="keyword">new</span> <span class="type">ObjectInputStream</span>(underlyingStream);
<span class="type">Object</span> <span class="variable-name">deserializedObject</span> = <span class="reference">deserializer</span>.readObject();
<span class="comment">//hmmmm, must typecast deserializerObject but, to what?</span></pre>

</li>

      </ul>
    </div><h3 id="makingaclassserializable">11.2 Making a Class Serializable</h3><div class="slidebody">
      <ol>
	<li>Implement the <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/io/Serializable.html" class="javadoc" title="javadoc:java/io/Serializable"><code>Serializable</code></a>
	interface.
	  <ol>
	    <li>Add <code>implements Serializable</code> to class definition. </li>
	  </ol>
	</li>

	<li>Make sure that <a href="allslides.xml#serializationofinstance">instance-level locally defined state is
	serialized properly</a>. </li>

	<li>Make sure that <a href="allslides.xml#ensuresuperclassstateishandledcorrectly">superclass
	state is properly serialized</a>. </li>

	<li><a href="allslides.xml#overrideequalsandhashcode">Override <code>equals()</code>  and <code>hashCode()</code></a>.</li>
      </ol>
    </div><h4 id="serializationofinstance">11.2.1 Ensure Serialization of Instance-Level State</h4><div class="slidebody">
      <ul>
	<li>The non-static member variables contain the instance-level
	state. </li>

	<li>If they are primitive or serializable then its OK. </li>

	<li>Your classes might not be serializable. Also, Java classes
	such as <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/ArrayList.html" class="javadoc" title="javadoc:java/util/ArrayList"><code>ArrayList</code></a>
	are not serializable! </li>

	<li>Your choices are: </li>
      </ul>
      <ol>
	<li>Make the variable <code>transient</code>:
<pre>
<span class="keyword">private</span> <span class="keyword">transient</span> <span class="type">Object</span> <span class="variable-name">myobject</span>[];</pre>
so it will not get serialized (be careful!)

</li>

	<li>Declare which variables should be stored by defining a special variable:
<pre>
<span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">ObjectSreamField</span>[] <span class="variable-name">serialPersistentFields</span> =
    { <span class="keyword">new</span> <span class="type">ObjectStreamField</span>(&quot;<span class="string">size</span>&quot;, <span class="reference">Integer</span>.Type), ... };</pre>

 </li>

	<li>Do your own serialization by implementing
<pre>
<span class="keyword">private</span> <span class="type">void</span> <span class="function-name">writeObject</span>(<span class="reference">java</span>.<span class="reference">io</span>.<span class="type">ObjectOutputStream</span> <span class="variable-name">out</span>) <span class="keyword">throws</span> <span class="type">IOException</span>;
<span class="keyword">private</span> <span class="type">void</span> <span class="function-name">readOject</span>(<span class="reference">java</span>.<span class="reference">io</span>.<span class="type">ObjectInputStream</span> <span class="variable-name">in</span>) 
       <span class="keyword">throws</span> <span class="type">IOException</span>, <span class="type">ClassNotFoundException</span>;</pre>

	these methods can invoke <code>defaultWriteObject()</code> to
	invoke default serialization on the non-transient members.</li>
      </ol>
    </div><h4 id="ensuresuperclassstateishandledcorrectly">11.2.2 Ensure Superclass State is Handled Correctly</h4><div class="slidebody">
      <ul>
	<li>If superclass is serializable then relax. </li>

	<li>Else if superclass maintains state then you can 
	  <ol>
	    <li>Use <code>serialPersistentFields</code> to tell
	    serialization about the parent's fields that need to be
	    serialized.</li>

	    <li>Write your own <code>writeObject()</code> and
	    <code>readObject()</code>. </li>
	  </ol>
	</li>

	<li>Also, it must have a zero-argument constructor (for de-serialization). </li>
      </ul>
    </div><h4 id="overrideequalsandhashcode">11.2.3 Override equals() and hashCode()</h4><div class="slidebody">
      <ul>
	<li>The default implementations use the object's
	location. </li>

	<li>After being deserialized, you have two identical copies
	which you might want to be <code>equals()</code> and produce
	the same <code>hashCode()</code>.</li>
      </ul>
    </div><h2 id="threading">12 Threading</h2><div class="slidebody">
    <ul>

      <li>Start with code that works for a single client.</li>

      <li><a href="allslides.xml#syncall">Ensure data integrity.</a></li>

      <li><a href="allslides.xml#mintime">Minimize time in synchronized blocks.</a></li>

      <li><a href="allslides.xml#container">Be careful when using container classes.</a></li>

      <li><a href="allslides.xml#usecontainer">Use containers to mediate inter-thread communication.</a></li>

      <li>Immutable objects are automatically threadsafe.
	<ul>
	  <li><code>String</code></li>
	</ul>
      </li>

      <li>Always have a safe way to stop your threads.
	<ul>
	  <li>Release all locks and resources before quitting.</li>
	</ul>
      </li>

      <li>Background threads should have low priority.</li>

      <li>Pay careful attention to what you serialize.
	<ul>
	  <li>Serialization takes time and objects could change in the meantime.</li>
	</ul>
      </li>

      <li>Use threading to reduce response-time variance.
	<ul>
	  <li>Starting a new thread can allow you to return to client quickly (e.g., web server).</li>
	</ul>
      </li>

      <li>Limit the number of objects a thread touches.
	<ul>
	  <li>Make it easier to debug.</li>
	</ul>
      </li>

      <li>Acquire locks in a fixed order.</li>

      <li>User worker threads to prevent deadlocks.</li>

    </ul>
  </div><h3 id="syncall">12.1 Ensure Data Integrity</h3><div class="slidebody">
    <ul>
      <li>Avoid either excessive or inadequate synchronization.</li>

      <li>We can try to synch everything:</li>
    </ul>
      <pre>
<span class="keyword">import</span> <span class="jde-java-font-lock-package">java</span>.<span class="jde-java-font-lock-package">rmi</span>.<span class="jde-java-font-lock-number">*</span>;
<span class="keyword">import</span> <span class="jde-java-font-lock-package">java</span>.<span class="jde-java-font-lock-package">rmi</span>.<span class="jde-java-font-lock-package">server</span>.<span class="jde-java-font-lock-number">*</span>;

<span class="jde-java-font-lock-modifier">public</span> <span class="keyword">class</span> <span class="type">Account_Impl</span> <span class="keyword">extends</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/rmi/server/UnicastRemoteObject.html" class="javadoc" title="javadoc:java/rmi/server/UnicastRemoteObject"><span class="type">UnicastRemoteObject</span></a> <span class="keyword">implements</span> <span class="type">Account</span> {
  <span class="jde-java-font-lock-modifier">private</span> <span class="type">Money</span> <span class="variable-name">_balance</span>;

  <span class="jde-java-font-lock-modifier">public</span> <span class="jde-java-font-lock-modifier">synchronized</span> <span class="type">Money</span> <span class="function-name">getBalance</span>()
    <span class="keyword">throws</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/rmi/RemoteException.html" class="javadoc" title="javadoc:java/rmi/RemoteException"><span class="type">RemoteException</span></a> {
    <span class="keyword">return</span> _balance;
  }

  <span class="jde-java-font-lock-modifier">public</span> <span class="jde-java-font-lock-modifier">synchronized</span> <span class="type">void</span> <span class="function-name">makeDeposit</span>(<span class="type">Money</span> <span class="variable-name">amount</span>)
    <span class="keyword">throws</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/rmi/RemoteException.html" class="javadoc" title="javadoc:java/rmi/RemoteException"><span class="type">RemoteException</span></a>, <span class="type">NegativeAmountException</span> {
    checkForNegativeAmount(amount);
    <span class="reference">_balance</span>.add(amount);
    <span class="keyword">return</span>;
  }

  <span class="jde-java-font-lock-modifier">public</span> <span class="jde-java-font-lock-modifier">synchronized</span> <span class="type">void</span> <span class="function-name">makeWithdrawal</span>(<span class="type">Money</span> <span class="variable-name">amount</span>)
    <span class="keyword">throws</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/rmi/RemoteException.html" class="javadoc" title="javadoc:java/rmi/RemoteException"><span class="type">RemoteException</span></a>, <span class="type">OverdraftException</span>, <span class="type">NegativeAmountException</span> {
    checkForNegativeAmount(amount);
    checkForOverdraft(amount);
    <span class="reference">_balance</span>.subtract(amount);
    <span class="keyword">return</span>;
  }
}

</pre>

    <ul>
      <li>It is possible to check balance then fail to withdraw that
      because someone else withdrew the money just after.</li>

      <li>Client should maintain lock.</li>
    </ul>
  </div><h3 id="clientlock">12.2 Client Maintains Lock</h3><div class="slidebody">
      <pre>
<span class="keyword">import</span> <span class="jde-java-font-lock-package">java</span>.<span class="jde-java-font-lock-package">rmi</span>.<span class="jde-java-font-lock-number">*</span>;
<span class="keyword">import</span> <span class="jde-java-font-lock-package">java</span>.<span class="jde-java-font-lock-package">rmi</span>.<span class="jde-java-font-lock-package">server</span>.<span class="jde-java-font-lock-number">*</span>;

<span class="jde-java-font-lock-modifier">public</span> <span class="keyword">class</span> <span class="type">Account2_Impl</span> <span class="keyword">extends</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/rmi/server/UnicastRemoteObject.html" class="javadoc" title="javadoc:java/rmi/server/UnicastRemoteObject"><span class="type">UnicastRemoteObject</span></a>
  <span class="keyword">implements</span> <span class="type">Account2</span> {
  <span class="jde-java-font-lock-modifier">private</span> <span class="type">Money</span> <span class="variable-name">_balance</span>;
  <span class="jde-java-font-lock-modifier">private</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html" class="javadoc" title="javadoc:java/lang/String"><span class="type">String</span></a> <span class="variable-name">_currentClient</span>;

  <span class="jde-java-font-lock-modifier">public</span> <span class="type">Account2_Impl</span>(<span class="type">Money</span> <span class="variable-name">startingBalance</span>)
    <span class="keyword">throws</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/rmi/RemoteException.html" class="javadoc" title="javadoc:java/rmi/RemoteException"><span class="type">RemoteException</span></a> {
    _balance = startingBalance;
  }

  <span class="comment">/** The client can use this to get a lock on the account */</span>
  <span class="jde-java-font-lock-modifier">public</span> <span class="jde-java-font-lock-modifier">synchronized</span> <span class="type">void</span> <span class="function-name">getLock</span>()
    <span class="keyword">throws</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/rmi/RemoteException.html" class="javadoc" title="javadoc:java/rmi/RemoteException"><span class="type">RemoteException</span></a>, <span class="type">LockedAccountException</span> {
    <span class="keyword">if</span> (<span class="jde-java-font-lock-constant">false</span> == becomeOwner()) {
      <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">LockedAccountException</span>();
    }
    <span class="keyword">return</span>;
  }

  <span class="comment">/** The client can use this to release a lock on the account */</span>
  <span class="jde-java-font-lock-modifier">public</span> <span class="jde-java-font-lock-modifier">synchronized</span> <span class="type">void</span> <span class="function-name">releaseLock</span>() <span class="keyword">throws</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/rmi/RemoteException.html" class="javadoc" title="javadoc:java/rmi/RemoteException"><span class="type">RemoteException</span></a> {
    <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html" class="javadoc" title="javadoc:java/lang/String"><span class="type">String</span></a> <span class="variable-name">clientHost</span> = wrapperAroundGetClientHost();

    <span class="keyword">if</span> ((<span class="jde-java-font-lock-constant">null</span> != _currentClient) &amp;&amp; (<span class="reference">_currentClient</span>.equals(clientHost))) {
      _currentClient = <span class="jde-java-font-lock-constant">null</span>;
    }
  }

  <span class="jde-java-font-lock-modifier">private</span> <span class="type">boolean</span> <span class="function-name">becomeOwner</span>() {
    <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html" class="javadoc" title="javadoc:java/lang/String"><span class="type">String</span></a> <span class="variable-name">clientHost</span> = wrapperAroundGetClientHost();

    <span class="keyword">if</span> (<span class="jde-java-font-lock-constant">null</span> != _currentClient) {
      <span class="keyword">if</span> (<span class="reference">_currentClient</span>.equals(clientHost)) {
        <span class="keyword">return</span> <span class="jde-java-font-lock-constant">true</span>;
      }
    } <span class="keyword">else</span> {
      _currentClient = clientHost;
      <span class="keyword">return</span> <span class="jde-java-font-lock-constant">true</span>;
    }
    <span class="keyword">return</span> <span class="jde-java-font-lock-constant">false</span>;
  }

  <span class="jde-java-font-lock-modifier">private</span> <span class="type">void</span> <span class="function-name">checkAccess</span>() <span class="keyword">throws</span> <span class="type">LockedAccountException</span> {
    <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html" class="javadoc" title="javadoc:java/lang/String"><span class="type">String</span></a> <span class="variable-name">clientHost</span> = wrapperAroundGetClientHost();

    <span class="keyword">if</span> ((<span class="jde-java-font-lock-constant">null</span> != _currentClient) &amp;&amp; (<span class="reference">_currentClient</span>.equals(clientHost))) {
      <span class="keyword">return</span>;
    }
    <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">LockedAccountException</span>();
  }

  <span class="jde-java-font-lock-modifier">private</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html" class="javadoc" title="javadoc:java/lang/String"><span class="type">String</span></a> <span class="function-name">wrapperAroundGetClientHost</span>() {
    <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html" class="javadoc" title="javadoc:java/lang/String"><span class="type">String</span></a> <span class="variable-name">clientHost</span> = <span class="jde-java-font-lock-constant">null</span>;

    <span class="keyword">try</span> {
      clientHost = getClientHost();
    } <span class="keyword">catch</span> (<a href="http://java.sun.com/j2se/1.4.2/docs/api/java/rmi/server/ServerNotActiveException.html" class="javadoc" title="javadoc:java/rmi/server/ServerNotActiveException"><span class="type">ServerNotActiveException</span></a> <span class="variable-name">ignored</span>) {
    }
    <span class="keyword">return</span> clientHost;
  }

  <span class="jde-java-font-lock-modifier">public</span> <span class="jde-java-font-lock-modifier">synchronized</span> <span class="type">Money</span> <span class="function-name">getBalance</span>()
    <span class="keyword">throws</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/rmi/RemoteException.html" class="javadoc" title="javadoc:java/rmi/RemoteException"><span class="type">RemoteException</span></a>, <span class="type">LockedAccountException</span> {
    checkAccess();
    <span class="keyword">return</span> _balance;
  }

  <span class="jde-java-font-lock-modifier">public</span> <span class="jde-java-font-lock-modifier">synchronized</span> <span class="type">void</span> <span class="function-name">makeDeposit</span>(<span class="type">Money</span> <span class="variable-name">amount</span>)
    <span class="keyword">throws</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/rmi/RemoteException.html" class="javadoc" title="javadoc:java/rmi/RemoteException"><span class="type">RemoteException</span></a>, <span class="type">LockedAccountException</span>, <span class="type">NegativeAmountException</span> {
    checkAccess();
    checkForNegativeAmount(amount);
    <span class="reference">_balance</span>.add(amount);
    <span class="keyword">return</span>;
  }

  <span class="jde-java-font-lock-modifier">public</span> <span class="jde-java-font-lock-modifier">synchronized</span> <span class="type">void</span> <span class="function-name">makeWithdrawal</span>(<span class="type">Money</span> <span class="variable-name">amount</span>)
    <span class="keyword">throws</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/rmi/RemoteException.html" class="javadoc" title="javadoc:java/rmi/RemoteException"><span class="type">RemoteException</span></a>, <span class="type">OverdraftException</span>, <span class="type">LockedAccountException</span>, <span class="type">NegativeAmountException</span> {
    checkAccess();
    checkForNegativeAmount(amount);
    checkForOverdraft(amount);
    <span class="reference">_balance</span>.subtract(amount);
    <span class="keyword">return</span>;
  }

  <span class="jde-java-font-lock-modifier">private</span> <span class="type">void</span> <span class="function-name">checkForNegativeAmount</span>(<span class="type">Money</span> <span class="variable-name">amount</span>)
    <span class="keyword">throws</span> <span class="type">NegativeAmountException</span> {
    <span class="type">int</span> <span class="variable-name">cents</span> = <span class="reference">amount</span>.getCents();

    <span class="keyword">if</span> (<span class="jde-java-font-lock-number">0</span> &gt; cents) {
      <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">NegativeAmountException</span>();
    }
  }

  <span class="jde-java-font-lock-modifier">private</span> <span class="type">void</span> <span class="function-name">checkForOverdraft</span>(<span class="type">Money</span> <span class="variable-name">amount</span>)
    <span class="keyword">throws</span> <span class="type">OverdraftException</span> {
    <span class="keyword">if</span> (<span class="reference">amount</span>.greaterThan(_balance)) {
      <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">OverdraftException</span>(<span class="jde-java-font-lock-constant">false</span>);
    }
    <span class="keyword">return</span>;
  }
} 

</pre>
    <ul>
      
      <li>This increases the number of method calls the client must
      make.</li>

      <li>Its vulnerable to partial failure. What if the client that
      has the lock dies?</li>

    </ul>
  </div><h3 id="expirythread">12.3 Using a Lock Expiry Thread</h3><div class="slidebody">
      <pre>
<span class="keyword">import</span> <span class="jde-java-font-lock-package">java</span>.<span class="jde-java-font-lock-package">rmi</span>.<span class="jde-java-font-lock-number">*</span>;
<span class="keyword">import</span> <span class="jde-java-font-lock-package">java</span>.<span class="jde-java-font-lock-package">rmi</span>.<span class="jde-java-font-lock-package">server</span>.<span class="jde-java-font-lock-number">*</span>;
<span class="comment">/*
 Has timer-based lock management on server-side
 */</span>

<span class="jde-java-font-lock-modifier">public</span> <span class="keyword">class</span> <span class="type">Account3_Impl</span> <span class="keyword">extends</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/rmi/server/UnicastRemoteObject.html" class="javadoc" title="javadoc:java/rmi/server/UnicastRemoteObject"><span class="type">UnicastRemoteObject</span></a> <span class="keyword">implements</span> <span class="type">Account3</span> {
  <span class="jde-java-font-lock-modifier">private</span> <span class="jde-java-font-lock-modifier">static</span> <span class="jde-java-font-lock-modifier">final</span> <span class="type">int</span> <span class="variable-name">TIMER_DURATION</span> = <span class="jde-java-font-lock-number">120000</span>; <span class="comment">// Two minutes
</span>  <span class="jde-java-font-lock-modifier">private</span> <span class="jde-java-font-lock-modifier">static</span> <span class="jde-java-font-lock-modifier">final</span> <span class="type">int</span> <span class="variable-name">THREAD_SLEEP_TIME</span> = <span class="jde-java-font-lock-number">10000</span>; <span class="comment">// 10 seconds
</span>
  <span class="jde-java-font-lock-modifier">private</span> <span class="type">Money</span> <span class="variable-name">_balance</span>;
  <span class="jde-java-font-lock-modifier">private</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html" class="javadoc" title="javadoc:java/lang/String"><span class="type">String</span></a> <span class="variable-name">_currentClient</span>;
  <span class="jde-java-font-lock-modifier">private</span> <span class="type">int</span> <span class="variable-name">_timeLeftUntilLockIsReleased</span>;

  <span class="jde-java-font-lock-modifier">public</span> <span class="type">Account3_Impl</span>(<span class="type">Money</span> <span class="variable-name">startingBalance</span>)
    <span class="keyword">throws</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/rmi/RemoteException.html" class="javadoc" title="javadoc:java/rmi/RemoteException"><span class="type">RemoteException</span></a> {
    _balance = startingBalance;
    _timeLeftUntilLockIsReleased = <span class="jde-java-font-lock-number">0</span>;
    <span class="keyword">new</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Thread.html" class="javadoc" title="javadoc:java/lang/Thread"><span class="type">Thread</span></a>(<span class="keyword">new</span> <span class="type">CountDownTimer</span>()).start();
  }

  <span class="jde-java-font-lock-modifier">public</span> <span class="jde-java-font-lock-modifier">synchronized</span> <span class="type">Money</span> <span class="function-name">getBalance</span>()
    <span class="keyword">throws</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/rmi/RemoteException.html" class="javadoc" title="javadoc:java/rmi/RemoteException"><span class="type">RemoteException</span></a>, <span class="type">LockedAccountException</span> {
    checkAccess();
    <span class="keyword">return</span> _balance;
  }

  <span class="jde-java-font-lock-modifier">public</span> <span class="jde-java-font-lock-modifier">synchronized</span> <span class="type">void</span> <span class="function-name">makeDeposit</span>(<span class="type">Money</span> <span class="variable-name">amount</span>)
    <span class="keyword">throws</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/rmi/RemoteException.html" class="javadoc" title="javadoc:java/rmi/RemoteException"><span class="type">RemoteException</span></a>, <span class="type">LockedAccountException</span>, <span class="type">NegativeAmountException</span> {
    checkAccess();
    checkForNegativeAmount(amount);
    <span class="reference">_balance</span>.add(amount);
    <span class="keyword">return</span>;
  }

  <span class="jde-java-font-lock-modifier">public</span> <span class="jde-java-font-lock-modifier">synchronized</span> <span class="type">void</span> <span class="function-name">makeWithdrawal</span>(<span class="type">Money</span> <span class="variable-name">amount</span>)
    <span class="keyword">throws</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/rmi/RemoteException.html" class="javadoc" title="javadoc:java/rmi/RemoteException"><span class="type">RemoteException</span></a>, <span class="type">OverdraftException</span>, <span class="type">LockedAccountException</span>, <span class="type">NegativeAmountException</span> {
    checkAccess();
    checkForNegativeAmount(amount);
    checkForOverdraft(amount);
    <span class="reference">_balance</span>.subtract(amount);
    <span class="keyword">return</span>;
  }

  <span class="jde-java-font-lock-modifier">private</span> <span class="type">void</span> <span class="function-name">checkAccess</span>() <span class="keyword">throws</span> <span class="type">LockedAccountException</span> {
    <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html" class="javadoc" title="javadoc:java/lang/String"><span class="type">String</span></a> <span class="variable-name">clientHost</span> = wrapperAroundGetClientHost();

    <span class="keyword">if</span> (<span class="jde-java-font-lock-constant">null</span> == _currentClient) {
      _currentClient = clientHost;
    } <span class="keyword">else</span> {
      <span class="keyword">if</span> (!<span class="reference">_currentClient</span>.equals(clientHost)) {
        <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">LockedAccountException</span>();
      }
    }
    resetCounter();
    <span class="keyword">return</span>;
  }

  <span class="jde-java-font-lock-modifier">private</span> <span class="type">void</span> <span class="function-name">resetCounter</span>() {
    _timeLeftUntilLockIsReleased = <span class="jde-java-font-lock-constant">TIMER_DURATION</span>;
  }

  <span class="jde-java-font-lock-modifier">private</span> <span class="type">void</span> <span class="function-name">releaseLock</span>() {
    <span class="keyword">if</span> (<span class="jde-java-font-lock-constant">null</span> != _currentClient) {
      _currentClient = <span class="jde-java-font-lock-constant">null</span>;
    }
  }

  <span class="jde-java-font-lock-modifier">private</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html" class="javadoc" title="javadoc:java/lang/String"><span class="type">String</span></a> <span class="function-name">wrapperAroundGetClientHost</span>() {
    <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html" class="javadoc" title="javadoc:java/lang/String"><span class="type">String</span></a> <span class="variable-name">clientHost</span> = <span class="jde-java-font-lock-constant">null</span>;

    <span class="keyword">try</span> {
      clientHost = getClientHost();
    } <span class="keyword">catch</span> (<a href="http://java.sun.com/j2se/1.4.2/docs/api/java/rmi/server/ServerNotActiveException.html" class="javadoc" title="javadoc:java/rmi/server/ServerNotActiveException"><span class="type">ServerNotActiveException</span></a> <span class="variable-name">ignored</span>) {
    }
    <span class="keyword">return</span> clientHost;
  }

  <span class="jde-java-font-lock-modifier">private</span> <span class="type">void</span> <span class="function-name">checkForNegativeAmount</span>(<span class="type">Money</span> <span class="variable-name">amount</span>)
    <span class="keyword">throws</span> <span class="type">NegativeAmountException</span> {
    <span class="type">int</span> <span class="variable-name">cents</span> = <span class="reference">amount</span>.getCents();

    <span class="keyword">if</span> (<span class="jde-java-font-lock-number">0</span> &gt; cents) {
      <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">NegativeAmountException</span>();
    }
  }

  <span class="jde-java-font-lock-modifier">private</span> <span class="type">void</span> <span class="function-name">checkForOverdraft</span>(<span class="type">Money</span> <span class="variable-name">amount</span>)
    <span class="keyword">throws</span> <span class="type">OverdraftException</span> {
    <span class="keyword">if</span> (<span class="reference">amount</span>.greaterThan(_balance)) {
      <span class="keyword">throw</span> <span class="keyword">new</span> <span class="type">OverdraftException</span>(<span class="jde-java-font-lock-constant">false</span>);
    }
    <span class="keyword">return</span>;
  }

  <span class="comment">/** The expire thread */</span>
  <span class="jde-java-font-lock-modifier">private</span> <span class="keyword">class</span> <span class="type">CountDownTimer</span> <span class="keyword">implements</span> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Runnable.html" class="javadoc" title="javadoc:java/lang/Runnable"><span class="type">Runnable</span></a> {
    <span class="jde-java-font-lock-modifier">public</span> <span class="type">void</span> <span class="function-name">run</span>() {
      <span class="keyword">while</span> (<span class="jde-java-font-lock-constant">true</span>) {
        <span class="keyword">try</span> {
          <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Thread.html" class="javadoc" title="javadoc:java/lang/Thread"><span class="type">Thread</span></a>.sleep(<span class="jde-java-font-lock-constant">THREAD_SLEEP_TIME</span>);
        } <span class="keyword">catch</span> (<a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Exception.html" class="javadoc" title="javadoc:java/lang/Exception"><span class="type">Exception</span></a> <span class="variable-name">ignored</span>) {
        }
        <span class="jde-java-font-lock-modifier">synchronized</span> (<span class="type">Account3_Impl</span>.<span class="keyword">this</span>) {
          <span class="keyword">if</span> (_timeLeftUntilLockIsReleased &gt; <span class="jde-java-font-lock-number">0</span>) {
            _timeLeftUntilLockIsReleased -= <span class="jde-java-font-lock-constant">THREAD_SLEEP_TIME</span>;
          } <span class="keyword">else</span> {
            releaseLock();
          }
        }
      }
    }
  }
} 

</pre>
    <ul>
      
      <li>Lock remains as long as client executes an operation every
      two minutes or more.</li>

      <li>This code is more complicated.</li>

      <li>The threads are expensive. There is one per account. We
      could have one thread check all instances (see book).</li>

    </ul>
  </div><h3 id="mintime">12.4 Minimize Time in Synchronized Blocks.</h3><div class="slidebody">
    <ul>
      
      <li>Synchronize around the smallest possible block of code.</li>

      <li>Don't synchronize across device accesses. If many clients
      use this method, they will all stop when the device slows
      down. This also creates a queue.
	<ul>
	  <li>One solution is to use a background thread which does a
	    "pull" of the information, instead of the "push".</li>
	</ul>
      </li>
    </ul>
  </div><h3 id="container">12.5 Be Careful When Using Container Classes.</h3><div class="slidebody">
    <ul>
      
	<li><a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/Vector.html" class="javadoc" title="javadoc:java/util/Vector"><code>Vector</code></a>
	  and <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/HashTable.html" class="javadoc" title="javadoc:java/util/HashTable"><code>Hashtable</code></a>
	  claim to be threadsafe because they synchronize every
	  method.</li>
	
	<li>But, this does not mean that they are really safe.</li>
	
	<li>Is the following thread safe?</li>
    </ul>

	<pre>
<span class="keyword">import</span> <span class="jde-java-font-lock-package">java</span>.<span class="jde-java-font-lock-package">util</span>.<span class="jde-java-font-lock-number">*</span>;
<span class="jde-java-font-lock-modifier">public</span> <span class="jde-java-font-lock-modifier">synchronized</span> <span class="type">void</span> <span class="function-name">insertIfAbsent</span>(<a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/Vector.html" class="javadoc" title="javadoc:java/util/Vector"><span class="type">Vector</span></a> <span class="variable-name">vector</span>, <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html" class="javadoc" title="javadoc:java/lang/Object"><span class="type">Object</span></a> <span class="variable-name">object</span>){
  <span class="keyword">if</span> (<span class="reference">vector</span>.contains(object)) {
    <span class="keyword">return</span>;
  } 
  <span class="reference">vector</span>.add(object);
}
</pre>
	
	<ul>
	  <li>No. It assumes there is only one instance of the class.</li>
	  
	  <li>The right way is to do:</li>
	  
	  <pre>
<span class="keyword">import</span> <span class="jde-java-font-lock-package">java</span>.<span class="jde-java-font-lock-package">util</span>.<span class="jde-java-font-lock-number">*</span>;

<span class="jde-java-font-lock-modifier">public</span> <span class="type">void</span> <span class="function-name">insertIfAbsent</span>(<a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/Vector.html" class="javadoc" title="javadoc:java/util/Vector"><span class="type">Vector</span></a> <span class="variable-name">vector</span>, <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html" class="javadoc" title="javadoc:java/lang/Object"><span class="type">Object</span></a> <span class="variable-name">object</span>){
  <span class="jde-java-font-lock-modifier">synchronized</span> (vector){
    <span class="keyword">if</span> (<span class="reference">vector</span>.contains(object)) {
      <span class="keyword">return</span>;
    } 
    <span class="reference">vector</span>.add(object);
  }
}
</pre>
	</ul>
      
    </div><h3 id="usecontainer">12.6 Use Containers To Mediate Inter-thread Communication.</h3><div class="slidebody">
    <ul>
      
      <li>If one thread needs to feed data to another thread it is
      often useful to use a queue.</li>

      <li>The publishing thread can always add to the end of the
      queue. The consumer thread takes from the head of the
      queue.</li>

      <li>We replace a synchronous call with asynchronous calls.</li>

      <li>Return values are no longer meaningful. We might need a
      callback mechanism (e.g., out-of-paper).</li>

    </ul>
  </div><h2 id="testing">13 Testing</h2><div class="slidebody">
      <ul>
	<li>Correctness:
	  <ul>
	    <li>Can client connect to server?</li>

	    <li>Can client perform remote calls? </li>

	    <li>Does server do the right thing? </li>
	  </ul>
	</li>

	<li>Scalability
	  <ul>
	    <li>Does it work with more than one client?</li>

	    <li>Is performance acceptable under normal load? </li>

	    <li>Can it handle peak loads? </li>

	    <li>How does it degrade with increased load? </li>

	    <li>How does it behavior over long-term? leaks? </li>
	  </ul>
	</li>
      </ul>
    </div><h3 id="teststrategy">13.1 Test Strategy</h3><div class="slidebody">
      <ol>
	<li>Build tests objects that test unit functionality, e.g.,
	one function. </li>

	<li>Build aggregate tests for entire use case. </li>

	<li>Build threaded <em>tester</em> that does many of these, in
	sequence. </li>

	<li>Build a container that launches many testers. Simulate
	users. </li>

	<li>Build a reporting mechanism. </li>

	<li>Run many tests. </li>

	<li>Profile performance using tester containers. </li>
      </ol>
    </div><b>Note:</b><div class="note">
      <p>
	I realize that these instructions are overkill for your
	typical problem set project. However, any real-world project
	will likely be ten times larger and involve five times as many
	developers. Unit testing and automated testing are
	<b>indispensable</b> for any real project. Frequent automated
	testing forms the basis of all major software development
	companies' culture. In fact, many of them have nightly
	builds/tests. If any bugs are found then fixing it becomes the
	developer's first priority.
      </p>
    </div><h2 id="namingservices">14 Naming Services</h2><div class="slidebody">
      <div class="floatright" style="width:468px">
	<img class="float" src="naming.png" alt="Naming"/>
      </div>

      <ul>
	<li>The rmiregistry is limited to one flat search space of
	services on one machine!</li>

	<li>Scalable systems can extend the <a href="../internet/allslides.xml#dns">DNS</a> idea by adding
	attributes. </li>

	<li>Most popular example is <span><a class="remote" href="http://www.wikipedia.org/wiki/LDAP" title="wikipedia:LDAP">LDAP</a> [4]</span>. </li>

	<li>It defines nested <dfn>contexts</dfn>. Elements can be
	added to any context and have attributes and values. </li>

	<li>Search proceeds bottom-up. Assumes most searches answered
	locally. </li>
      </ul>
    </div><b>Note:</b><div class="note">
      <p>
	LDAP provides an excellent example of the kind of
	sophisticated naming service that will likely be needed to
	replace the rmiregistry's limited search ability. If we
	envision a world of different remote objects offered by
	different companies then the need for this type of service is
	obvious. Web services have been trying to provide a solution
	to this same problem via the use of UDDI and WSDL (later in
	class). 
      </p>
    </div><h2 id="rmigarbagecollection">15 RMI Garbage Collection</h2><div class="slidebody">
      <ul>
	<li>The JVM uses reference counting for local garbage
	collection. When number of references is zero then it can be
	collected.  </li>

	<li>No time guarantee. </li>

	<li>RMI keeps track of number of active clients. </li>

	<li>Clients <em>lease</em> objects for fixed periods (10
	minutes, <code>java.rmi.dgc.leasevalue</code>) </li>

	<li>Clients must renew or lease expires and object gets
	collected. </li>
      </ul>
    </div><h2 id="rmilogging">16 RMI Logging</h2><div class="slidebody">
      <ul>
	<li>The <em>standard log</em> is turned on with <pre>
java -Djava.rmi.server.logCalls=true ...</pre> or with
<pre>
<span class="reference">System</span>.getProperties().put(&quot;<span class="string">java.rmi.server.logCalls</span>&quot;,&quot;<span class="string">true</span>&quot;);</pre> and you must set the destination with 

<pre>
<span class="type">FileOutputStream</span> <span class="variable-name">logFile</span> = <span class="keyword">new</span> <span class="type">FileOutputStream</span>(&quot;<span class="string">/tmp/file</span>&quot;);
<span class="reference">RemoteServer</span>.setLog(logFile);</pre>

Log is very verbose.</li>

      </ul>
    </div><h3 id="specializedlogs">16.1 Specialized Logs</h3><div class="slidebody">
      <ul>
	<li>They are: transport, proxy, tcp, dgc, and loader. </li>

	<li>Set them with

<pre>
<span class="type">FileOutputStream</span> <span class="variable-name">transportLogFile</span> = <span class="keyword">new</span> <span class="type">FileOutputStream</span>(&quot;<span class="string">/tmp/tlog</span>&quot;);
<span class="reference">LogStream</span>.log(&quot;<span class="string">transport</span>&quot;).setOutputStream(transportLogFile);</pre>

and similarly for the other types.  </li>

	<li>You can then determine how much information goes into them
	by setting these six properties to either: silent, brief, or verbose.
	  <ol>
	    <li>sum.rmi.server.dgcLevel</li>

	    <li>sun.rmi.server.logLevel </li>

	    <li>sun.rmi.loader.logLevel </li>

	    <li>sun.rmi.transport.logLevel </li>

	    <li>sun.rmi.transport.tcp.logLevel </li>

	    <li>sun.rmi.transport.proxy.logLevel </li>
	  </ol>
	</li>
      </ul>
    </div><h2 id="securitypolicy">17 Security Policy</h2><div class="slidebody">
      <blockquote>
	"Making a distributed system secure is a mindnumbingly
	difficult task."&mdash;William Grosso
      </blockquote>
      <ul>
	<li>Keep API as simple as possible. </li>

	<li>Grant your code (downloaded code) the minimal permissions
	needed. </li>

	<li>The <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/SecurityManager.html" class="javadoc" title="javadoc:java/lang/SecurityManager"><code>SecurityManager</code></a>
	tells JVM what the code can't do. </li>
      </ul>
    </div><h3 id="securitymanagerpermissions">17.1 Security Manager Permissions</h3><div class="slidebody">
      <ul>
	<li><em>AWT permissions</em>: accesClipboard,
	accessEventQueue, listenToAllAwtEvents, readDisplayPixels,
	showWindowWithoutWarningBanner, and createRobot (pretends to
	be user). <pre>
grant{
   permission java.awt.AWTPermission "showWindowWithoutWarningBanner";};</pre>
 </li>

	<li><em>File permissions</em> can be: read, write, execute,
	and delete. <pre>
grant {
   permissions java.io.FilePermission "/tmp/-", "read, write, delete";};</pre>
	- is a recursive wildcard, * is local wildcard.</li>

	<li><em>Socket permissions</em> cover resolve, connect,
	listen, and accept. <pre>
grant {
   permission java.net.SocketPermission "*.sc.edu:1024-", "accept,
   connect";};</pre> </li>

	<li><em>Property permissions</em> allow read, write to system
	properties ("-Dsun.com.property=false")<pre>
grant {
   permission java.util.PropertyPermission "java.version", "read";}</pre> </li>
      </ul>
    </div><h3 id="thesecuritymanager">17.2 The Security Manager</h3><div class="slidebody">
      <ul>
	<li><em>If there is none, then there is no security
	checks!</em> </li>

	<li>You can install one with <pre>
java -Djava.security.manager application</pre> or in the code with
<pre>
<span class="reference">System</span>.setSecurityManager(<span class="keyword">new</span> <span class="type">RMISecurityManager</span>());</pre>
this last is a much better idea for your RMI code.

	</li>

	<li>In Java there are three policy files that are used.
	  <ol>
	    <li>Global policy file. (<code>...jre/lib/security/java.policy</code>)</li>

	    <li>User-specific policy file
	    (<code>HOME/.java.policy</code>) </li>

	    <li>Application-specific set with<pre>
java -Djava.security.policy="java.policy"</pre> </li>
	  </ol>
	</li>

	<li>The general format is<pre>grant [signedBy Name] [codebase URL] {...};</pre> where Name and URL
can be anything. </li>

	<li>The program <code>policytool</code> provides a gui for editing this file. </li>
      </ul>
    </div><h2 id="httptunneling">18 HTTP Tunneling</h2><div class="slidebody">

      <div class="floatright" style="width:418px">
	<img class="float" src="tunnel.png" alt="Tunnel"/>
      </div>
      <ul>
	<li>When an RMI client (stub, even registry stub) tries to
	contact a server, it will try:</li>
      </ul>
      <ol>
	<li>Contact directly using JRMP.</li>

	<li>Make direct HTTP connection to server, encapsulate method
	call in HTTP request. </li>

	<li>Assume firewall is proxy server, ask it to forward the
	request to appropriate port on server. Firewall forwards
	request as HTTP request.</li>

	<li>Connect to port 80 on server machine and send request to
	URL beginning with <code>/cgi-bin/java-rmi.cgi</code>. Hope
	request gets forwarded to proper port on server machine.</li>

	<li>Connect to port 80 of firewall machine and send request to
	URL beginning with <code>/cgi-bin/java-rmi.cgi</code>. Hope
	request gets forwarded to server. </li>
      </ol>
    </div><h2>URLs</h2><ol><li>Java
      RMI, <a href="http://www.amazon.com/exec/obidos/ASIN/1565924525/multiagentcom/">http://www.amazon.com/exec/obidos/ASIN/1565924525/multiagentcom/</a></li><li>O'Reilly, <a href="http://www.oreilly.com/catalog/javarmi/">http://www.oreilly.com/catalog/javarmi/</a></li><li>wikipedia:Adapter_pattern, <a href="http://www.wikipedia.org/wiki/Adapter_pattern">http://www.wikipedia.org/wiki/Adapter_pattern</a></li><li>wikipedia:LDAP, <a href="http://www.wikipedia.org/wiki/LDAP">http://www.wikipedia.org/wiki/LDAP</a></li></ol><hr class="bottom"/>
<p class="author">This talk available at <a href="http://jmvidal.cse.sc.edu/talks/rmidesign">http://jmvidal.cse.sc.edu/talks/rmidesign/</a><br />
Copyright &copy; 2004 <a href="../../index.html">Jos&eacute; M. Vidal</a>
<a href=" http://validator.w3.org/check?uri=http://jmvidal.cse.sc.edu/talks/rmidesign/allslides.xml">.</a>
 All rights reserved.</p>
<p class="pagenumber">17 March 2004, 09:42AM</p>
</body>
</html>