Implement the client-side interface
21.2.2.5 Implement the client-side interface
We will implement the first version of CallbackClient , the one without documentKey . We need to do two things: actually implement CallbackClient and then adapt our outside frame to use it correctly. Heres an implementation of CallbackClient . As in our previous examples, all it does is display a dialog box with the outcome of the print request: public class CallbackClient_DialogImpl extends UnicastRemoteObject implements CallbackClient { private static final String SUCCESS_WINDOW_TITLE = Success; private static final String FAILURE_WINDOW_TITLE = Failure; private String _documentName; public CallbackClient_DialogImplString documentName throws RemoteException { _documentName = documentName; } public void documentIsDone throws RemoteException { reportResultOfPrintRequestSUCCESS_WINDOW_TITLE, _documentName + is done printing.; ceaseBeingAServer ; } public void documentFailedToPrintString reason throws RemoteException { reportResultOfPrintRequestFAILURE_WINDOW_TITLE, _documentName + failed to print because + reason; } private void reportResultOfPrintRequestString windowTitle, String message { SwingUtilities.invokeLaternew SendMessageToUserwindowTitle, message; } private void ceaseBeingAServer { try { unexportObjectthis, true; } catch NoSuchObjectException e { Not much to do. The RMI runtime thinks were not a server. } } private class SendMessageToUser implements Runnable { private String _windowTitle; private String _message; public SendMessageToUserString windowTitle, String message { _windowTitle = windowTitle; _message = message; } public void run { JOptionPane.showMessageDialognull, _windowTitle, _message, JOptionPane.INFORMATION_MESSAGE; } } } As you can see, this is a one-shot RMI server. CallbackClient_DialogImpl extends UnicastRemoteObject and, therefore, instances of CallbackClient_DialogImpl can receive remote method invocations. However, they never get registered in any naming service, and once an instance of CallbackClient_DialogImpl receives a remote method invocation, it immediately unexports itself. There are three convenient aspects to this. First, the client application doesnt need to create any thread objects; the RMI runtime handles thread management issues for it. Second, most of the reported back code is encapsulated in a single class. We can easily change the method of reporting by simply using a different implementation of CallbackClient . Third, the rest of the client application doesnt need to keep a reference to instances of CallbackClient_DialogImpl at all. That is, an instance of CallbackClient_DialogImpl has the following lifecycle: 1. It is created. 2. It waits for a message. While it is waiting, it is exported, and the server has a reference to it. Therefore, the instance will not be garbage collected. 3. It receives a message. At this point, it unexports itself and is no longer a server. The RMI runtime no longer has any references to the instance of CallbackClient_DialogImpl . This means that, as long as we dont keep any references to the instance of CallbackClient_DialogImpl within the rest of the client application, it will automatically become eligible for garbage collection as soon as it receives a message from the server. With that in mind, heres the new implementation of the Print File buttons action listener: private class PrintFile implements ActionListener { private CallbackPrinter _printer; public void actionPerformedActionEvent event { try { File fileToPrint = _fileChooser.getSelectedFile ; FileInputStream documentStream = new FileInputStreamfileToPrint; DocumentDescription documentDescription = new DocumentDescriptiondocumentStream; _printer = CallbackPrinter Naming.lookupDEFAULT_PRINTER_NAME; CallbackClient callbackClient = new CallbackClient_DialogImplfileToPrint.getName ; _printer.printDocumentcallbackClient, documentDescription; } catch Exception exception { SwingUtilities.invokeLaternew ExceptionMessageexception; return; } } } private class ExceptionMessage implements Runnable { private Exception _exception; public ExceptionMessageException exception { _exception = exception; } public void run { JOptionPane.showMessageDialogCallbackClientFrame.this , Print failed , Error in printing , JOptionPane.INFORMATION_ MESSAGE; _messageBox.setTextException attempting to print + _fileChooser.getSelectedFile.getAbsolutePath + \n\t Error was: + _exception.toString ; _exception.printStackTrace ; } }21.3 Handling Report-Type Methods
Parts
» OReilly.Java.Rmi. 2313KB Mar 29 2010 05:03:49 AM
» Writing data Resource management
» Some Useful Intermediate Streams
» Revisiting the ViewFile Application
» Protocols Metadata Protocols and Metadata
» The accept method A Simple Web Server
» Customizing Socket Behavior Sockets
» Direct Stream Manipulation Subclassing Socket Is a Better Solution
» A Special-Purpose Socket Special-Purpose Sockets
» Factories Socket Factories Special-Purpose Sockets
» Registering providers Using SSL with JSSE
» Configuring SSLServerSocket Using SSL with JSSE
» A Network-Based Printer A Socket-Based Printer Server
» The Basic Objects A Socket-Based Printer Server
» DocumentDescription Encapsulation and Sending Objects
» ClientNetworkWrapper Network-Aware Wrapper Objects
» ServerNetworkWrapper Network-Aware Wrapper Objects
» Passing by Value Versus Passing by Reference
» The Architecture Diagram Revisited
» The Printer Interface Implementing the Basic Objects
» Examining the skeleton Implementing a Printer
» DocumentDescription The Data Objects
» The Client Application Summary
» The Bank Example Introducing the Bank Example
» Security Scalability Design Postponements
» The Basic Use Case A Distributed Architecturefor the Bank Example
» Partial Failures Problems That Arise in Distributed Applications
» Network Latency Problems That Arise in Distributed Applications
» Memory, in general, is not an issue here Sockets in RMI arent a limitation either
» Applying this to Bank versus Accounts
» Should We Implement Bank or Account?
» Iterators, again Applying this to the Account interface
» Applying this to the Account interface
» Data Objects Dont Usually Have Functional Methods Interfaces Give You the Data Objects
» Accounting for Partial Failure
» A Server That Extends UnicastRemoteObject A Server That Does Not Extend UnicastRemoteObject
» The benefits of UnicastRemoteObject
» The costs of UnicastRemoteObject
» Getting Rid of the Skeletons
» Build Test Applications The Rest of the Application
» Dont Hold Connections to a Server Youre Not Using
» Validate Arguments on the Client Side Whenever Reasonable
» The Actual Client Application
» Deploying the Application The Rest of the Application
» Drilling Down on Object Creation
» The write methods ObjectOutputStream
» The stream manipulation methods Methods that customize the serialization mechanism
» The read methods ObjectInputStream
» Declaring transient fields Implementing writeObject and readObject
» Implement the Serializable Interface Make Sure That Superclass State Is Handled Correctly
» The Data Format The Serialization Algorithm
» Writing A Simplified Version of the Serialization Algorithm
» annotateClass replaceObject RMI Customizes the Serialization Algorithm
» Maintaining Direct Connections The Serialization Algorithm
» The Two Types of Versioning Problems
» How Serialization Detects When a Class Has Changed Implementing Your Own Versioning Scheme
» Serialization Depends on Reflection Serialization Has a Verbose Data Format
» It Is Easy to Send More Data Than Is Required
» Comparing Externalizable to Serializable
» The Calling Stack Basic Terminology
» The Heap Threads Basic Terminology
» Mutexes Applying This to the Printer Server
» Controlling Individual Threads Threading Concepts
» Coordinating Thread Activities Threading Concepts
» Cache Management Assigning Priorities to Threads
» The effects of synchronization on the threads local cache
» The wait methods The notify methods
» Starting a thread is easy Stopping a thread is harder
» Using Runnable instead of subclassing Thread Useful methods defined on the Thread class
» The Basic Task Implementing Threading
» Applying this to the bank example
» Synchronize around the smallest possible block of code
» Dont synchronize across device accesses
» Concurrent modification exceptions Be Careful When Using Container Classes
» Start with Code That Works Use Containers to Mediate Interthread Communication
» Immutable Objects Are Automatically Threadsafe Always Have a Safe Way to Stop Your Threads
» Pay Careful Attention to What You Serialize
» Use Threading to Reduce Response-Time Variance Limit the Number of Objects a Thread Touches
» Acquire Locks in a Fixed Order Use Worker Threads to Prevent Deadlocks
» The Idea of a Pool Two Interfaces That Define a Pool
» A First Implementation of Pooling
» Problems with SimplePool Pools: An Extended Example
» The Creation Thread Pools: An Extended Example
» Gradually Shrinking the Pool
» What Were Testing Testing the Bank Application
» When Are Naming Services Appropriate?
» bind , rebind , and unbind lookup and list
» Bootstrapping the Registry The RMI Registry Is an RMI Server
» Querying the Registry Launching an Application-Specific Registry
» Filesystems Yellow pages The general idea of directories and entries
» Security Issues The RMI Registry
» Operations on contexts Hierarchies
» Attributes are string-valued, name-value pairs
» Federation Federation and Threading
» Value Objects Represent Sets and Lists Paths, Names, and Attributes Are All Distinct
» AttributeSet The Value Objects
» Path and ContextList The Value Objects
» The Context Interface The Java Naming and Directory Interface JNDI
» Using JNDI with the Bank Example
» How RMI Solves the Bootstrapping Problem
» Ordinary Garbage Collection Distributed Garbage Collection
» Defining Network Garbage Distributed Garbage Collection
» Leasing Distributed Garbage Collection
» The Actual Distributed Garbage Collector The Unreferenced Interface
» The Standard Log RMIs Logging Facilities
» The Specialized Logs RMIs Logging Facilities
» java.rmi.server.randomIDs sun.rmi.server.exceptionTrace
» sun.rmi.dgc.client.gcInterval sun.rmi.dgc.server.gcInterval
» sun.rmi.dgc.checkInterval sun.rmi.dgc.cleanInterval
» Resource Management Factories and the Activation Framework
» A Basic Factory Implementing a Generic Factory
» The new factory Building on the Account-Locking Mechanism
» The new account The launch code and the client
» Persistence and the Server Lifecycle
» Making a server into an activatable object
» Deploying an Activatable System
» ActivationDesc, ActivationGroupDesc, and ActivationGroup in More Detail
» Shutting Down an Activatable Server
» -port -log rmid Command-Line Arguments
» sun.rmi.server.activation.debugExec
» A Final Word About Factories
» Implementing Serializable Implementing equals and hashCode
» Modifying Ordinary Servers Incorporating a Custom Socket into an Application
» Modifying Activatable Servers Incorporating a Custom Socket into an Application
» Interaction with Parameters Incorporating a Custom Socket into an Application
» A Redeployment Scenario How Dynamic Classloading Works
» A Multiple-Deployment Scenario How Dynamic Classloading Works
» Requesting a Class The Class Server
» Receiving a Class Handling JAR files
» Suns Class Server The Class Server
» Server-Side Changes Using Dynamic Classloadingin an Application
» Naming-Service Changes Using Dynamic Classloadingin an Application
» Client-Side Changes Disabling Dynamic Classloading Entirely
» A Different Kind of Security Problem
» AWT permissions The Types of Permissions
» File permissions Socket permissions
» Property permissions The Types of Permissions
» Installing an Instance of SecurityManager
» How a Security Manager Works java.security.debug
» Using Security Policies with RMI Policy Tool
» Printer-Type Methods Report-Type Methods
» Client-side polling Polling code in the printer application
» Server-side callbacks Define a client-side callback interface
» Implement the client-side interface
» Server-evaluation models Ch a pt e r 7
» Iterators on the client side
» Implementing Background Downloading on the Client Side
» The Common Gateway Interface Servlets
» Naming services and the server machine
» The Servlet Code A Servlet Implementationof HTTP Tunneling
» Modifying the Tunneling Mechanism
» Disabling HTTP Tunneling HTTP Tunneling
» Defining the Interface Generating Stubs and Skeletons
» The Server The Launch and Client Code
Show more