A Final Word About Factories
17.6.6.6 sun.rmi.server.activation.debugExec
This is the simplest, and possibly the most useful, of the rmid parameters. Its boolean valued. If its set to true , then the activation system will print out the command line used to create JVMs. This can really help in debugging an activatable system. You get to see exactly what parameters and properties are set in the created JVMs. The default for sun.rmi.server.activation.debugExec is false . In addition to these parameters, has some security -related parameters that we will discuss in Chapt er 1917.7 A Final Word About Factories
In this chapter, we discussed the idea of a factory. At its most fundamental level, a factory is a server that launches other servers in response to client demands. However, a factory is more than just a remote constructor; its also a way to share resources among clients, and its a very convenient place to insert code that manages the server lifecycle. Theres another interesting point lurking here. Factories simplify client applications by providing client applications with the illusion of persistent servers. Consider the typical account server in our example. From the clients point of view, this server is always up and always available. The client calls the factory, using a method call that looks quite a bit like a naming-system lookup call. In response, the client gets a stub to a server. As long as the client holds on to the stub, the distributed garbage collector will keep the server alive, and the stub will be a valid reference. If the client discards the stub and then makes another request to the factory, the client will get another stub. Its quite possible that in the interim, the account server was shut down, and the new stub the client gets is actually for an entirely different instance of Account but with the same state as the previous instance. However, this fact is completely hidden from the client application. This can be summarized in two points: • Factories enable the automatic launching and shutdown of servers and provide an ideal mechanism for inserting persistence code. As such, they greatly simplify the design and implementation of large sets of similar server objects. • Factories enable clients to be written as if all the associated servers are up all the time. They also greatly simplify the design and implementation of client code. These two points make factories an incredibly important and versatile tool in the fight against application complexity. Part III: Advanced Topics Chapter 18. Using Custom Sockets One of the major themes of this book is that RMI, for all its power and convenience, is really just a layer implemented on top of the standard socket objects shipped with the JDK. In this chapter, I build on this theme by showing how to replace the standard cleartext sockets that RMI uses with other sockets. The fact that RMI allows you to do this, and to do this differently for each type of server, is a very powerful feature. By the end of this chapter, youll understand how to change the sockets that RMI uses and know when doing so is an appropriate design strategy. As Ive mentioned countless times, RMI is built on top of sockets. This means that: • Data sent between clients and servers in both directions is sent using a streams interface. • Connections between clients and servers are created and maintained by using the socket classes defined in the java.net package. • RMI doesnt make any assumptions about the underlying network infrastructure or communication protocol. Understanding these points, and what they imply, is crucial for understanding how RMI works under the covers. However, the strict separation they imply between RMI on the one hand, and the operating system and network transport protocol on the other, also leads quite naturally to the following thought: If I can define a new socket class, and my socket-level communications protocols will work with it, then my RMI applications, which are built on top of sockets and dont make any assumptions about the underlying network, should also be able to run on top of my new sockets. Indeed, this turns out to be the case. RMI, through the definition of custom socket factories, contains a remarkably flexible way of letting you use whatever sockets you feel like using to handle the raw bits that need to get sent over the wire. Why Use a Custom Socket Class? By default, RMI uses the standard socket classes defined in the java.net package to send information over the wire. Servers use instances of ServerSocket to listen for connections, and clients initiate connections using instances of Socket . These sockets send information as plain text, without any encryption or compression, and thus involve a trade-off. On the positive side, they involve the least CPU usage information is not transformed in any way and are the most straightforward to use. The latter is true because compression can get a little tricky. The semantics of flush , especially with GZIPOutputStream , are not entirely compatible with the idea of sending remote method invocations as discrete and self - contained units. On the negative side, they use more bandwidth than needed, and information is very vulnerable while its being sent over the network. This leads to two reasons for using custom sockets: • If youre not on a secured network, and the information being sent across the wire is sensitive, you may want to use encrypting sockets, such as the SSL sockets we discussed in Chapt er 2 . • If youre on a very congested network where bandwidth is an issue, you may want to compress information before sending it over the wire. In both of these cases, an explicit trade is made: single -machine resources, such as CPU time, are used to transform data for better network characteristics. In addition to these trade-offs, there are local e.g., not involving how data is sent over the network reasons to use a custom socket. One common reason is to monitor socket usage and track how much information is sent over the wire. This is an important part of performance profiling and may, in fact, lead to the use of compressing sockets.18.1 Custom Socket Factories
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