Java分布式计算


by Jim Farley ISBN 1-56592-206-9E First edition, published January 1998. (See the catalog page for this book.) Search the text of Java™ Distributed Computing. Table of Contents Copyright Preface Chapter 1: Introduction Chapter 2: Networking in Java Chapter 3: Distributing Objects Chapter 4: Threads Chapter 5: Security Chapter 6: Message-Passing Systems Chapter 7: Databases Chapter 8: Bandwidth-Limited Systems Chapter 9: Collaborative Systems Chapter 10: Building Collaborative Applications Appendix A: Using the Examples in Applets Appendix B: CORBA Services Appendix C: JavaSpaces Appendix D: RMI Quick Reference Index Colophon Copyright © 2001 O'Reilly & Associates. All rights reserved. Full Text Search If you are having difficulty searching, or if you have not used this search utility before, please read this. Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved. Copyright © 2001 O'Reilly & Associates, Inc. All rights reserved. Java™ Distributed Computing by Jim Farley ISBN 1-56592-206-9E Print book published 1998 by O'Reilly & Associates, Inc., 101 Morris Street, Sebastopol, CA 95472. This electronic publication is intended for use by one individual. As such, you may make copies for your own personal use. However, you may not provide copies to others, or make this publication available to others over a LAN or other network. You may not reprint, offer for sale, or otherwise re-use material from this publication without the explicit written permission of O'Reilly & Associates, Inc. You can purchase print editions of these books directly from O'Reilly & Associates, Inc. or from bookstores that carry O'Reilly & Associates books. Logos and Trademarks Java™ and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems, Inc., in the United States and other countries. O'Reilly & Associates, Inc. is independent of Sun Microsystems. The O'Reilly logo is a registered trademark of O'Reilly & Associates, Inc. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and O'Reilly & Associates, Inc. was aware of a trademark claim, the designations have been printed in caps or initial caps. The use of the Gabriel® Original Tinkertoy® Construction Set image in association with Java™ Distributed Computing is a trademark of O'Reilly & Associates, Inc. Disclaimer While every precaution has been taken in the preparation of this product, the publisher assumes no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein. Questions, comments, and suggestions to bookquestions@ora.com. Table of Contents Preface Copyright © 2001 O'Reilly & Associates. All rights reserved. Java Distributed Computing Preface In a sense, distributed computing has been with us since the beginning of computer technology. A conventional computer can be thought of as "internally distributed," in the sense that separate, distinct devices within the computer are responsible for certain well-defined tasks (arithmetic/logic operations, operator stack storage, short/long-term data storage). These "distributed" devices are interconnected by communication pathways that carry information (register values, data) and messages (assembler instructions, microcode instructions). The sources and destinations of these various pathways are literally hardwired, and the "protocols" that they use to carry information and messages are rigidly defined and highly specific. Reorganizing the distribution scheme of these devices involves chip fabrication, soldering, and the recoding of microprograms, or the construction of a completely new computer. This level of inflexibility offers benefits, however, in terms of processing speed and information-transfer latencies. The functions expected of a computing device at this level are very well defined and bounded (perform arithmetic and logic operations on data, and store the results); therefore, the architecture of the device can and should be highly optimized for these tasks. The history of truly distributed computing begins with the first day that someone tapped a mainframe operator on the shoulder and asked, "Hey, is there any way we can both use that?" Display terminals, with no computing capabilities themselves, were developed to be attached to monolithic central computing devices, and to communicate with them in very rigid and limited protocols. This allowed multiple users to access and submit jobs to the mainframe. Other I/O devices also needed to be attached to the mainframe, generally to store and retrieve data to/from other non-volatile forms (printed storage such as paper tape and punch cards, and later magnetic storage devices). For the most part, the physical links and communications protocols used to hook in these devices were custom designed for each case, and not reusable for other devices. Meanwhile, people began to desire personal, dedicated computing resources that were available on demand, not when the mainframe schedule said so. The personal computer fit the bill, and its popularity has been growing ever since. Personal computers and workstations, despite the larger numbers of units, followed a similar evolutionary path to mainframes with respect to peripheral devices. Many and varied hardware and communications protocols were born to allow printers, disk drives, pointing devices, and the like to be connected to people's desktop computers. At first, peripheral vendors saw these custom-fit solutions as a potential for competitive advantage in the market; i.e., make your hardware or software faster or more laden with features than the next product, to become the preferred vendor of whatever it is you make. Gradually, both users and makers of personal computers became weary of this game. Users became frustrated with the lack of consistency in the installation, use, and maintenance of these devices, and computer makers were faced with an array of hardware and software interfaces, from which they had to choose the most advantageous ones to support directly in their hardware and operating systems. This became one of the major attractions for buyers of Apple's computer line, second only to their user-friendly operating system. Apple defined and strictly controlled the hardware and software interfaces to their systems, thereby guaranteeing that any third-party devices or software that followed their specifications and standards would operate correctly with their computers. The concept of standards for hardware and software interfaces caught on at many levels. Standards for every level of distributed computing, from hardware interfaces, network cabling, and physical-level communications protocols, all the way up to application-level protocols, were developed, refined, and promoted in the marketplace. Some standards achieved a critical usage mass, for various reasons, and persist today, such as Ethernet, TCP/IP, and RPC. Others were less popular, and faded with time. Today, both computing devices and network bandwidth have begun to achieve commodity status. A set of standard protocols, some of which make up the World Wide Web, are beginning to evolve into a worldwide network operating system. Specifics about the type of hardware, operating system, and network being used are becoming more and more irrelevant, making information and tools to process information more and more easily deployable and available. Security protocols have been defined to help owners of information and services restrict access to them. Researchers and developers are looking forward to the next evolutionary steps in information technology, such as autonomous agents and enterprise-wide distributed object systems. In the midst of this revolutionary period, Java™ can be viewed as both a product and a catalyst of all of these trends. Java offers an environment in which the network is truly the computer, and specifics such as operating system features and transport protocols become even more blurred and less important, though not yet completely irrelevant. The Java language and environment promise to play a prominent part in the next generation of distributed computing. 0.1. What Does This Book Cover? This book is an overview of the tools and techniques that are at your disposal for building distributed computing systems in Java. In most cases, these tools are provided inherently in the Java API itself, such as the Java Remote Method Invocation (RMI) API, the Java Security API, and the Java™ Database Connectivity ( JDBC) package. Other tools are standards and protocols that exist independently of Java and its environment, but are supported within Java, either through its core APIs or by add-on APIs offered by third-party vendors. Some examples include the Common Object Request Broker Adapter (CORBA) standards, the multicast IP protocol, and the Secure Socket Layer (SSL) standard. I intend this book to serve as both explanatory and reference material for you, the professional developer. Most of the book is made up of detailed explanations of concepts, tools, and techniques that come into play in most distributed computing situations. At the same time, for readers who are more familiar with the subject matter, the text and code examples are broken up into subject areas that should make it fairly easy to reference important bits. 0.1.1. Organization The first four chapters of the book (after the Introduction) cover some fundamental tools that come into play in most distributed applications: basic networking tools, distributed objects, multithreading, and security measures. The last five chapters go into detail about some common types of distributed applications: message-passing systems, multitier systems involving databases, bandwidth-limited systems, and systems that allow multiple distributed users or user agents to collaborate dynamically over a network; and discuss the special issues that arise in each. The figure on the next page shows the dependence of the various chapters on each other, to give you a sense of the order (random or otherwise) that you can choose as you journey through the book. Since the Introduction covers some concepts and terminology that will persist throughout the book, I'd suggest reading it before any of the others. The next four chapters can be read in just about any order, depending on your level of experience with each topic. Since the later chapters use concepts from all of the chapters in the first part of the book, you should have a basic understanding of their topics, either from personal experience or from reading the earlier chapters, before delving into the second part of the book. Copyright Page 0.2. Who Should Read This Book? Copyright © 2001 O'Reilly & Associates. All rights reserved. Java Distributed Computing Chapter 1. Introduction Contents: Anatomy of a Distributed Application Requirements for Developing Distributed Applications What Does Java Provide? For the past decade, "distributed computing" has been one of the biggest buzz phrases in the computer industry. At this point in the information age, we know how to build networks; we use thousands of engineering workstations and personal computers to do our work, instead of huge behemoths in glass- walled rooms. Surely we ought to be able to use our networks of smaller computers to work together on larger tasks. And we do--an act as simple as reading a web page requires the cooperation of two computers (a client and a server) plus other computers that make sure the data gets from one location to the other. However, simple browsing (i.e., a largely one-way data exchange) isn't what we usually mean when we talk about distributed computing. We usually mean something where there's more interaction between the systems involved. You can think about distributed computing in terms of breaking down an application into individual computing agents that can be distributed on a network of computers, yet still work together to do cooperative tasks. The motivations for distributing an application this way are many. Here are a few of the more common ones: ● Computing things in parallel by breaking a problem into smaller pieces enables you to solve larger problems without resorting to larger computers. Instead, you can use smaller, cheaper, easier-to- find computers. ● Large data sets are typically difficult to relocate, or easier to control and administer located where they are, so users have to rely on remote data servers to provide needed information. ● Redundant processing agents on multiple networked computers can be used by systems that need fault tolerance. If a machine or agent process goes down, the job can still carry on. There are many other motivations, and plenty of subtle variations on the ones listed here. Assorted tools and standards for assembling distributed computing applications have been developed over the years. These started as low-level data transmission APIs and protocols, such as RPC and DCE, and have recently begun to evolve into object-based distribution schemes, such as CORBA, RMI, and OpenDoc. These programming tools essentially provide a protocol for transmitting structured data (and, in some cases, actual runnable code) over a network connection. Java offers a language and an environment that encompass various levels of distributed computing development, from low-level network communication to distributed objects and agents, while also having built-in support for secure applications, multiple threads of control, and integration with other Internet-based protocols and services. This chapter gives an introduction to distributed application development, and how Java can be used as a tool towards this end. In the following chapters, we'll start by reviewing some essential background material on network programming, threads, and security. Then we'll move into a series of chapters that explore different distributed problems in detail. Where appropriate, we'll use RMI, CORBA, or a homegrown protocol to implement examples. If you are developing distributed applications, you need to be familiar with all possible solutions and where they're appropriate; so where we choose a particular tool, we'll try to discuss how things would be better or worse if you chose a different set of tools in building something similar. 1.1. Anatomy of a Distributed Application A distributed application is built upon several layers. At the lowest level, a network connects a group of host computers together so that they can talk to each other. Network protocols like TCP/IP let the computers send data to each other over the network by providing the ability to package and address data for delivery to another machine. Higher-level services can be defined on top of the network protocol, such as directory services and security protocols. Finally, the distributed application itself runs on top of these layers, using the mid-level services and network protocols as well as the computer operating systems to perform coordinated tasks across the network. At the application level, a distributed application can be broken down into the following parts: Processes A typical computer operating system on a computer host can run several processes at once. A process is created by describing a sequence of steps in a programming language, compiling the program into an executable form, and running the executable in the operating system. While it's running, a process has access to the resources of the computer (such as CPU time and I/O devices) through the operating system. A process can be completely devoted to a particular application, or several applications can use a single process to perform tasks. Threads Every process has at least one thread of control. Some operating systems support the creation of multiple threads of control within a single process. Each thread in a process can run independently from the other threads, although there is usually some synchronization between them. One thread might monitor input from a socket connection, for example, while another might listen for user events (keystrokes, mouse movements, etc.) and provide feedback to the user through output devices (monitor, speakers, etc.). At some point, input from the input stream may require feedback from the user. At this point, the two threads will need to coordinate the transfer of input data to the user's attention. Objects Programs written in object-oriented languages are made up of cooperating objects. One simple definition of an object is a group of related data, with methods available for querying or altering the data (getName(), set-Name()), or for taking some action based on the data (sendName(Out- putStreamo)). A process can be made up of one or more objects, and these objects can be accessed by one or more threads within the process. And with the introduction of distributed object technology like RMI and CORBA, an object can also be logically spread across multiple processes, on multiple computers. Agents For the sake of this book, we will use the term "agent" as a general way to refer to significant functional elements of a distributed application.[1] While a process, a thread, and an object are pretty well-defined entities, an agent (at least the definition we'll use for the sake of this book) is a higher-level system component, defined around a particular function, or utility, or role in the overall system. A remote banking application, for example, might be broken down into a customer agent, a transaction agent and an information brokerage agent. Agents can be distributed across multiple processes, and can be made up of multiple objects and threads in these processes. Our customer agent might be made up of an object in a process running on a client desktop that's listening for data and updating the local display, along with an object in a process running on the bank server, issuing queries and sending the data back to the client. There are two objects running in distinct processes on separate machines, but together we can consider them to make up one customer agent, with client-side elements and server-side elements. [1]The term "agent" is overused in the technology community. In the more formal sense of the word, an agent is a computing entity that is a bit more intelligent and autonomous than an object. An agent is supposed to be capable of having goals that it needs to accomplish, such as retrieving information of a certain type from a large database or remote data sources. Some agents can monitor their progress towards achieving their goals at a higher level than just successful execution of methods, like an object. The definition of agent that we're using here is a lot less formal than this, and a bit more general. So a distributed application can be thought of as a coordinated group of agents working to accomplish some goal. Each of these agents can be distributed across multiple processes on remote hosts, and can consist of multiple objects or threads of control. Agents can also belong to more than one application at once. You may be developing an automated teller machine application, for example, which consists of an account database server, with customer request agents distributed across the network submitting requests. The account server agent and the customer request agents are agents within the ATM application, but they might also serve agents residing at the financial institution's headquarters, as part of an administrative application. 0.5. Acknowledgments 1.2. Requirements for Developing Distributed Applications Copyright © 2001 O'Reilly & Associates. All rights reserved. Java Distributed Computing Chapter 2. Networking in Java Contents: Sockets and Streams URLs, URLConnections, and ContentHandlers The ClassLoader We saw in Chapter 1, "Introduction" how the socket and stream classes in the java.net and java.io packages could be used to do basic networking between agents. In this chapter we take a more detailed look at the networking support in Java, as the foundation for distributed systems. The topics we'll cover include: ● Sockets for low-level network connections ● Streams for formatted data and messaging protocols ● URL, URLConnection, and ContentHandler classes ● The ClassLoader as an object distribution scheme We'll look at these topics in increasing pecking order from the networking perspective. Sockets first, since they are the most primitive communication object in the Java API; then streams, which let you impose some order on the data flowing over these sockets; next, the classes associated with the HTTP protocol, namely, the URL, URLConnection, and ContentHandler classes; finally, the ClassLoader, which, when coupled with the others, offers the ability to transmit actual Java classes over the wire. 2.1. Sockets and Streams The java.net package provides an object-oriented framework for the creation and use of Internet Protocol (IP)[1] sockets. In this section, we'll take a look at these classes and what they offer. [1]The Internet Protocol is the predominant networking protocol today, being the protocol in use on the Internet and on most corporate WANs and LANs. 2.1.1. IP Addressing Before communicating with another party, you must first know how to address your messages so they can be delivered correctly. Notice that I didn't say that you need to know where the other party is located--once a scheme for encoding a location is established, I simply need to know my party's encoded address to communicate. On IP networks, the addressing scheme in use is based on hosts and port numbers. A given host computer on an IP network has a hostname and a numeric address. Either of these, in their fully qualified forms, is a unique identifier for a host on the network. The JavaSoft home page, for example, resides on a host named www.javasoft.com, which currently has the IP address 204.160.241.98. Either of these addresses can be used to locate the machine on an IP network. The textual name for the machine is called its Domain Name Services (DNS) name, which can be thought of as a kind of alias for the numeric IP address. In the Java API, the InetAddress class represents an IP address. You can query an InetAddress for the name of the host using its getHostName() method, and for its numeric address using getAddress() . Notice that, even though we can uniquely specify a host with its IP address, we do not necessarily know its physical location. I look at the web pages on www.javasoft.com regularly, but I don't know where the machine is (though I could guess that it's in California somewhere). Conversely, even if I knew where the machine was physically, it wouldn't do me a bit of good if I didn't know its IP address (unless someone was kind enough to label the machine with it, or left a terminal window open on the server's console for me to get its IP address directly). Now, you typically don't want to communicate with a given host, but rather with one or many agent processes running on the host. To engage in network communications, each process must associate itself with a port on the host, identified by a number. HTTP servers, for example, typically attach themselves to port 80 on their host machine. When you ask to connect to http://www.javasoft.com/ from your web browser, the browser automatically assumes the default port and attempts to connect to the process running on www.javasoft.com listening to port 80. If this process is an HTTP server process that understands the commands that the browser is sending, the browser and the server will commence communications. This host/port scheme is the basis of the IP addressing protocol, and is supported directly in the Java API. All network connections are specified using an Inet-Address and a port number. The Java environment does the hard work of initiating the IP protocol communications and creating Java objects that represent these network connections. 2.1.2. Your Basic Socket At the core of Java's networking support are the Socket and DatagramSocket classes in java.net. These classes define channels for communication between processes over an IP network. A new socket is created by specifying a host, either by name or with an InetAddress object, and a port number on the host. There are two basic flavors of network sockets on IP networks: those that use the Transmission Control Protocol (TCP) and those that use the User Datagram Protocol (UDP). TCP is a reliable protocol in which data packets are guaranteed to be delivered, and delivered in order. If a packet expected at the receiving end of a TCP socket doesn't arrive in a set period of time, then it is assumed lost, and the packet is requested from the sender again. The receiver doesn't move on to the next packet until the first is received. UDP, on the other hand, makes no guarantees about delivery of packets, or the order in which packets are delivered. The sender transmits a UDP packet, and it either makes it to the receiver or it doesn't. TCP sockets are used in the large majority of IP applications. UDP sockets are typically used in bandwidth- limited applications, where the overhead associated with resending packets is not tolerable. A good example of this is real-time network audio applications. If you are delivering packets of audio information over the network to be played in real-time, then there is no point in resending a late packet. By the time it gets delivered it will be useless, since the audio track must play continuously and sequentially, without backtracking. The Socket class is used for creating TCP connections over an IP network. A Socket is typically created using an InetAddress to specify the remote host, and a port number to which the host can connect. A process on the remote host must be listening on that port number for incoming connection requests. In Java, this can be done using a ServerSocket: // Listen to port 5000 on the local host for socket connection requests ServerSocket s = new ServerSocket(5000); while (true) { // Wait for a connection request from a client Socket clientConn = s.accept(); InputStream in = clientConn.getInputStream(); OutputStream out = clientConn.getOutputStream(); // Now we have input and output streams connected to our client, do // something with them... On client side, the code simply creates a socket to the remote host on the specified port (5000, in this case): // Create the socket InetAddress addr = InetAddress.getByName("our.remote.host"); Socket s = new Socket(addr, 5000); InputStream in = s.getInputStream(); OutputStream out = s.getOutputStream(); // We've got input/output streams to the remote process, // now do something with them... UDP socket connections are created and used through the DatagramSocket and DatagramPacket classes. A DatagramSocket sends and receives data using UDP packets, represented as DatagramPacket objects. Before two agents can talk to each other over a UDP connection, they both have to have a DatagramSocket connected to a port on their local machines. This is done by simply creating a DatagramSocket object: DatagramSocket udpSocket = new DatagramSocket(5000); In this example we are connecting a UDP socket to a specific port (5000) on the local host. If we don't particularly care which port is used, then we can construct the DatagramSocket without specifying the port. An unused port on the local host will be used, and we can find out which one by asking the new socket for its port number: DatagramSocket udpSocket = new DatagramSocket(); int portNo = udpSocket.getLocalPort(); In order for two agents to send data to each other over a UDP socket, they must know the host name and port number of each other's socket connection. So they will either have preordained ports for each other and will create DatagramSockets using these port numbers, or they will create a socket on a random local port and transmit their port numbers to each other over another connection. Data is sent over a DatagramSocket using DatagramPacket objects. Each DatagramPacket contains a data buffer, the address of the remote host to send the data to, and the port number the remote agent is listening to. So to send a buffer of data to a process listening to port 5000 on host my.host.com, we would do something like this: byte[] dataBuf = {'h', 'i', ' ', 't', 'h', 'e', 'r', 'e'}; InetAddress addr = InetAddress.getByName("my.host.com"); DatagramPacket p = new DatagramPacket(dataBuf, dataBuf.length, addr, 5000); udpSocket.send(p); The remote process can receive the data in the form of a DatagramPacket by calling the receive() method on its DatagramSocket. The received DatagramPacket will have the host address and port of the sender filled in as a side-effect of the call. Note that in all of the examples, we would have to catch the appropriate exceptions and handle them. Sending a DatagramPacket, for example, can generate an IOException if the network transmission fails for some reason. A robust networked program will catch this exception and behave appropriately, perhaps by resending the packet if the application warrants, or perhaps by simply noting the lost packet and continuing. 2.1.3. Multicast Sockets There is a subset of the IP protocol that supports multicasting . Multicasting can be thought of as broadcasting data over a network connection to many connected agents, as opposed to unicasting packets between two agents on a normal connection. Multicasting is done using UDP packets that are broadcast out on a multicast IP address. Any agent "listening in" to that IP address will receive the data packets that are broadcast. The analogy to radio and television broadcasting is no accident--the very first practical uses of multicast IP were for broadcasting audio and video over the Internet from special events.[2] [2]For more information on the history of the multicast backbone (MBONE) and its current state, visit http://www.mbone.com/. Java supports multicast IP through the java.net.MulticastSocket class, which is an extension of the DatagramSocket class. Joining a multicast group is done almost the same way that you would establish a UDP connection between two agents. Each agent that wants to listen on the multicast address creates a MulticastSocket and then joins the multicast session by calling the joinGroup() method on the MulticastSocket: MulticastSocket ms = new MulticastSocket(); InetAddress sessAddr = InetAddress.getByName("224.2.76.24"); ms.joinGroup(sessAddr); Once the connection to the multicast session is established, the agent can read data being broadcast on the multicast "channel": byte[] audioBuf = new byte[1024]; DatagramPacket dp = new DatagramPacket(audioBuf, 1024); ms.receive(dp); // Play the data on a fictitious audio device myAudioDevice.play(dp.getData()); Data can also be sent out on the multicast channel to all the other listening agents using the send() method on the MulticastSocket. Once the broadcast is over, or we simply want to stop listening, we can disconnect from the session using the leaveGroup() method: ms.leaveGroup(sessAddr); Multicasting is useful when we want to connect many agents together on a common communication channel. Shared audio and video channels are the most obvious uses, but multicasting can also be applied in collaborative tools like shared whiteboards, or between application servers performing synchronization tasks, like load balancing. However, since multicast IP is based on UDP, you have to be willing to accept the possibility of losing some data along the way, and dealing with it gracefully. Also, since clients can join a multicast session asynchronously, they have to be ready to synchronize themselves with the current state of the multicast session when they join. 2.1.4. Streams, Readers, and Writers for Input and Output Once we make a connection between two processes over the network, we need a simple, easy way to send and receive data in different formats over the connection. Java provides this through the stream classes in the java.io package. Included in the java.io package are the InputStream and OutputStream classes and their subclasses for byte- based I/O, and the Reader and Writer classes and their subclasses for character-based I/O. The InputStream and OutputStream classes handle data as bytes, with basic methods for reading and writing bytes and byte arrays. Their subclasses can connect to various sources and destinations (files, string buffers), and provide methods for directly sending and receiving basic Java data types, like floating-point values. The Reader and Writer classes transmit data in the form of 16-bit Unicode characters, which provides a platform-independent way to send and receive textual data. Like the InputStream and OutputStream subclasses, the subclasses of Reader and Writer specialize in terms of their source and destination types. A Socket, once it's created, can be queried for its input/output streams using getInputStream() and getOutputStream(). These methods return in-stances of InputStream and OutputStream, respectively. If you need to exchange mostly character-based data between two agents in your distributed system, then you can wrap the InputStream with an InputStreamReader(a subclass of Reader), or the OutputStream with an OutputStreamWriter (a subclass of Writer). Another way to create an interprocess communication link is to use the java.lang.Runtime interface to execute a process, then obtain the input and output streams from the returned Process object, as shown in Example 2-1. You would do this if you had a local subtask that needed to run in a separate process, but with which you still needed to exchange messages. Example 2-1. Interprocess I/O Using Runtime-Executed Processes Runtime r = Runtime.getRuntime(); Process p = r.exec("/bin/ls /tmp"); InputStream in = p.getInputStream(); OutputStream out = p.getOutputStream(); From the abstract I/O classes, the java.io package offers several specializations which vary the format of the data transmitted over the stream, as well as the type of data source/receiver at the ends of the stream. The InputStream, OutputStream, Reader, and Writer classes provide basic interfaces for data I/O (read() and write() methods that just transfer bytes, byte arrays, characters and character arrays). To define data types and communication protocols on top of these base classes, Java offers the FilterInputStream and FilterOutputStream classes for byte-oriented I/O, and the FilterReader and FilterWriter for character-based I/O. Subclasses of these offer a higher level of control and structure to the data transfers. A BufferedInputStream or BufferedReader uses a memory buffer for efficient reading of data. The overhead associated with data read requests is minimized by performing large data reads into a buffer, and offering data to the caller from the local buffer until it's been exhausted. This feature can be used to minimize the latency associated with slow source devices and communication media. The BufferedOutputStream or BufferedWriter performs the same service on outgoing data. A PushbackInputStream or PushbackReader provides a buffer for pushing back data onto the incoming data stream. This is useful in parsing applications, where the next branch in the parse tree is determined by peeking at the next few bytes or characters in the stream, and then letting the subparser operate on the data. The other interesting subclasses of FilterInputStream and FilterOutputStream are the DataInputStream and DataOutputStream classes. These classes read and write Java data primitives in a portable binary format. There aren't similar subclasses of FilterReader and FilterWriter, since Readers and Writers only transfer character data, and the serialized form of Java data types are represented in bytes. Besides being useful in their own right for manipulating and formatting input/output data streams, the subclasses of FilterInputStream, FilterOutputStream, FilterReader, and FilterWriter are also well suited for further specialization to define application-specific data stream protocols. Each of the stream classes offers a constructor method, which accepts an InputStream or OutputStream as an argument. Likewise, the FilterReader class has a constructor that accepts a Reader, and FilterWriter has a constructor that accepts a Writer object. In each case, the constructor argument is taken as the source or sink of the stream that is to be filtered, which enables the construction of stream filter "pipelines." So defining a special-purpose data protocol is simply a matter of subclassing from an appropriate I/O class, and wrapping an existing data source or sink with the new filter. For example, if we wanted to read an XDR-formatted[3] data stream, we could write a subclass of FilterInputStream that would offer the same methods to read Java primitive data types as DataInputStream, but would be implemented to parse the XDR format, rather than the portable binary format of the DataInputStream. Example 2-2 shows a skeleton for the input version of this kind of stream; Example 2-2 shows a sample application using the stream. The application first connects to a host and port, where presumably another process is waiting to accept this connection. The remote process uses XDR-formatted data to communicate, so we wrap the input stream from the socket connection with our XDRInputStream and begin reading data. [3]XDR is the binary format underlying Remote Procedure Call (RPC) data connections. Example 2-2. An InputStream Subclass for Reading XDR-Formatted Data package dcj.examples; import java.io.*; import java.net.*; class XDRInputStream extends FilterInputStream { public XDRInputStream(InputStream in) { super(in); } // Overridden methods from FilterInputStream, implemented // to read XDR-formatted data public boolean readBoolean() throws IOException; public byte readByte() throws IOException; public int readUnsignedByte() thows IOException; public float readFloat() thows IOException; // Other readXXX() methods omitted in this example... // We'll assume this stream doesn't support mark/reset operations public boolean markSupported() { return false; } } Example 2-3. Example XDRInputStream Client import dcj.examples.XDRInputStream; import java.io.*; class XDRInputExample { public static void main(String argv[]) { String host = argv[0]; // Default port is 5001 int port = 5001; try { port = Integer.parseInt(argv[1]); } catch (NumberFormatException e) { System.out.println("Bad port number given, using default " + port); } // Try connecting to specified host and port Socket serverConn = null; try { serverConn = new Socket(host, port); } catch (UnknownHostException e) { System.out.println("Bad host name given."); System.exit(1); } // Wrap an XDR stream around the input stream XDRInputStream xin = new XDRInputStream(serverConn.getInputStream()); // Start reading expected data from XDR-formatted stream int numVals = xin.readInt(); float val1 = xin.readFloat(); ... } } The classes in the java.io package also offer the ability to specialize the sources and destinations of data.Table 2-1 summarizes the various stream, writer, and reader classes in java.io, and the types of sources and destinations that they can access. The purpose and use of the file, byte-array, and string classes are fairly obvious, and we won't spend any time going into detail about them here, since we'll see them being used in some of the examples later in the book. The stream classes that allow communication between threads deserve some explanation, though. Table 2-1. Source and Destination Types Supported by java.io Source/Destination Type Input/OutputStream Class Reader/Writer Class Remote or local process InputStream OutputStream (created from Socket or from Process) InputStreamReader OutputStreamWriter (wrappers around InputStream or OutputStream objects) Disk files FileInputStream FileOutputStream FileReader FileWriter In-memory data buffers ByteArrayInputStream ByteArrayOutputStream CharArrayReader CharArrayWriter In-memory string buffers StringBufferInputStream (input only) (deprecated in JDK 1.1, use StringReader instead) StringReader StringWriter Threads within same process PipedInputStream PipedOutputStream PipedReader PipedWriter The PipedInputStream and PipedOutputStream classes access data from each other. That is, a PipedInputStream reads data from a PipedOutputStream, and a PipedOutputStream writes data to a PipedInputStream. This class design allows the developer to establish data pipes between threads in the same process. Example 2-4 and Example 2-5 show client and server classes that use piped streams to transfer information, and Example 2-6 shows an application of these classes. Example 2-4. A Piped Client package dcj.examples; import java.lang.*; import java.net.*; import java.io.*; import java.util.*; public class PipedClient extends Thread { PipedInputStream pin; PipedOutputStream pout; public PipedClient(PipedInputStream in, PipedOutputStream out) { pin = in; pout = out; } public void run() { // Wrap a data stream around the input and output streams DataInputStream din = new DataInputStream(pin); DataOutputStream dout = new DataOutputStream(pout); // Say hello to the server... try { System.out.println("PipedClient: Writing greeting to server..."); dout.writeChars("hello from PipedClient\n"); } catch (IOException e) { System.out.println("PipedClient: Couldn't get response."); System.exit(1); } // See if it says hello back... try { System.out.println("PipedClient: Reading response from server..."); String response = din.readLine(); System.out.println("PipedClient: Server said: \"" + response + "\""); } catch (IOException e) { System.out.println("PipedClient: Failed to connect to peer."); } stop(); } } The example shows two threads, a client and a server, talking to each other over piped streams. The PipedClient class accepts a PipedInputStream and PipedOutputStream as constructor arguments; the PipedServer class does the same. Both are extensions of the Thread class. The client attempts to send a "hello" message to the server over its output stream, then listens for a response on its input stream. The server listens for the "hello" from the client on its input stream, then sends a response back on its output stream. The PipedStreamExample class sets up the stream connections for the threads by creating two pairs of piped streams. It then creates a PipedClient and a PipedServer, sends each the input stream from one pair and the output stream from the other, and tells each of them to start their threads. The important feature of this example is that the piped streams are connected to each other within the same process, and are not connected to any remote hosts. Example 2-5. A Piped Server package dcj.examples; import java.lang.*; import java.net.*; import java.io.*; public class PipedServer extends Thread { PipedInputStream pin; PipedOutputStream pout; public PipedServer(PipedInputStream in, PipedOutputStream out) { pin = in; pout = out; } public void run() { // Wrap a data stream around the input and output streams DataInputStream din = new DataInputStream(pin); DataOutputStream dout = new DataOutputStream(pout); // Wait for the client to say hello... try { System.out.println("PipedServer: Reading from client..."); String clientHello = din.readLine(); System.out.println("PipedServer: Client said: \"" + clientHello + "\""); } catch (IOException e) { System.out.println("PipedServer: Couldn't get hello from client."); stop(); } // ...and say hello back. try { System.out.println("PipedServer: Writing response to client..."); dout.writeChars("hello I am the server.\n"); } catch (IOException e) { System.out.println("PipedServer: Failed to connect to client."); } stop(); } } Example 2-6. Piped Stream Application package dcj.examples; import java.net.*; import java.io.*; import java.lang.*; import dcj.examples.PipedClient; import dcj.examples.PipedServer; class PipedStreamExample { public static void main(String argv[]) { // Make two pairs of connected piped streams PipedInputStream pinc = null; PipedInputStream pins = null; PipedOutputStream poutc = null; PipedOutputStream pouts = null; try { pinc = new PipedInputStream(); pins = new PipedInputStream(); poutc = new PipedOutputStream(pins); pouts = new PipedOutputStream(pinc); } catch (IOException e) { System.out.println( "PipedStreamExample: Failed to build piped streams."); System.exit(1); } // Make the client and server threads, connected by the streams PipedClient pc = new PipedClient(pinc, poutc); PipedServer ps = new PipedServer(pins, pouts); // Start the threads System.out.println("Starting server..."); ps.start(); System.out.println("Starting client..."); pc.start(); // Wait for threads to end try { ps.join(); pc.join(); } catch (InterruptedException e) {} System.exit(0); } } Note that a similar scenario could be set up using the PipedReader and PipedWriter classes, if you knew the two threads were going to exchange character arrays. 1.3. What Does Java Provide? 2.2. URLs, URLConnections, and ContentHandlers Copyright © 2001 O'Reilly & Associates. All rights reserved. Java Distributed Computing Chapter 3. Distributing Objects Contents: Why Distribute Objects? What's So Tough About Distributing Objects? Features of Distributed Object Systems Distributed Object Schemes for Java CORBA Java RMI RMI vs. CORBA Distributed objects are a potentially powerful tool that has only become broadly available for developers at large in the past few years. The power of distributing objects is not in the fact that a bunch of objects are scattered across the network. The power lies in that any agent in your system can directly interact with an object that "lives" on a remote host. Distributed objects, if they're done right, really give you a tool for opening up your distributed system's resources across the board. And with a good distributed object scheme you can do this as precisely or as broadly as you'd like. The first three sections of this chapter go over the motivations for distributing objects, what makes distributed object systems so useful, and what makes up a "good" distributed object system. Readers who are already familiar with basic distributed object issues can skip these sections and go on to the following sections, where we discuss two major distributed object protocols that are available in the Java environment: CORBA and RMI. Although this chapter will cover the use of both RMI and CORBA for distributing objects, the rest of the book primarily uses examples that are based on RMI, where distributed objects are needed. We chose to do this because RMI is a simpler API and lets us write relatively simple examples that still demonstrate useful concepts, without getting bogged down in CORBA API specifics. Some of the examples, if converted to be used in production environments, might be better off implemented in CORBA. 3.1. Why Distribute Objects? In Chapter 1, "Introduction", we discussed some of the optimal data/function partitioning capabilities that you'd like to have available when developing distributed applications. These included being able to distribute data/function "modules" freely and transparently, and have these modules be defined based on application structure rather than network distribution influences. Distributed object systems try to address these issues by letting developers take their programming objects and have them "run" on a remote host rather than the local host. The goal of most distributed object systems is to let any object reside anywhere on the network, and allow an application to interact with these objects exactly the same way as they do with a local object. Additional features found in some distributed object schemes are the ability to construct an object on one host and transmit it to another host, and the ability for an agent on one host to create a new object on another host. The value of distributed objects is more obvious in larger, more complicated applications than in smaller, simpler ones. That's because much of the trade-off between distributed objects and other techniques, like message passing, is between simplicity and robustness. In a smaller application with just a few object types and critical operations, it's not difficult to put together a catalog of simple messages that would let remote agents perform all of their critical operation through on-line transactions. With a larger application, this catalog of messages gets complicated and difficult to maintain. It's also more difficult to extend a large message-passing system if new objects and operations are added. So being able to distribute the objects in our system directly saves us a lot of design overhead, and makes a large distributed system easier to maintain in the long run. 2.3. The ClassLoader 3.2. What's So Tough About Distributing Objects? Copyright © 2001 O'Reilly & Associates. All rights reserved. Java Distributed Computing Chapter 4. Threads Contents: Thread and Runnable Making a Thread Managing Threads at Runtime Networked Threads In this chapter we will take a look at Java's support for multithreaded applications. The ability to create multithreaded applications is critical in distributed computing systems, since in many cases you'll want multiple clients to be able to make requests to agents in your system, and you'd like the agents to be as responsive as possible. Supporting asynchronous transactions introduces some new issues in developing any distributed application, and we'll take a look at how the thread support in Java helps you manage these issues. 4.1. Thread and Runnable The Java API includes two classes that embody the core thread support in the language. These classes are java.lang.Thread and java.lang.Runnable. They allow you to define threads of control in your application, and to manage threads in terms of runtime resources and running state. As the name suggests, java.lang.Thread represents a thread of control. It offers methods that allow you to set the priority of the thread, to assign a thread to a thread group (more on these in a later section), and to control the running state of the thread (e.g., whether it is running or suspended). The java.lang.Runnable interface represents the body of a thread. Classes that implement the Runnable interface provide their own run() methods that determine what their thread actually does while running. In fact, run() is the only method defined by the Runnable interface. If a Thread is constructed with a Runnable object as its body, the run() method on the Runnable will be called when the thread is started. 3.7. RMI vs. CORBA 4.2. Making a Thread Copyright © 2001 O'Reilly & Associates. All rights reserved. Java Distributed Computing Chapter 5. Security Contents: Security Issues and Concerns The java.security Package Identities and Access Control Keys: Public, Private, and Secret Digital Signatures Data Encryption Choosing a Cryptographic Algorithm Security becomes an issue as soon as you allow your computing resources to come in contact with the rest of the world. With the recent explosion in the use of networks, preserving the security of data and the resources that carry data has become a primary concern. An open communications port on any computing device almost always carries the potential for abuse: a malicious party may steal or damage sensitive information, network bandwidth, or any other resource associated with your site. Security measures can increase the effort needed for an intruder to gain access to these resources. In this chapter, we'll look at the Java Security API and how you can use it to make the agents in your distributed application safe from network hostility. We'll briefly discuss the kinds of security concerns you should have as a distributed application developer, and what tools are available in the Java environment for addressing these issues. Some of the issues we'll discuss are common across most applications, so the Java language developers have provided integrated features in the runtime environment that attempt to address them. An example of one of these features is the bytecode verifier, which prevents some kinds of malicious code from running on your machine. Other issues are only important in specific domains and applications, and it's your duty to determine how important these issues are to your particular application, what kinds of measures need to be taken, and how much effort needs to be invested in implementing these measures. For example, consider data theft from communications links. Is your data valuable enough to protect with data encryption, and if so, what level of encryption is appropriate, given the value of the data and the level of effort you can expect from those trying to steal it? The subject of security in networked environments is worthy of several books' worth of material, and you can find many readings on the subject. In this book, we will only have a superficial discussion of the technical aspects of network security and cryptography, with limited excursions into the details only where it is necessary to support a solid understanding of the topic. From this foundation, we can take an educated look at the security options available to you in the Java Security API, and where you might find them useful. The next section of this chapter discusses general security issues in networked environments. If you're already familiar with this topic, you can jump right to the later sections, which discuss the design and use of cryptographic security measures through the Java Security API. 5.1. Security Issues and Concerns Just about everything making up a site on a computer network is a resource with potential value. The most obvious resource you need to worry about is information--the data being sent over the network and the information residing on your host computers. Other resources that could be targets are the applications on your hosts, the CPU resources of your computers, even the bandwidth available on your communications links. A hostile party may want to steal these resources or do damage to them. Following are some of the things an attacker may do to steal or destroy your resources: Eavesdrop on network communications The hostile agent may physically tap into network lines, or set up rogue programs on other hosts to watch for interesting traffic. They may be trying to steal information, or gather information that will help them steal or damage other resources. Set up imposter agents or data sources This will let them fool you into sending valuable information or giving access to resources they shouldn't have. Our Solver servers could be accessed by intruders acting as legitimate clients, and used to solve their numerical problems; or a hostile party could flood the server with ProblemSets to be solved, rendering the server useless to the legitimate users. Clients of the Solver are also vulnerable, since a hostile party could set up an imposter Solver meant to steal the problem data submitted by clients, or they could purposely generate erroneous results. If the attacker manages to figure out that the clients are trying to solve for stress levels in a finite-element model, for example, then the imposter server could be set up to return results that indicate abnormally high or low stress levels in critical sections of the model. This could cause someone to design a bridge that will collapse, or that's too expensive to build. Directly or indirectly intrude on your site Once attackers have located your site, and maybe even stolen some information about what's on the site, they may try to break in to your host and steal or destroy resources directly. For example, attackers may try to crack passwords so that they can log onto your system. A more sophisticated approach is to take advantage of the class-loading and distributed-object features of Java to inject hostile agents directly into a remote host. For example, a client of the RMISolver from Chapter 3, "Distributing Objects" downloads a stub class that it uses for remote method calls to the server. A sophisticated attacker might try to create a "synthetic" remote stub, one whose methods have been modified to steal and transmit valuable information back to the attacker, or to do damage to the remote host from the inside. This discussion leads us to the following list of general security concerns for the distributed application developer: Verification of the identity of remote agents Any time you open a network connection to a remote host, either directly, using the java.net.Socket and ServerSocket classes, or indirectly, using higher-level operations like connecting to a remote object, you should be concerned about whose agent you are really communicating with, and on which host machine the agent actually resides. Ensuring that transmitted data is only received and understood by the intended recipient If you assume that your network transmissions can be tapped into by a hostile party, then you may need to take measures to ensure that only the destination agent is able to interpret and reuse the information you're sending. Verification of "visiting" agents for correctness and security holes Internet-based languages such as Java have brought with them the common practice of allowing agents to "visit" your local environment, either as distributed objects or as applets embedded in an HTML page. So you need a means for screening incoming agents for questionable behavior. Fortification of the local environment against damage If your other security measures fail and a malicious agent manages to gain access to your local Java runtime environment, you want to minimize or prevent any damage the agent can cause. Luckily for us, the Java language developers have decided that the last two issues mentioned in the preceding list will be handled inherently by the Java language and runtime. Verification of incoming Java objects is handled by the runtime bytecode verifier. Any classes loaded over the network as applets or distributed objects are checked for correct bytecode syntax and for basic malicious operations. Some of these questionable operations are attempts to manipulate memory addresses directly, or to replace core system classes with network-loaded versions. On top of this, the Java runtime puts restrictions on any loaded code, depending on its source. Applets have minimal access to the local system, for example, and any code has restricted access to classes outside of its own package scope. If we assume that the Java language developers have done their job in dealing with the last two issues, that leaves the first two for you to worry about as an application developer. Verifying the identity of a remote agent or the source of incoming data requires some kind of certification and authentication process. Keeping communications private on a semiprivate or public communications link involves the use of data encryption. Again, the Java language developers are looking out for you. The Java Security API, introduced in the 1.1 version of the Java Developers' Kit (JDK™), provides a framework for integrating these security measures into your applications. 4.4. Networked Threads 5.2. The java.security Package Copyright © 2001 O'Reilly & Associates. All rights reserved. Java Distributed Computing Chapter 6. Message-Passing Systems Contents: Messages Defined Why Do We Need Messages? Message Processing Fixed Protocols Adaptable Protocols Message Passing with Java Events Using Remote Objects In this chapter we examine applications that use message-passing schemes to distribute information between agents in a distributed system. The first thing we'll do is define what we mean by "message passing," then we'll look at some ways that messages can be handled by a Java agent. We'll build two versions of a message-passing system. The first is based on a homegrown message-handling system, with Message objects being transmitted over I/O streams between MessageHand-lers. Most of our discussion about message passing will be based on these classes. Near the end of the chapter, we'll look at a message-passing system based on the delegation event model built into the JDK and used by the AWT package. In this case, we'll be using EventObjects as our messages, and leveraging the model of event sources and listeners from the JDK to build a message-handling framework. 6.1. Messages Defined Before we start discussing message-passing systems, we need to define what we mean by a message. Essentially, a message is a structured piece of information sent from one agent to another over a communication channel. Some messages are requests made to one agent by another, other messages deliver data or notification to another agent. In most applications that we'll discuss, a message consists of a message identifier and, if needed, a set of message arguments. The message identifier tells the receiver the purpose or type of the message. The arguments to the message contain additional information that is interpreted based on the type of message. They may contain the object of an action (e.g., the message "xy" means, "Do x to y and return the result"), or they may contain information used to carry out a request (e.g., "x a b c " means, "Do x, and use a, b, and c to do it"). Message identifiers are usually simple, unique tokens that differentiate one type of message from another. They may even be simple integer values, where the agents on either end use a look-up table of some sort to match the value with its meaning. Message arguments, on the other hand, can be of many types. Some simple message protocols get away with using only basic data types, like integers, strings, and floating- point values, for message arguments. These arguments can be read and written directly using the DataInputStream and DataOutputStream classes. Other protocols need to use more complicated data types and objects as message arguments. These complex data types can be sent as an ordered sequence of simple data types over a DataOutputStream. They can also be transmitted as objects using the Java RMI object serialization support, as discussed in Chapter 3, "Distributing Objects". In some very well defined and controlled application environments, a message protocol may not need message identifiers at all. The interactions between agents may be so strictly defined that there's no need to specify the type of message being sent because the receiver is already expecting it. Suppose, for example, that we have two chess-playing agents talking to each other. Assuming that they both always make valid moves and that they both continue to play until checkmate results, the only kind of message they need to exchange is one that contains the next move that they want to make, with an optional argument that indicates if the move results in a "check" or a "checkmate." In this case, there's no need for message identifiers--the messages can just contain the chess players' moves. In a sense, every network standard and protocol we've discussed so far can be boiled down to some form of message passing. HTTP, SSL, even low-level network protocols like TCP/IP are protocols built around some form of message passing. When we speak of message passing in this chapter, however, we are talking about message passing that is done explicitly by the application programmer. While these other protocols are built around some kind of message-passing protocol, that level of the protocol is hidden from the developer by an API of some kind. For example, SSL is utilized by an application programmer through a class library, where method calls on SSL-related objects are automatically broken down into SSL- compliant messages. Likewise, incoming SSL "messages" are processed and mapped into new data objects and method calls on SSL objects. This is what makes these complicated but powerful protocols so useful: the application programmer doesn't need to know the details of the protocol at the lower level. When we speak of message passing in this chapter, we're referring to situations where the message protocol--the generation and the processing of messages--is defined and performed directly at the application level. 5.7. Choosing a Cryptographic Algorithm 6.2. Why Do We Need Messages? Copyright © 2001 O'Reilly & Associates. All rights reserved. Java Distributed Computing Chapter 7. Databases Contents: An Overview of JDBC Remote Database Applications Multi-Database Applications This chapter is a brief introduction to the topic of integrating databases into networked Java applications. As with many of the topics in this book, the development of database applications is a subject that can fill a book of its own. And it has, many times over. For the purposes of this book, rather than trying to cover the gamut of database design and development in depth, we will restrict this chapter to a discussion of the following topics: ● An overview of the primary database access API available in the Java environment, JDBC ● A discussion of the basic issues that arise in developing networked database applications ● The special issues that come into play when multiple distributed databases are accessed from a single application We assume that the reader has a basic understanding of general relational database topics, such as SQL and the layout of data into tables and records. For more in-depth coverage of the JDBC package than we will be able to provide here, refer to George Reese's book, Database Programming with JDBC and Java (O'Reilly & Associates). 7.1. An Overview of JDBC JDBC is the database connectivity package included in the core Java API.[1] JDBC gives you a database- independent interface for opening a connection to a relational database, issuing SQL calls to the database, and receiving a set of data as the result. In more technical terms, JDBC acts as a Java implementation of the standard SQL call-level interface (CLI) defined by X/Open and supported by most major relational database vendors. In order to perform transactions with a specific type of database, you need to have a JDBC driver that acts as a bridge between the JDBC method calls and the native database interface. [1]JDBC became a formal part of the JDK in version 1.1. 7.1.1. Data Retrieval Example Perhaps the easiest way to get started with JDBC is to see a simple example of the API in action. Example 7-1 shows a Java code segment that opens a database connection, executes a query, and iterates through the results. Example 7-1. A Simple JDBC Database Query // Construct the database address String dbaseURL = "jdbc:mysubprotocol://dbasehost/dbasename"; // Make the database connection Connection dbConnection = DriverManager.getConnection(dbaseURL, "dbaseuser", "dbasepasswd"); // Create a statement and execute the SQL query Statement query = dbConnection.getStatement(); ResultSet results = query.executeQuery("SELECT first_name, last_name from user_table"); // Iterate through the results and print them to standard output while (results.next()) { String fname = results.getString("first_name"); String lname = results.getString("last_name"); System.out.println("Found user \"" + fname + " " + lname + "\""); } In the example, we refer to the database using a URL: String dbaseURL = "jdbc:mysubprotocol://dbasehost/dbasename"; This URL is passed to the JDBC DriverManager's getConnection() method, along with an account name and password, to open a connection to the database: Connection dbConnection = DriverManager.getConnection(dbaseURL, "dbaseuser", "dbasepasswd"); Once the connection is created, we construct a Statement object, which is used to issue an SQL query. In this case, we're retrieving all of the first and last names (user_fname and user_lname) from a table of user information (user_table). The results of the query are returned by JDBC as a ResultSet object: Statement query = dbConnection.createStatement(); ResultSet results = query.executeQuery("SELECT first_name, last_name from user_table"); Finally, we can iterate over the results of the query and present them to the user: while (results.next()) { String fname = results.getString("first_name"); String lname = results.getString("last_name"); System.out.println("Found user \"" + fname + " " + lname + "\""); } In the following sections, we'll examine JDBC in more detail to see how this and other database interactions are supported. 7.1.2. The API at a Glance The JDBC API offers you interfaces that mirror the basic concepts surrounding relational databases. These interfaces, all part of the java.sql package, include interfaces for a DriverManager, a Connection, a Statement, and a ResultSet. 7.1.2.1. DriverManager The DriverManager class provides the means to load database drivers into a Java application or applet; it is the primary way in JDBC to establish a connection to a database. A Java application first creates a DriverManager instance, then connects to a database by calling the DriverManager's static getConnection() method, passing a URL-like reference to the database as a method argument. The DriverManager searches the set of available drivers for one that can support a connection to the referenced database. If it finds one, it passes the database address to the driver and asks it to create a connection. The connection to the database is returned in the form of a Connection object (described later). All JDBC drivers provide an implementation of the java.sql.Driver interface. When a DriverManager is created, it attempts to load a set of drivers specified by the sql.Driver's Java property, which can be set to a list of colon-delimited Driver class names. Additional drivers can also be loaded explicitly in the Java application as needed. When a Driver class is loaded into the Java runtime, it's responsible for creating an instance of itself and registering this instance with the resident DriverManager. So any additional drivers needed by an application can be loaded explicitly by using the Class.forName() method: Driver myDriver = (Driver)Class.forName("specialdb.Driver"); Since the Driver class automatically registers itself with the DriverManager, there really isn't any reason to keep the reference to the Driver. You'll often see drivers loaded by just calling the forName() method and later referencing the driver by name when a database connection is made. 7.1.2.2. Connection Once the necessary drivers have been loaded by the DriverManager, a connection to a database can be made through the getConnection() method of the DriverManager class. The desired database is specified with a String argument that acts as a URL-like address to the database. There is no standard format for this database address string; the DriverManager simply passes it to each loaded JDBC driver in turn and asks if it understands and supports the type of database being addressed. Typically, the database address will include explicit information about the type of driver to be used to make the connection. For example, JDBC drivers using ODBC protocol to establish database connections usually use addresses of the form: jdbc:odbc:financedata, where financedata is a local data source. Access to a remote database from a local client may involve an address of a slightly different form: jdbc:drvr://dataserver.foobar.com:500/financedata. The JDBC API specification recommends that database URLs take the form: jdbc::, where specifies a database connection service and provides all of the information that the underlying service will need to find the database and connect to it. So in the remote database URL shown above, drvr is the sub-protocol, specifying a specific driver to use to connect to our database. The dataserver.foobar.com:500/financedata portion of the URL acts as the sub- name, and gives the information the driver needs to find our database. Other drivers may require you to specify sub-protocols and sub-names differently. You should consult the documentation for the JDBC drivers you're using to find out what form your database URLs should take. The getConnection() method on DriverManager either returns a Connection object that represents the connection to the named database, or throws an exception if the connection couldn't be established. 7.1.2.3. Statement The Connection interface allows the user to create query statements to the database. Query statements are represented as Statement objects or subclasses. The Connection interface provides three methods for creating database query statements: createStatement(), prepareStatement(), and prepareCall(). The createStatement() method is used for simple SQL statements that don't involve any parameters. This returns a Statement object that can be used to issue SQL queries to the database, normally using its executeQuery() method. This method accepts an SQL statement as a string argument, and the results of the statement are returned in the form of a ResultSet object (described later). Other methods available in the Statement interface for issuing SQL statements to the database are execute(), which is used for SQL queries that can return multiple result sets, and executeUpdate(), which can be used to issue INSERT, UPDATE, or DELETE statements. In addition to the basic Statement interface, a Connection object can be used to create precompiled PreparedStatement s, and CallableStatements that represent stored procedures in the database. An SQL statement involving input parameters, or a statement that you want to execute multiple times, can be created using the prepareStatement() method on a Connection object, which returns a PreparedStatement object. The SQL statement passed into the prepareStatement() method is precompiled so that multiple executions of the statement will be more efficient. This subclass of Statement supports setting the values of precompiled input parameters through a series of setXXX() methods. The PreparedStatement object has an executeQuery() method that requires no arguments, and instead executes the precompiled SQL statement on the database. Note that not all database vendors or JBC drivers support precompiled statements, so check your DBMS documentation and JDBC driver specifications to see if you can use PreparedStatements. A stored SQL procedure can be accessed through an SQL statement created through the prepareCall() method on a Connection object. This method returns a CallableStatement object, which lets you set input parameters and get output parameters from the statement. By default, the JDBC package is configured to commit each Statement issued through a Connection. If you need to do rollbacks of transactions, or you want to commit multiple statements as a single transaction, or both, you can disable the autocommit feature by calling Connection.setAutoCommit(false) . Then a sequence of Statements can be created from a Connection object, executed against the database, and the entire transaction can be committed as one transaction by calling the Connection's commit() method. If you want to abort the transaction, you can call the Connection's rollback() method. 7.1.2.4. ResultSet Rows of data returned from the execution of a statement against a database are represented as ResultSet objects in JDBC. For example, the executeQuery() method of the Statement interface returns a ResultSet object. A ResultSet object provides ways to iterate through the rows of data returned as the result of an SQL query, through its next() method; data fields within each row can be retrieved by name or by column index number using its getXXX() methods. The user needs to know the type of data to expect in each column of returned data, since each data item is retrieved through type-specific getXXX() methods. Depending on how your JDBC driver is implemented, iterating through the rows of data in a ResultSet may cause individual data fetches from the database, or it may simply pull each row of data from a local cache. If the performance of your data transactions is an issue in your application, you should determine how returned data is handled by your vendor's drivers. 6.7. Using Remote Objects 7.2. Remote Database Applications Copyright © 2001 O'Reilly & Associates. All rights reserved. Java Distributed Computing Chapter 8. Bandwidth-Limited Systems Contents: Flavors of Limited Bandwidth Coping with Limited Bandwidth Scope of This Chapter Monitoring Bandwidth Bandwidth Management Up until now, our discussions about network applications have asssumed that the reliability and capacity of the underlying network is sufficient for the task at hand. With the continued growth of wireless communications devices, as well as the ever-increasing use of multimedia content in networked applications, it's important to consider situations where this assumption is not valid--in other words, in situations where the distributed system is bandwidth-limited. After a brief discussion of the overall topic of limited bandwidth, we'll show a framework for doing some crude bandwidth monitoring, built within the I/O stream classes in java.io. Then we'll show a general content consumer/ producer model that could be used in conjunction with the bandwidth monitoring utilities to implement adaptive buffering for data being streamed over the network. 8.1. Flavors of Limited Bandwidth An application can be considered bandwidth-limited in two ways. First, the application can have relatively high bandwidth requirements (compared to average applications) that the communications scheme can't fully support. An application falls into this category when the required rate of data flow is very close to the capacity of the network connection. Streaming high-quality video for real-time playback is one such application--a constant, high-throughput, reliable network connection is necessary to support distributed video. Bandwidth is also limited when the network connection has relatively low or unreliable capacity (compared to average network connections), and is insufficient for many data transactions. Current telephone modem throughput rates, for example, are insufficient to support downloading high-quality multimedia in real time. Many wireless communications schemes can be unreliable to the point that their effective throughput is much lower than their peak throughput, and a bandwidth-limited situation occurs. In either case, the data requirements of the application exceed the available bandwidth, so measures must be taken to handle this situation without degrading our application's behavior unacceptably. 7.3. Multi-Database Applications 8.2. Coping with Limited Bandwidth Copyright © 2001 O'Reilly & Associates. All rights reserved. Java Distributed Computing Chapter 9. Collaborative Systems Contents: What Is a Collaborative System? Issues with Collaboration A Basic Collaborative Infrastructure In this chapter we'll examine the implementation of collaborative systems, a topic that will fuse most of the subjects we discussed earlier in the book. First we'll define what we mean by collaborative systems, and discuss what complications can arise while implementing these systems. Then we'll look at how these issues can be addressed in the Java environment by building a set of base classes that will act as a basic collaboration framework. In the next chapter, we'll present some complete collaborative systems. 9.1. What Is a Collaborative System? A collaborative system is one where multiple users or agents engage in a shared activity, usually from remote locations. In the larger family of distributed applications, collaborative systems are distinguished by the fact that the agents in the system are working together towards a common goal and have a critical need to interact closely with each other: sharing information, exchanging requests with each other, and checking in with each other on their status. In this chapter, we'll consider a collaborative system as one that is also distinguished by a certain level of concurrency; i.e., the agents in the system are interacting with the system and with each other at roughly the same time. So a chat session is collaborative, because all of the agents involved need to coordinate with each other to be sure that the chatters don't miss anyone else's comments. An email system isn't collaborative, because each email client simply wants to be sure that its messages get to the right server, and eventually to the intended recipient. A particular email client doesn't care about the state of any other client, and doesn't need to coordinate with any of them in order to accomplish its goal. Figure 9-1 depicts some of the elements that can go into a collaborative system: ● Autonomous or user-driven agents ● Operational and data servers ● Dynamic and persistent data repositories ● Transactions between agents, servers, and data Agents, servers, data repositories, and transactions are all elements that make up distributed systems in general, but the nature of the transactions between agents and the shared goals of the agents make a system collaborative. Figure 9-1. Collaborative systems structure Here are some examples of what we refer to as collaborative systems: ● Shared whiteboards ● Interactive chat ● Distributed or parallel compute engines ● Coordinated data search agents (e.g., web "robots") The first two involve collaborative agents under the direct control of human beings, while the last two involve agents that are programmed to act autonomously. So a collaborative system can involve concurrent transactions between people, between autonomous computing agents,[1] or some mixture of the two. [1]Here our use of the word "agent" is much closer to the academic term, e.g., an autonomous computing entity trying to achieve a goal of some kind. 8.5. Bandwidth Management 9.2. Issues with Collaboration Copyright © 2001 O'Reilly & Associates. All rights reserved. Java Distributed Computing Chapter 10. Building Collaborative Applications Contents: A Simple Chat System A Shared Whiteboard In the previous chapter we built up a set of base classes for building collaborative applications, in both RMI and message-passing forms. In this chapter, we'll put those classes to work, using them to build some collaborative applications: a simple chat system and a shared whiteboard. We'll only be building applications based on the RMI version of our collaborative framework, but the mapping to message-passing versions is straightforward. 10.1. A Simple Chat System It's a pretty simple matter to build a basic chat system on top of our base classes. All we need to do is write a subclass of our collaborator that acts as a chat client, receiving messages from remote chat clients and displaying them in a text window next to their name. We can pull each client's name from its Identity. Example 10-1 shows an RMIChatClient based on our RMI collaborative system. The RMIChatClient extends the RMICollaboratorImpl class, and also implements the java.awt.event.ActionListener interface, so that it can act as a listener for its own AWT elements. This AWT interface includes a TextArea for showing the chat session, a TextField for the user to type in chat messages, and a Button to submit the messages to the chat server, which in our case is simply one of our RMIMediatorImpl objects routing messages to other RMIChatClients. The constructor for the RMIChatClient simply connects to the specified mediator, then initializes its graphical elements by calling its initGraphics() method. The initGraphics() method creates a Frame, inserts the TextArea, TextField, and Button in the correct locations, then registers itself as an ActionListener for the button. The RMIChatClient's actionPerformed() method, which is called whenever the "Send" button is pressed, simply gets the text in the TextField when the button is pressed, and broadcasts it to all the other chat clients by calling its broadcast() method with a message tag of "chat." It then clears the TextField to let the user type in the next message. The RMIChatClient also has a notify() implementation that accepts chat messages from the mediator, and writes them to the TextArea along with the name of the sender (from its Identity). Figure 10-1 shows the chat screen that a user would see. Figure 10-1. A chat client implemented using the RMICollaborator Example 10-1. An RMI-Based Chat Client package dcj.util.Collaborative; import java.awt.Frame; import java.awt.TextArea; import java.awt.TextField; import java.awt.Button; import java.awt.Label; import java.awt.event.*; import java.rmi.RemoteException; import java.util.Properties; import java.io.IOException; public class RMIChatClient extends RMICollaboratorImpl implements java.awt.event.ActionListener { TextArea chatArea; TextField chatInput; public RMIChatClient(String name, String host, String mname) throws RemoteException { super(name); Properties p = new Properties(); p.put("host", host); p.put("mediatorName", mname); connect(p); initGraphics(); } public boolean notify(String tag, String msg, Identity src) throws IOException, RemoteException { // Print the message in the chat area. chatArea.append("\n" + src.getName() + ": " + msg); return true; } protected void initGraphics() throws RemoteException { Frame f = new Frame(); f.setLayout(null); f.addNotify(); f.setSize(f.getInsets().left + 405, f.getInsets().top + 324); chatArea = new java.awt.TextArea(); chatArea.setBounds(f.getInsets().left, f.getInsets().top,405, 300); f.add(chatArea); chatInput = new java.awt.TextField(); chatInput.setBounds(f.getInsets().left + 84, f.getInsets().top + 300,264,24); f.add(chatInput); Button button = new java.awt.Button("Send"); button.setBounds(f.getInsets().left + 348, f.getInsets().top + 300,60,24); f.add(button); button.addActionListener(this); Label label = new java.awt.Label("Chat here:"); label.setBounds(f.getInsets().left,f.getInsets().top + 300,84,24); label.setAlignment(label.RIGHT); f.add(label); f.setTitle("RMI Chat Client"); f.show(); } public void actionPerformed(ActionEvent e) { // See if there's something to say... String msg = chatInput.getText(); if (msg.length() > 0) { try { // Broadcast our message to the rest of the chat clients boolean success = broadcast("chat", msg); if (success) { System.out.println("Sent message OK."); } else { System.out.println("Failed to send message."); } // Clear the chat input field chatInput.setText(""); } catch (Exception exc) { } } } } Our RMIChatClient's notify() method doesn't include any synchronized code blocks. Since each chat client connects to a single mediator, and since the mediator synchronizes all of its message-routing functions at any given time, there's only one thread that could be making remote calls to the chat client's notify() method. This chat system was simple to implement because many of the really hard issues with collaborative systems are not a problem here. The data passed between the agents is small and simple ( just text strings), so communication performance shouldn't be a problem. Every message is broadcast to every other chat client, so flexible communications aren't an issue either. And while there is a kind of shared "state" between the chatting agents (the list of chat messages that each displays), it isn't a problem keeping this shared state consistent. Each chat client sends its chat messages using the broadcast() method, but doesn't display the message locally until it's received back from the chat mediator. This way all messages displayed in each client's chat window are synchronized, because they all pass through the mediator and are sent in the same order to each chat client. 9.3. A Basic Collaborative Infrastructure 10.2. A Shared Whiteboard Copyright © 2001 O'Reilly & Associates. All rights reserved. Java Distributed Computing Appendix A. Using the Examples in Applets Contents: Whiteboard Applet Class Downloads You may have noticed that most of the examples in this book are provided in a form suitable for use as Java applications, not as applets. Rather than interspersing applet examples with applications throughout the book, we decided to concentrate on distributed system development issues without the additional complications of applet programming. In this appendix, we'll see how some of the examples could be modified for use in applets. A.1. Whiteboard Applet One of the examples that seems like an obvious candidate for use as an applet is our whiteboard example from Chapter 10, "Building Collaborative Applications". Currently, support for RMI within web browsers is scarce, so let's concentrate on a message-passing version of the whiteboard, instead of the RMI-based version shown in Example A-3. The message-passing version is very similar, but is based on the MessageCollaborator and MessageMediator classes from that chapter. This version, which we called the MsgWhiteboardUser, is shown in Example A-1. Since the differences between this and the RMI-based WhiteboardUser are minor, we won't go into details about the code here. Example A-1. Message-Passing Whiteboard package dcj.examples.Collaborative; import dcj.util.Collaborative.*; import java.awt.event.*; import java.awt.*; import java.util.Hashtable; import java.util.Properties; import java.io.IOException; import java.util.Vector; class Msg { public Object data; public String tag; public Msg(Object o, String t) { data = o; tag = t; } } class CommHelper extends Thread { Collaborator collaborator; static Vector msgs = new Vector(); public CommHelper(Collaborator c) { collaborator = c; } public static void addMsg(Object o, String t) { synchronized (msgs) { msgs.addElement(new Msg(o, t)); } } public void run() { while (true) { try { Msg m = null; synchronized (msgs) { m = (Msg)msgs.elementAt(0); msgs.removeElementAt(0); } collaborator.broadcast(m.tag, m.data); } catch (Exception e) {} } } } public class MsgWhiteboardUser extends MessageCollaborator implements java.awt.event.MouseListener, java.awt.event.MouseMotionListener { protected Hashtable lastPts = new Hashtable(); protected Component whiteboard; protected Image buffer; public MsgWhiteboardUser(String name, Color color, String host, int port) { super(host, port, name); getIdentity().setProperty("color", color); System.out.println("color = " + color.getRed() + " " + color.getGreen() + " " + color.getBlue()); buildUI(); CommHelper helper = new CommHelper(this); helper.start(); } protected void buildUI() { Frame f = new Frame(); GridBagLayout gridbag = new GridBagLayout(); GridBagConstraints c = new GridBagConstraints(); f.setLayout(gridbag); f.addNotify(); c.fill = GridBagConstraints.BOTH; c.gridwidth = GridBagConstraints.REMAINDER; Canvas canvas1 = new java.awt.Canvas(); canvas1.setSize(240,180); canvas1.setBackground(Color.white); gridbag.setConstraints(canvas1, c); f.add(canvas1); String name = null; try { name = getIdentity().getName(); } catch (Exception e) { name = "unknown"; } Label label1 = new java.awt.Label("Your name: " + name); label1.setSize(100,30); gridbag.setConstraints(label1, c); f.add(label1); f.setSize(240,210); f.show(); whiteboard = canvas1; whiteboard.addMouseListener(this); whiteboard.addMouseMotionListener(this); buffer = whiteboard.createImage(f.getSize().width, f.getSize().height); } protected void nextLine(String agent, Point pt, Color c) { Graphics g = buffer.getGraphics(); g.setColor(c); Point lastPt = (Point)lastPts.get(agent); g.drawLine(lastPt.x, lastPt.y, pt.x, pt.y); whiteboard.getGraphics().drawImage(buffer, 0, 0, whiteboard); } public void mousePressed(MouseEvent ev) { Point evPt = ev.getPoint(); try { lastPts.put(getIdentity().getName(), evPt); CommHelper.addMsg(evPt, "start"); } catch (Exception e) {} } public void mouseReleased(MouseEvent ev) { Point evPt = ev.getPoint(); try { nextLine(getIdentity().getName(), evPt, (Color)getIdentity().getProperty("color")); lastPts.remove(getIdentity().getName()); CommHelper.addMsg(evPt, "end"); } catch (Exception e) {} } public void mouseDragged(MouseEvent ev) { Point evPt = ev.getPoint(); try { nextLine(getIdentity().getName(), evPt, (Color)getIdentity().getProperty("color")); lastPts.put(getIdentity().getName(), evPt); CommHelper.addMsg(evPt, "drag"); } catch (Exception e) { } } public void mouseExited(MouseEvent ev) {} public void mouseMoved(MouseEvent ev) {} public void mouseClicked(MouseEvent ev) {} public void mouseEntered(MouseEvent ev) {} public boolean notify(String tag, Object data, Identity src) throws IOException { if (src.getName().compareTo(getIdentity().getName()) == 0) { return true; } Color origColor = null; Color agentColor = null; Graphics gr = buffer.getGraphics(); try { agentColor = (Color)src.getProperty("color"); if (agentColor != null) { gr.setColor(agentColor); } else { System.out.println("No agent color available."); } } catch (Exception exc) { System.out.println("Exception while switching colors."); exc.printStackTrace(); } if (tag.compareTo("start") == 0) { lastPts.put(src.getName(), data); } else if (tag.compareTo("drag") == 0) { Point lastPt = (Point)lastPts.get(src.getName()); Point currPt = (Point)data; gr.drawLine(lastPt.x, lastPt.y, currPt.x, currPt.y); lastPts.put(src.getName(), data); } else if (tag.compareTo("end") == 0) { Point lastPt = (Point)lastPts.get(src.getName()); Point currPt = (Point)data; gr.drawLine(lastPt.x, lastPt.y, currPt.x, currPt.y); lastPts.remove(src.getName()); } whiteboard.getGraphics().drawImage(buffer, 0, 0, whiteboard); return true; } } A quick and dirty way to use our message-passing whiteboard in an applet context is to just create a MsgWhiteboardUser from inside the init() method of an Applet: public class WhiteboardApplet extends Applet { private MsgWhiteboardUser wbUser; public WhiteboardApplet() {} public void init() { wbUser = new MsgWhiteboardUser("Fred", new Color(255, 0, 0), "medhost", 5009); } } When the MsgWhiteboardUser initializes itself, one of the things it does is try to connect to a MessageMediator at the host and port number given to the constructor. This will work just fine, assuming that the applet security policy for your browser allows you to make network connections to the host on which the mediator is running. Typically a browser will only allow an applet to open connections to the host it came from, so you may be forced to have the mediator running on the same host serving the HTML page with your applet. Since the whiteboard constructs its own top-level Frame inside the buildUI() method, using the WhiteboardApplet in a web page will cause a separate window to pop up on the user's machine. It would be nice to have the whiteboard GUI appear embedded in the web page itself. To do this, we'll need a way to pass the Applet's top-level Container into the constructor for the MsgWhiteboardUser, so that it adds all of its user interface elements to the Container instead of a separate window. We just need to add an additional argument to the MsgWhiteboardUser constructor: public MsgWhiteboardUser(String name, Color color, String host, int port, Container c) { . . . Then we pass the external Container into the buildUI() method, which then uses it instead of a new Frame as the container for all of its AWT elements: protected void buildUI(Container cont) { if (cont == null) cont = new Frame(); GridBagLayout gridbag = new GridBagLayout(); GridBagConstraints c = new GridBagConstraints(); cont.setLayout(gridbag); cont.addNotify(); c.fill = GridBagConstraints.BOTH; c.gridwidth = GridBagConstraints.REMAINDER; Canvas canvas1 = new java.awt.Canvas(); canvas1.setSize(240,180); canvas1.setBackground(Color.white); gridbag.setConstraints(canvas1, c); cont.add(canvas1); String name = null; try { name = getIdentity().getName(); } catch (Exception e) { name = "unknown"; } Label label1 = new java.awt.Label("Your name: " + name); label1.setSize(100,30); gridbag.setConstraints(label1, c); cont.add(label1); cont.setSize(240,210); cont.setVisible(true); whiteboard = canvas1; whiteboard.addMouseListener(this); whiteboard.addMouseMotionListener(this); buffer = whiteboard.createImage(cont.getSize().width, cont.getSize().height); } Now our whiteboard will appear within the web page itself. Many of the other examples in the book are even easier to apply in an applet context. They can be used within an applet you have developed, assuming that the browsers support the libraries used (e.g., RMI, CORBA, etc.). Of course, you must take applet security restrictions into account when you're deciding how to distribute your agents and how they'll talk to each other. (For example, if you put a server agent on machine X, will any browser running one of your client agents allow the agent to connect to the server machine? ) 10.2. A Shared Whiteboard A.2. Class Downloads Copyright © 2001 O'Reilly & Associates. All rights reserved. Java Distributed Computing Appendix B. CORBA Services Contents: Naming Service Event Service Security Service Other Key CORBA Services The CORBA standard is really a collection of standards and definitions. In addition to the core specifications for the Object Request Broker (ORB) and inter-ORB communication protocols such as IIOP, CORBA also includes specifications for services that distributed objects may require, such as naming services, security measures, etc. Taken as a whole, these specifications, backed up by solid implementations, provide a very powerful environment for the distributed application developer. This appendix provides a brief overview of some of the key services currently included in the CORBA Services specification. Some of these services are similar in nature to features provided inherently by Java. In these cases, we discuss the contrasts between the Java-native service and the CORBA service. B.1. Naming Service The Naming Service is arguably the most commonly used service in the CORBA family. We used the Naming Service in our CORBA example in Chapter 3, "Distributing Objects" to look up our CORBA-based Solver object. The Naming Service provides a means for objects to be referenced by name within a given naming context. A naming context is a scoping mechanism for names, similar in philosophy to class packages in Java. Within a particular context, names must be unique, and contexts can be nested to form compound contexts and names. Figure B-1 shows two naming contexts in the form of Venne diagrams: one, whose topmost context is named "BankServices," defines names for objects in a banking application; the other, named "LANResources," defines names for network resources such as printers, compute servers, data servers, etc. The "BankServices" naming context contains a single object named "AuthorizationAgent," and a subcontext named "CorporateAccount." The "LANServices" context contains a "DataServer" context and a "Printer" context, and each of these contains two named objects. Figure B-1. Sample naming contexts Agents in a distributed system can add named objects to the Naming Service by binding objects to a particular name within a context. Other agents can then look up these objects by resolving their names into object references. The name of an object is made up of a sequence of name components that specify the subcontexts that the object falls within. So, for example, the "Laser1" object in the "LANResources" context would be fully specified with a name made up of the ordered components "LANResources," "Printer," and "Laser1." All of the interfaces making up the Naming Service are contained in the CosNaming module. The interface to the central Naming Service functions is the NamingContext interface, which provides methods for binding, rebinding, and unbinding objects to names, as well resolving object references from names. Using a Java implementation of the CORBA Naming Service, the "LANResources" context and all of its object "contents" might be built up as follows: // Get handle on base naming context from the ORB NamingContext base = ... // Get references to the objects to be registered in Naming Service omg.CORBA.Object engDataBaseRef = ... omg.CORBA.Object finDataBaseRef = ... omg.CORBA.Object laserPrinterRef = ... omg.CORBA.Object plotterRef = ... // Build up subcontexts for LAN resources NameComponent lan = new NameComponent("LANResources", ""); NameComponent data = new NameComponent("DataServer", ""); NameComponent print = new NameComponent("Printer", ""); // Create context for LAN resources NameComponent path[] = {lan}; NamingContext lanContext = base.bind_new_context(path); // Bind all of the data servers to their names within the new context path = {lan, data, new NameComponent("Engineering", "")}; lanContext.bind(path, engDataBaseRef); path = {lan, data, new NameComponent("Financial", "")}; lanContext.bind(path, finDataBaseRef); // Bind the printers to their names path = {lan, print, new NameComponent("Laser1", "")}; lanContext.bind(path, laserPrinterRef); path = {lan, print, new NameComponent("Plotter", "")}; lanContext.bind(path, plotterRef); In this example, a new context is established first for the LAN resource objects. The bind_new_context() method of the NamingContext interface takes an array of NameComponents, which specify the fully qualified name for the new context. In this case, we simply need a single NameComponent to give the new context the name "LANResources." Next, the object references are bound to their names within this new context. In each case, we create an array of NameComponents specifying the compound name for the object, then bind the object to its name by calling the bind() method on the NamingContext. Agents that want to use these named objects can look them up by getting a reference to the NamingContext and resolving the object references from their full names: NamingContext base = ... NameComponent printerName = {new NameComponent("LANResources", ""), new NameComponent("Printer", ""), new NameComponent("Laser1", "")}; omg.CORBA.Object printerRef = base.resolve(printerName); B.1.1. Comparison to the RMI Registry There are many similarities between the RMI registry facilities, represented by the java.rmi.Naming interface, and the CORBA Naming Services, represented by the NamingContext interface in the CosNaming module. Each provides methods for binding and rebinding objects to names, removing these bindings, and looking up objects by name. They also both provide methods for listing the contents of a registry or NamingContext, respectively. Where CORBA and RMI differ the most with regards to naming services is hierarchical naming contexts. RMI does not support them at all, while CORBA supports them extensively with the ability to both create hierarchical naming contexts and represent compound object names. In the RMI examples in this book, we got around this limitation of the RMI registry by registering a single factory object with the registry, which was then used to create references to other remote objects. So the client of the remote object would use a single, simple name to look up the remote factory object, and the factory object would be responsible for supporting the "lookup" of other objects within this "context." In situations where hierarchical naming is critical, such as distributed directory services, this becomes a major deficiency in the RMI package, and a good reason to turn to the more comprehensive services provided by CORBA. A.2. Class Downloads B.2. Event Service Copyright © 2001 O'Reilly & Associates. All rights reserved. Java Distributed Computing Appendix C. JavaSpaces Contents: Overview of JavaSpaces Entry and EntryRep Transactions The JavaSpace Interface JavaSpaces is a new distributed object system being proposed by Sun as a package at a higher level than the existing RMI and object serialization facilities built into Java. JavaSpaces provides a distributed, persistent object system that is roughly modeled after earlier shared memory systems, such as LINDA. While it has some analogies with parallel shared memory systems such as the Posix shm_xxx library and shared memory facilities in parallel languages like Python, it also has some important differences. This appendix provides an overview of the general JavaSpace architecture as currently described in the draft JavaSpace specification. It doesn't go into detail about how to use the JavaSpace API, since the API isn't fully available yet. This appendix only includes the core elements of the specification, without discussing any proposed features that may or may not be in the final API. C.1. Overview of JavaSpaces The distributed application paradigm supported by JavaSpaces is one in which remote agents interact with each other indirectly through shared data object spaces. Objects are stored in a JavaSpace in the form of entries. Clients write entries into the space, read entries from the space, or take entries from the space, as shown in Figure C-1. Figure C-1. JavaSpaces general architecture Access to the entries in JavaSpaces is through a small set of basic operations: read Read an entry from the space that matches a template. write Add an entry to the space. take Read and remove an entry from the space. notify Send a notification through a given event handler if entries that match a template are added to the space. A notification request has a time-out period associated with it: if a matching entry isn't added within the time-out period, the notify request fails and is dropped from the JavaSpace. Multiple basic operations can be assembled into transactions that group basic operations into a single, atomic aggregate operation. There can be many clients and many JavaSpaces in a given distributed application. One client, and even one transaction from one client, can access multiple JavaSpaces. So instead of one agent sending a message to another, or invoking a remote method directly on another object within an agent, agents interact by writing and reading objects in JavaSpaces. An important feature of the JavaSpaces specification is that all operations on a given JavaSpace are considered unordered. If you have multiple threads or multiple remote agents issuing operations on a JavaSpace, and for some reason you want to impose some order on the operations, then it's up to you to synchronize your threads or agents as needed. Each JavaSpace holds data in the form of entries, which can either be read, written, or taken from a JavaSpace. Each entry has one or more fields that are used to match incoming requests from clients. Each request to read, take, or be notified about an entry includes a template for the entry to match. In order for an entry in the JavaSpace to match, the entry must be of the same type as the template object. Each field in the template can either have a non-null value, which must match the fields in a matching entry in the JavaSpace, or a null value, which matches any value in that field. All operations on JavaSpaces are "transactionally secure," which means that each operation or transaction is either entirely committed or entirely noncommitted to a JavaSpace. So if a write to a JavaSpace succeeds, then you can be assured that the Entry was written and will appear in the next client read or take operation on the space. An operation on JavaSpaces can be either in the form of a simple operation, or a group of operations within a single Transaction. The authors of the JavaSpace specification make a point of distinguishing JavaSpaces from a distributed database system. A JavaSpace knows the type of its entries, and can compare field values, but it doesn't understand anything about the structure of the data in its entries. It also isn't meant to provide opaque read/write access to persistent data. An entry in a JavaSpace is a serialized copy of the object written to the space, and entries returned to clients as a result of read or take operations are separate copies of the objects in the space. B.4. Other Key CORBA Services C.2. Entry and EntryRep Copyright © 2001 O'Reilly & Associates. All rights reserved. Java Distributed Computing Appendix D. RMI Quick Reference Contents: The java.rmi Package The java.rmi.registry Package The java.rmi.server Package This appendix is a quick reference guide to RMI, the remote object package included in JDK 1.1. Since there are many examples in the book that use RMI, we felt it would be useful for you to have this reference right here at your fingertips. The RMI API is contained in the java.rmi package, which includes three major sub-packages: java.rmi.dgc, java.rmi.registry, and java.rmi.server. We include all but the java.rmi.dgc package in this reference; that package is really internal to the RMI implementation, having to do with distributed garbage collection, and the average reader won't have any reason to use the package directly. This reference is broken down into sections by packages. First we look at the classes in the base java.rmi package, then java.rmi.registry, and, finally, java.rmi.server. Within each package, the classes are listed alphabetically. D.1. The java.rmi Package The core package in RMI contains the Remote interface as well as the Naming class and the RMISecurityManager class. These interfaces are used by both RMI clients and servers to define remote interfaces, look them up over the network and use them securely. In addition, this core package contains a number of basic RMI exception types used during remote object lookups and remote method calls. java.rmi.AccessException A RemoteException caused by an attempt to perform an improper operation on the Naming or Registry interface. A registry only allows local requests to bind, rebind or unbind objects, so an attempt to call these methods on a remote registry results in an AccessException. public class AccessException extends java.rmi.RemoteException { // Public constructors public AccessException(String descr); public AccessException(String descr, Exception detail); } java.rmi.AlreadyBoundException An exception that is thrown when an attempt is made to bind an object to a name that is already bound. public class AlreadyBoundException extends java.lang.Exception { // Public constructors public AlreadyBoundException(); public AlreadyBoundException(String descr); } java.rmi.ConnectException A RemoteException that's thrown when a remote host refuses to connect during a remote method call. public class ConnectException extends RemoteException { // Public constructors public ConnectException(String descr); public ConnectException(String descr, Exception nestedExc); } java.rmi.ConnectIOException A RemoteException thrown if there is an I/O error while attempting to make a remote method call. public class ConnectIOException extends RemoteException { public ConnectIOException(String descr); public ConnectIOException(String descr, Exception ex); } java.rmi.MarshalException A RemoteException thrown if an I/O error occurs while attempting to marshal any part of a remote method call (header data or method arguments). public class MarshalException extends RemoteException { // Public constructors public MarshalException(String s); public MarshalException(String s, Exception ex); } java.rmi.Naming This is the primary application interface to the naming service within the RMI registry. References to remote objects are obtained with the lookup() method. Local object implementations can be bound to names within the local registry using the bind() and rebind() methods. Locally bound objects can be removed from the name registry using unbind(). All of the names for objects currently stored in the registry can be obtained using the list() method. Each name argument to the methods on the Naming interface takes the form of a URL (e.g., rmi://remoteHost:port/objName). If a local object is being referenced, and the object is exported to the default registry port, then the URL can simply take the form of the object's name in the local registry (e.g., objName). This is possible because the rmi: protocol is assumed if it isn't present in the URL, and the default host is the local host. While the lookup() method can reference any remote RMI registry, the bind(), rebind(), and unbind() methods can only be called on the local registry. Attempting to call these methods against a remote registry will result in an AccessException being thrown. public final class Naming { // Class Methods public static void bind(String name, Remote obj) // Register throws AlreadyBoundException, java.net.MalformedURLException, UnknownHostException, RemoteException; public static String[] list(String name) // List bound object names throws RemoteException, java.net.MalformedURLException, UnknownHostException public static Remote lookup(String name) // Gets remote object throws NotBoundException, java.net.MalformedURLException, UnknownHostException, RemoteException; public static void rebind(String name, Remote obj) throws RemoteException, java.net.MalformedURLException, UnknownHostException; public static void unbind(String name) // Remove an object throws RemoteException, NotBoundException, java.net.MalformedURLException, UnknownHostException; } java.rmi.NoSuchObjectException A RemoteException thrown when you attempt to invoke a method on a remote object that is no longer available. public class NoSuchObjectException extends java.rmi.RemoteException { // Public constructors public NoSuchObjectException(String descr); } java.rmi.NotBoundException An exception that is thrown when a lookup is attempted using a name with no object bound to it. public class NotBoundException extends java.lang.Exception { // Public constructors public NotBoundException(); public NotBoundException(String descr); } java.rmi.Remote Every remote object has to implement this interface, and any methods intended to be remotely callable have to be defined within a Remote interface. This is a placeholder interface that identifies all remote objects, but doesn't define any methods of its own. public interface Remote {} java.rmi.RemoteException An IOException that is thrown when an error occurs during any remote object operation. The RemoteException includes a Throwable data member that represents the nested exception that caused the RemoteException to be thrown. For example, if an exception occurs on the server while executing a remote method, then the client receives a RemoteException (in the form of a ServerException, one of its subclasses) with its Throwable data member initialized to the server-side exception that caused the client-side RemoteException. public class RemoteException extends java.io.IOException { // Public Constructors public RemoteException(); public RemoteException(String descr); public RemoteException(String descr, Throwable nestedExc); // Public Instance Methods public String getMessage(); // Public Instance Variables public Throwable detail; } java.rmi.RMISecurityException A SecurityException thrown by the RMISecurityManager when a security violation is detected during a remote operation. public class RMISecurityException extends java.lang.SecurityException { // Public Constructors public RMISecurityException(String name); public RMISecurityException(String name, String arg); } java.rmi.RMISecurityManager The RMISecurityManager enforces the security policy for classes that are loaded as stubs for remote objects, by overriding all of the relevant access-check methods from the SecurityManager. By default, stub objects are only allowed to perform class definition and class access operations. If the local security manager is not an RMISecurityManager (using the System.setSecurityManager() method), then stub classes will only be loadable from the local file system. You normally won't need to interact with the RMISecurityManager directly within your application code, except to set it as the system security manager before entering your RMI code. public class RMISecurityManager extends SecurityManager { // Public Constructors public RMISecurityManager(); // Public Instance Methods public synchronized void checkAccept(String host, int port); public synchronized void checkAccess(Thread t); public synchronized void checkAccess(ThreadGroup g); public void checkAwtEventQueueAccess(); public synchronized void checkConnect(String host, int port); public void checkConnect(String host, int port, Object context); public synchronized void checkCreateClassLoader(); public void checkDelete(String file); public synchronized void checkExec(String cmd); public synchronized void checkExit(int status); public synchronized void checkLink(String lib); public synchronized void checkListen(int port); public void checkMemberAccess(Class clazz, int which); public void checkMulticast(InetAddress maddr); public void checkMulticast(InetAddress maddr, byte ttl); public synchronized void checkPackageAccess(String pkg); public synchronized void checkPackageDefinition(String pkg); public void checkPrintJobAccess(); public synchronized void checkPropertiesAccess(); public synchronized void checkPropertyAccess(String key); public synchronized void checkRead(FileDescriptor fd); public synchronized voidcheckRead(String file); public void checkRead(String file, Object context); public void checkSecurityAccess(String provider); public synchronized void checkSetFactory(); public void checkSystemClipboardAccess(); public synchronized boolean checkTopLevelWindow(Object window); public synchronized void checkWrite(FileDescriptor fd); public synchronized void checkWrite(String file); public Object getSecurityContext(); } java.rmi.ServerError An error that occurs while a server is executing a remote method. The nested Throwable data member (inherited from RemoteException) contains the server-side exception that generated the error. public class ServerError extends RemoteException { // Public Constructors public ServerError(String descr, Error err); } java.rmi.ServerException An exception that occurs while a server is executing a remote method. The nested Throwable data member (inherited from RemoteException) contains the server-side exception that generated the exception. public class ServerException extends RemoteException { // Public Constructors public ServerException(String descr); public ServerException(String descr, Exception nestedExc); } java.rmi.ServerRuntimeException A RemoteException that occurs while the server is executing a remote method. public class ServerRuntimeException extends RemoteException { // Public Constructors public ServerRuntimeException(String descr, Exception nestedExc); } java.rmi.StubNotFoundException This exception can occur either when an object is being exported to participate in remote RMI calls, or during a remote method call. During export on the server, this exception is thrown if the stub class for the object can't be found or used for some reason (e.g., the stub class isn't in the CLASSPATH of the server process, or the stub class can't be instantiated). During a remote method call, the client can receive this exception if the remote object hasn't been exported completely or correctly. public class StubNotFoundException extends RemoteException { // Public Constructors public StubNotFoundException(String s); public StubNotFoundException(String s, Exception ex); } java.rmi.UnexpectedException All exceptions are unexpected, right? An UnexpectedException is thrown if an exception that isn't specified on a remote method's signature is encountered during the return from a remote method call. The unexpected exception can occur on the server or on the client. The nested Throwable object inherited from RemoteException contains the actual exception that occurred. public class UnexpectedException extends RemoteException { // Public Constructors public UnexpectedException(String descr); public UnexpectedException(String descr, Exception NestedExc); } java.rmi.UnknownHostException This RemoteException is thrown if the host specified during a Naming lookup can't be found. public class UnknownHostException extends RemoteException { // Public Constructors public UnknownHostException(String descr); public UnknownHostException(String descr, Exception nestedEx); } java.rmi.UnmarshalException This RemoteException is thrown if an error occurs while unmarshaling the return value from a remote method call. The source of the error could be an I/O error while sending the header or the value of the return from the server to the client, or the fact that the class of the return object is not found. public class UnmarshalException extends RemoteException { // Public Constructors public UnmarshalException(String s); public UnmarshalException(String s, Exception ex); } C.4. The JavaSpace Interface D.2. The java.rmi.registry Package Copyright © 2001 O'Reilly & Associates. All rights reserved. Index Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z D.3. The java.rmi.server Package Colophon Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved. Java Distributed Computing Colophon Our look is the result of reader comments, our own experimentation, and feedback from distribution channels. Distinctive covers complement our distinctive approach to technical topics, breathing personality and life into potentially dry subjects. The image of the Gabriel® Original Tinkertoy® Construction Set on the cover of Java™ Distributed Computing was photographed by Edie Freedman and manipulated using Adobe Photoshop 3.0 and Adobe Gallery Effects filters. The cover layout was produced by Hanna Dyer using Quark XPress 3.3 and the Bodoni Black font from URW Software. The inside layout was designed by Nancy Priest. Text was prepared by Mike Sierra in FrameMaker 5.0. The heading font is Bodoni BT; the text font is New Baskerville. The illustrations that appear in the book were created in Macromedia Freehand 7.0 by Robert Romano. Index Copyright © 2001 O'Reilly & Associates. All rights reserved. Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Index: A abstract object interfaces: 1.3.2. Abstract Interfaces acceptMove( ): 6.4. Fixed Protocols access control lists: 5.3.1. Access Control Lists AccessDecision class: B.3.2. Security Model AccessException: D.1. The java.rmi Package Acl interface: 5.3.1. Access Control Lists AclEntry class: 5.3.1. Access Control Lists activation, dynamic: 3.3.2. Object Manager adaptable message protocols: 6.5. Adaptable Protocols addAgent( ): 9.3.1. Building the Infrastructure with Message Passing addEntry( ): 5.3.1. Access Control Lists addHandler( ): 6.6.2. Distributed Events addMessageType( ): 6.5.4. An Adaptable Message Handler addPageElements( ): 8.5.2. Web Browsing addPermission( ): 5.3.1. Access Control Lists addresses, IP: 2.1.1. IP Addressing addSample( ): 8.4. Monitoring Bandwidth agents AgentConnection class (example): 9.3.1. Building the Infrastructure with Message Passing AgentHandler class (example): 9.3.1. Building the Infrastructure with Message Passing identities for: 5.3. Identities and Access Control 9.3.1. Building the Infrastructure with Message Passing collaboration and: 9.2.2. Maintaining Agent Identities managing: 5.2.2. The Core Security API verifying: 5.1. Security Issues and Concerns 5.5.5. Distributing Certified Public Keys imposter: 5.1. Security Issues and Concerns algorithms, cryptographic: 5.2.1.1. The User API 5.7. Choosing a Cryptographic Algorithm Diffie-Hellman technique: 5.4.2. Public Key Methods 5.4.2. Public Key Methods 5.7.2.1. Encryption techniques DSA: 5.2.1.1. The User API 5.7.2.1. Encryption techniques presently available: 5.7.2. Available Algorithms RSA public key encryption: 5.7.2.1. Encryption techniques AlreadyBoundException: D.1. The java.rmi Package applets: A. Using the Examples in Applets downloading support classes for: A.2. Class Downloads applications collaborative (see collaborative systems) distributed (see distributed applications) assignmentsFor( ): 7.2.4. JDBC-Enabled Data Objects asymmetric encryption techniques: 5.4.2. Public Key Methods 5.6.1. Ciphers for Secure Data Transfers asynchronous agents: 4.4.1. Asynchronous Agents communications, CORBA Event Service for: B.2. Event Service message handling: 6.3.1. Asychronous vs. Synchronous Message Handling message passing: 6.3.2. A Basic Message Processor audio, streaming (example): 8.5.1. Streaming Multimedia AudioConsumer class (example): 8.5.1. Streaming Multimedia AudioProducer class (example): 8.5.1. Streaming Multimedia AuditChannel interface: B.3.2. Security Model AuditDecision interface: B.3.2. Security Model auditing transactions (CORBA): B.3.1. Service Types audit_needed( ): B.3.2. Security Model authenticate( ): 5.5.3. An Authenticating Credit Agent 5.6.2. Back to Our Credit Agent authentication: 1.3.6.2. Secure remote transactions AuthAgent client (example): 5.5.3. An Authenticating Credit Agent 5.6.2. Back to Our Credit Agent AuthCreditAgent client (example): 5.5.3. An Authenticating Credit Agent CORBA Security Service for: B.3.1. Service Types digital signatures (see digital signatures) one-, two-, many-way: 5.7.1.3. One-, two-, and many-way cryptography PGP for: 5.7.3.2. Pretty Good Privacy (PGP) presently available techniques for: 5.7.2.2. Certificates and authentication techniques Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved. Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Index: B bandwidth-limited systems managing bandwidth: 8.2. Coping with Limited Bandwidth 8.5. Bandwidth Management monitoring bandwidth: 8.2. Coping with Limited Bandwidth types of: 8.1. Flavors of Limited Bandwidth BankServer interface (example): 3.5.2. The Interface Definition Language (IDL) BasicMessage class (example): 6.3.2. A Basic Message Processor 6.5.4. An Adaptable Message Handler (see also Message class) for heterogeneous argument lists: 6.4.1. Heterogeneous Argument Lists BasicMsgHandler class (example): 6.3.2. A Basic Message Processor 6.5.4. An Adaptable Message Handler (see also MessageHandler class) for heterogeneous argument lists: 6.4.1. Heterogeneous Argument Lists bind( ) Naming interface: D.1. The java.rmi Package Remote interface: D.2. The java.rmi.registry Package binding objects: B.1. Naming Service bind_new_context( ): B.1. Naming Service broadcast( ) Collaborator interface: 9.3.1. Building the Infrastructure with Message Passing Mediator interface: 9.3.1. Building the Infrastructure with Message Passing RMICollaboratorImpl class (example): 9.3.2. Collaborating with RMI broadcastCmd( ): 4.4.2. Distributed ThreadGroups browser application example: 8.5.2. Web Browsing BufferedInputStream class: 1.3.6.2. Secure remote transactions 2.1.4. Streams, Readers, and Writers for Input and Output BufferedOutputStream class: 1.3.6.2. Secure remote transactions 2.1.4. Streams, Readers, and Writers for Input and Output BufferedReader class: 2.1.4. Streams, Readers, and Writers for Input and Output BufferedWriter class: 2.1.4. Streams, Readers, and Writers for Input and Output buffering data: 8.5.1. Streaming Multimedia buildMessage( ): 6.3.2. A Basic Message Processor 6.5.4. An Adaptable Message Handler buildUI( ): A.1. Whiteboard Applet byte-oriented I/O: 2.1.4. Streams, Readers, and Writers for Input and Output ByteArrayInputStream class: 2.1.4. Streams, Readers, and Writers for Input and Output ByteArrayOutputStream class: 2.1.4. Streams, Readers, and Writers for Input and Output bytecodes: 1.3.3. Platform Independence Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved. Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Index: C caching database data: 7.2.5. Data Caching Issues CallableStatement class: 7.1.2.3. Statement cancel( ): C.4.6. cancel( ) CAs (certification authorities): 5.4.2. Public Key Methods 5.5.5. Distributing Certified Public Keys 5.7.2.2. Certificates and authentication techniques catch clause: 1.3.4. Fault Tolerance Through Exception Handling certification: 5.5.4. Certification: The Last Identity Link certification authorities (CAs): 5.4.2. Public Key Methods 5.5.5. Distributing Certified Public Keys 5.7.2.2. Certificates and authentication techniques digital signatures (see digital signatures) distributing public keys: 5.5.5. Distributing Certified Public Keys presently available techniques for: 5.7.2.2. Certificates and authentication techniques public key certificates: 5.4.2. Public Key Methods CFDContentHandler class (example): 2.2. URLs, URLConnections, and ContentHandlers CFDContentHandlerFactory class (example): 2.2. URLs, URLConnections, and ContentHandlers character-based I/O: 2.1.4. Streams, Readers, and Writers for Input and Output CharArrayReader class: 2.1.4. Streams, Readers, and Writers for Input and Output CharArrayWriter class: 2.1.4. Streams, Readers, and Writers for Input and Output chat system (example): 10.1. A Simple Chat System checkPermission( ): 5.5.3. An Authenticating Credit Agent chess-playing agents example: 6.1. Messages Defined Chess...Event classes (example): 6.6.2. Distributed Events ChessEventServer class (example): 6.6.2. Distributed Events ChessMessage class (example): 6.4. Fixed Protocols ChessMove class (example): 6.4.2. Objects as Message Arguments 6.5.4. An Adaptable Message Handler ChessPlayer class (example): 6.4. Fixed Protocols ChessServer class (example): 6.4. Fixed Protocols 6.4. Fixed Protocols fixed message protocol for: 6.4. Fixed Protocols Java events for: 6.6.2. Distributed Events RMI implementation of: 6.7. Using Remote Objects synchronous vs. asynchronous handling: 6.3.1. Asychronous vs. Synchronous Message Handling Cipher class: 5.6.1. Ciphers for Secure Data Transfers classes ClassLoader class: 2.3. The ClassLoader object serialization versus: 3.6.6. Serializing Objects ClassNotFoundException: 2.3.1. Loading Classes from the Network downloading for applets: A.2. Class Downloads locking for threads: 4.3.1. Synchronizing Threads references to: 3.2.1. Creating Remote Objects clients interface for object classes: 3.3. Features of Distributed Object Systems object stub: 3.3. Features of Distributed Object Systems IDL interface and: 3.5.4. Client Stubs 3.5.5.2. The client stubs Java RMI and: 3.6.4. Client Stubs and Server Skeletons PipedClient class (example): 2.1.4. Streams, Readers, and Writers for Input and Output RunnableSolverClient class (example): 4.2.1. Implementing Runnable SimpleClient class (example): 1.3.5. Network Support code, obtaining online: 0.3. About the Source Code collaborative systems chat system (example): 10.1. A Simple Chat System Collaborator interface (example): 9.3.1. Building the Infrastructure with Message Passing 9.3.1. Building the Infrastructure with Message Passing collaborator requirements: 9.3.1. Building the Infrastructure with Message Passing CollaboratorMessage class (example): 9.3.1. Building the Infrastructure with Message Passing concerns with: 9.2. Issues with Collaboration definition of: 9.1. What Is a Collaborative System? infrastructure of: 9.3. A Basic Collaborative Infrastructure with message passing: 9.3.1. Building the Infrastructure with Message Passing MessageCollaborator interface (example): 9.3.1. Building the Infrastructure with Message Passing 9.3.1. Building the Infrastructure with Message Passing A.1. Whiteboard Applet with RMI: 9.3.2. Collaborating with RMI shared whiteboard (example): 10.2. A Shared Whiteboard commit( ): 7.1.2.3. Statement communication protocols: 1.2.2. Flexible, Extendible Communication Protocols complexity of cryptographic algorithms: 5.7.1.2. Sophistication and complexity concede( ): 6.4. Fixed Protocols ConcedeMessage class (example): 6.4. Fixed Protocols configuring JDBC drivers: 7.2.1. JDBC Driver Configurations ConfirmMoveMessage class (example): 6.4. Fixed Protocols 6.4.1. Heterogeneous Argument Lists connect( ): 9.3.1. Building the Infrastructure with Message Passing ConnectException: D.1. The java.rmi Package ConnectIOException: D.1. The java.rmi Package Connection interface: 7.1.2.2. Connection connect_pull_supplier( ): B.2.2. Interface Specifics constraintsFor( ): 7.2.4. JDBC-Enabled Data Objects consume( ): 8.4.2. Real Data Monitoring consumeAll( ): 8.4.2. Real Data Monitoring ConsumerAdmin interface: B.2. Event Service ContentConsumer class (example): 8.4.2. Real Data Monitoring ContentHandler class: 2.2. URLs, URLConnections, and ContentHandlers ContentHandlerFactory class: 2.2. URLs, URLConnections, and ContentHandlers ContentProducer class (example): 8.4.2. Real Data Monitoring CORBA: 3.5. CORBA B. CORBA Services Event Service: B.2. Event Service IDL (Interface Definition Language): 3.5.2. The Interface Definition Language (IDL) Solver interface (example): 3.5.5.1. The IDL interface Naming Service: B.1. Naming Service java.rmi.Naming versus: B.1.1. Comparison to the RMI Registry ORB (Object Request Broker): 3.5.1. The Object Request Broker (ORB) RMI versus: 3.7. RMI vs. CORBA Security Service: B.3. Security Service CosEventChannelAdmin module: B.2.2. Interface Specifics CosEventComm module: B.2.2. Interface Specifics CosNaming module: B.1. Naming Service costs of cryptography: 5.7.1.5. Financial and legal issues createRegistry( ): D.2. The java.rmi.registry Package createServerSocket( ): D.3. The java.rmi.server Package createSocket( ): D.3. The java.rmi.server Package createStatement( ): 7.1.2.3. Statement Credential class: B.3.2. Security Model crypt( ): 5.6.1. Ciphers for Secure Data Transfers cryptography algorithms for: 5.2.1.1. The User API 5.7. Choosing a Cryptographic Algorithm JCE (Java Cryptography Extension): 5.2.2. The Core Security API SSL for: 5.7.3.1. Secure Socket Layer (SSL) Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved. Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Index: D data buffering: 8.5.1. Streaming Multimedia caching, database objects and: 7.2.5. Data Caching Issues encrypting (see encryption) marshaling: 3.2.2. Remote Method Calls multicasting: 2.1.3. Multicast Sockets partitioning and distributing: 1.2.1. Partitioning and Distributing Data and Functions raw throughput monitoring: 8.4.1. Raw Data Monitoring real throughput monitoring: 8.4.2. Real Data Monitoring XDR-formatted (example): 2.1.4. Streams, Readers, and Writers for Input and Output DatabaseItem interface (example): 7.2.4. JDBC-Enabled Data Objects multiple Connection objects: 7.3. Multi-Database Applications databases defining data objects: 7.2.2. Defining the Data Objects scheduling system example: 7.2.3. A Scheduling Example JDBC API, overview of: 7.1. An Overview of JDBC multiple in applications: 7.3. Multi-Database Applications ODBC drivers: 7.2.1. JDBC Driver Configurations remote: 7.2. Remote Database Applications remote data servers and: 7.2.6. Remote Data Servers sample query: 7.1.1. Data Retrieval Example scheduling system (example): 7.2.3. A Scheduling Example data caching: 7.2.5. Data Caching Issues with JDBC-enabled data objects: 7.2.4. JDBC-Enabled Data Objects DatagramPacket class: 2.1.2. Your Basic Socket DatagramSocket class: 2.1.2. Your Basic Socket DataInputStream class: 1.3.5. Network Support 2.1.4. Streams, Readers, and Writers for Input and Output DataMonitor class (example): 8.4. Monitoring Bandwidth DataOutputStream class: 2.1.4. Streams, Readers, and Writers for Input and Output dcj.examples packages: 0.3. About the Source Code dcj.utils packages: 0.3. About the Source Code defocusElement( ): 8.5.2. Web Browsing delegation models: 6.6.1. Event Model Overview destroy( ): B.2.2. Interface Specifics development tools for distributed object systems: 3.3.5. Development Tools Diffie-Hellman encryption technique: 5.4.2. Public Key Methods 5.4.2. Public Key Methods 5.7.2.1. Encryption techniques Digital Signature Algorithm (DSA): 5.2.1.1. The User API 5.7.2.1. Encryption techniques digital signatures: 5.2.2. The Core Security API 5.5. Digital Signatures DII (Dynamic Invocation Interface): 3.5. CORBA disconnect_push_supplier( ): B.2.2. Interface Specifics dispatch( ): D.3. The java.rmi.server Package distributed applications anatomy of: 1.1. Anatomy of a Distributed Application bandwidth-limited (see bandwidth-limited systems) with databases (see databases) requirements for development: 1.2. Requirements for Developing Distributed Applications distributed certified public keys: 5.5.5. Distributing Certified Public Keys distributed computing bandwidth-limited (see bandwidth-limited systems) development tools for: 3.3.5. Development Tools distribution of workload: 3.2.3. Other Issues history of: 0. Preface Java's advantages in: 1.3. What Does Java Provide? motivations for: 1. Introduction distributed events: 6.6.2. Distributed Events distributed objects: 3.1. Why Distribute Objects? databases and remote data: 7.2.6.2. Distributed objects from the data server Java schemes: 3.4. Distributed Object Schemes for Java comparison between: 3.7. RMI vs. CORBA CORBA: 3.5. CORBA Java RMI: 3.6. Java RMI JavaSpaces system: C. JavaSpaces system features: 3.3. Features of Distributed Object Systems distributed threads/ThreadGroups: 4.4.2. Distributed ThreadGroups synchronizing: 4.4.4. Synchronizing Distributed Threads distributeEvent( ): 6.6.2. Distributed Events distributing data and functions: 1.2.1. Partitioning and Distributing Data and Functions DistThreadGroup class (example): 4.4.2. Distributed ThreadGroups DNS (Domain Name Service): 2.1.1. IP Addressing doConsume( ) AudioConsumer class: 8.5.1. Streaming Multimedia ContentConsumer class: 8.4.2. Real Data Monitoring Domain Name Service (DNS): 2.1.1. IP Addressing done( ) RemoteCall interface: D.3. The java.rmi.server Package RemoteRef class: D.3. The java.rmi.server Package DoneCmd class (example): 1.3.5. Network Support doProduction( ) AudioProducer class: 8.5.1. Streaming Multimedia ContentProducer class: 8.4.2. Real Data Monitoring downloading applet support classes: A.2. Class Downloads web pages (example): 8.5.2. Web Browsing Driver interface: 7.1.2.1. DriverManager DriverManager class: 7.1.2.1. DriverManager drivers, configuring: 7.2.1. JDBC Driver Configurations DSA (Digital Signature Algorithm): 5.2.1.1. The User API 5.7.2.1. Encryption techniques DSAKeyPairGenerator interface: 5.2.1.1. The User API dynamic database objects: 7.2.3. A Scheduling Example Dynamic Invocation Interface (DII): 3.5. CORBA dynamic object activation: 3.3.2. Object Manager Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved. Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Index: E eavesdropping: 5.1. Security Issues and Concerns 5.6. Data Encryption encapsulation in database design: 7.2.2. Defining the Data Objects encryption: 1.3.6.2. Secure remote transactions 5.2.2. The Core Security API 5.6. Data Encryption asymmetric algorithms: 5.4.2. Public Key Methods 5.6.1. Ciphers for Secure Data Transfers available techniques for: 5.7.2.1. Encryption techniques EncryptedInputStream class (example): 1.3.6.2. Secure remote transactions PGP for: 5.7.3.2. Pretty Good Privacy (PGP) public key: 5.4.2. Public Key Methods SSL for: 5.7.3.1. Secure Socket Layer (SSL) symmetric algorithms: 5.6.1. Ciphers for Secure Data Transfers entries, JavaSpace: C.1. Overview of JavaSpaces Entry class (JavaSpaces): C.2. Entry and EntryRep EntryReps class (JavaSpaces): C.2. Entry and EntryRep equals( ) ObjID class: D.3. The java.rmi.server Package RemoteObject class: D.3. The java.rmi.server Package UID class: D.3. The java.rmi.server Package error handling: 1.3.4. Fault Tolerance Through Exception Handling Event Service (CORBA): B.2. Event Service events AWT: 6.6.3. Pros and Cons distributed: 6.6.2. Distributed Events event channels quality of service: B.2.1. Quality of Service for Channels EventHandler interface (example): 6.6.2. Distributed Events EventListener interface: 6.6.1. Event Model Overview B.2.3. Comparison to the Java Event Model EventObject class: 6.6.1. Event Model Overview EventTransceiver class (example): 6.6.2. Distributed Events message passing and: 6.6. Message Passing with Java Events example source code, obtaining: 0.3. About the Source Code exception handling: 1.3.4. Fault Tolerance Through Exception Handling executeCall( ): D.3. The java.rmi.server Package executeQuery( ): 7.1.2.3. Statement 7.1.2.3. Statement ExportException: D.3. The java.rmi.server Package extendibility: 1.2.2. Flexible, Extendible Communication Protocols Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved. Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Index: F failure( ): D.3. The java.rmi.server Package fault tolerance: 1.3.4. Fault Tolerance Through Exception Handling FilterInputStream class: 2.1.4. Streams, Readers, and Writers for Input and Output FilterOutputStream class: 2.1.4. Streams, Readers, and Writers for Input and Output FilterReader class: 2.1.4. Streams, Readers, and Writers for Input and Output FilterWriter class: 2.1.4. Streams, Readers, and Writers for Input and Output finalize( ): 1.3.5. Network Support finally blocks: 1.3.4. Fault Tolerance Through Exception Handling fixed message protocols: 6.4. Fixed Protocols flexibility: 1.2.2. Flexible, Extendible Communication Protocols for_consumers( ): B.2.2. Interface Specifics forName( ): 3.2.1. Creating Remote Objects 7.1.2.1. DriverManager for_suppliers( ): B.2.2. Interface Specifics FTP, obtaining source code via: 0.3. About the Source Code fully qualified hostnames: 2.1.1. IP Addressing functions, partitioning and distributing: 1.2.1. Partitioning and Distributing Data and Functions Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved. Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Index: G generateKey( ): 5.4.3. Keys in the Java Security API generateKeyPair( ): 5.4.3. Keys in the Java Security API generating keys: 5.4.2. Public Key Methods 5.4.3. Keys in the Java Security API getAddress( ): 2.1.1. IP Addressing getAlgorithm( ): 5.4.3. Keys in the Java Security API getAllTasks( ): 7.2.4. JDBC-Enabled Data Objects getAverageRate( ): 8.4. Monitoring Bandwidth getClientHost( ) RemoteServer class: D.3. The java.rmi.server Package ServerRef interface: D.3. The java.rmi.server Package GetCmd class (example): 1.3.5. Network Support getConnection( ): 7.1.1. Data Retrieval Example 7.1.2.1. DriverManager getConsumer( ): 8.5.2. Web Browsing getContent( ): 2.2. URLs, URLConnections, and ContentHandlers getCreditData( ) (example): 5.5.1. A Motivating Example: A Credit Agent getDefaultStream( ): D.3. The java.rmi.server Package getHostName( ): 2.1.1. IP Addressing getIdentity( ): 9.3.1. Building the Infrastructure with Message Passing getInputStream( ) java.io package: 2.1.4. Streams, Readers, and Writers for Input and Output RemoteCall interface: D.3. The java.rmi.server Package getInstance( ): 5.5.2. Public Key Signatures for Authentication getLastRate( ): 8.4. Monitoring Bandwidth getLog( ): D.3. The java.rmi.server Package getName( ): 3.2.2. Remote Method Calls getOperation( ): D.3. The java.rmi.server Package getOperations( ): D.3. The java.rmi.server Package getOutputStream( ) java.io package: 2.1.4. Streams, Readers, and Writers for Input and Output LogStream class: D.3. The java.rmi.server Package RemoteCall interface: D.3. The java.rmi.server Package getPrivate( ): 5.4.3. Keys in the Java Security API getPublic( ): 5.4.3. Keys in the Java Security API getRateFor( ): 8.4. Monitoring Bandwidth getRegistry( ): D.2. The java.rmi.registry Package GetResourceMsg class (example): 7.2.6.1. Message passing with the data server getResultStream( ): D.3. The java.rmi.server Package getSecurityContext( ) LoaderHandler interface: D.3. The java.rmi.server Package RMIClassLoader class: D.3. The java.rmi.server Package getSocketFactory( ): D.3. The java.rmi.server Package Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved. Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Index: H handleEvent( ): 6.6.2. Distributed Events B.2.3. Comparison to the Java Event Model hashCode( ) ObjID class: D.3. The java.rmi.server Package RemoteObject class: D.3. The java.rmi.server Package UID class: D.3. The java.rmi.server Package HeadCmd class (example): 1.3.5. Network Support heterogeneous argument lists: 6.4.1. Heterogeneous Argument Lists host computers: 2.1.1. IP Addressing HTMLPageLoader class (example): 8.5.2. Web Browsing HTTP protocol: 2.2. URLs, URLConnections, and ContentHandlers Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved. Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Index: I identifiers, message: 6.1. Messages Defined identity, agent: 5.3. Identities and Access Control 9.3.1. Building the Infrastructure with Message Passing collaboration and: 9.2.2. Maintaining Agent Identities managing: 5.2.2. The Core Security API verifying: 5.1. Security Issues and Concerns 5.5.5. Distributing Certified Public Keys Identity class (example): 5.3. Identities and Access Control 9.3.1. Building the Infrastructure with Message Passing IDL (Interface Definition Language): 3.5.2. The Interface Definition Language (IDL) Solver interface (example): 3.5.5.1. The IDL interface IIOP (Internet Inter-ORB Protocol): 3.5. CORBA implementation-neutral interfaces: 1.3.2. Abstract Interfaces implementation of object classes: 3.3. Features of Distributed Object Systems import statement: 2.3. The ClassLoader imposter agents: 5.1. Security Issues and Concerns in keyword (IDL): 3.5.2. The Interface Definition Language (IDL) InetAddress class: 2.1.1. IP Addressing initEncrypt( ): 5.6.1. Ciphers for Secure Data Transfers initialize( ): 5.4.3. Keys in the Java Security API initSign( ): 5.5.2. Public Key Signatures for Authentication initStream( ): 2.3.1. Loading Classes from the Network initVerify( ): 5.5.2. Public Key Signatures for Authentication inout keyword (IDL): 3.5.2. The Interface Definition Language (IDL) 3.5.5.2. The client stubs InputStream classes: 2.1.4. Streams, Readers, and Writers for Input and Output 4.2.1. Implementing Runnable InputStreamReader class: 2.1.4. Streams, Readers, and Writers for Input and Output interactive chat system (example): 10.1. A Simple Chat System Interface Definition Language (IDL): 3.5.2. The Interface Definition Language (IDL) Solver interface (example): 3.5.5.1. The IDL interface interfaces, abstract (implementation-neutral): 1.3.2. Abstract Interfaces Internet Inter-ORB Protocol (IIOP): 3.5. CORBA Internet Protocol (IP): 2.1. Sockets and Streams intruders: 5.1. Security Issues and Concerns invoke( ): D.3. The java.rmi.server Package IP (Internet Protocol): 2.1. Sockets and Streams isAuthorized( ): 5.5.3. An Authenticating Credit Agent Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved. Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Index: J Java Cryptography Extension (JCE): 5.2.2. The Core Security API Cipher class: 5.6.1. Ciphers for Secure Data Transfers Java language advantages for distributed computing: 1.3. What Does Java Provide? distributed object schemes: 3.4. Distributed Object Schemes for Java comparison between: 3.7. RMI vs. CORBA CORBA: 3.5. CORBA Java RMI: 3.6. Java RMI event model: 6.6.1. Event Model Overview B.2.3. Comparison to the Java Event Model multithreading support: 1.3.7. Multithreading Support network support of: 1.3.5. Network Support as RMI's exclusive language: 3.7.1. The Language Barrier: Advantage or Disadvantage? security: 1.3.6. Security 5.1. Security Issues and Concerns Java RMI: 3.6. Java RMI collaborating with: 9.3.2. Collaborating with RMI CORBA versus: 3.7. RMI vs. CORBA B.1.1. Comparison to the RMI Registry message passing with: 6.7. Using Remote Objects quick reference: D. RMI Quick Reference Registry: 3.6.3. The RMI Registry security manager for: 3.6.5. Registering and Using a Remote Object Java Security API (java.security): 1.3.6.2. Secure remote transactions 5.2. The java.security Package B.3.3. Comparison to the Java Security API acl package: 5.3.1. Access Control Lists Cipher class: 5.6.1. Ciphers for Secure Data Transfers Key interface: 5.4.3. Keys in the Java Security API Java Virtual Machine (JVM): 1.3.3. Platform Independence java.io package: 1.3.5. Network Support 2.1.4. Streams, Readers, and Writers for Input and Output java.net package: 2.1. Sockets and Streams 2.2. URLs, URLConnections, and ContentHandlers java.rmi package: D.1. The java.rmi Package java.rmi.Naming interface (see naming service) java.rmi.server package: D.3. The java.rmi.server Package JavaSpace interface: C.4. The JavaSpace Interface JavaSpaces system: C. JavaSpaces JCE (Java Cryptography Extension): 5.2.2. The Core Security API Cipher class: 5.6.1. Ciphers for Secure Data Transfers JDBC API: 7.1. An Overview of JDBC driver configuration: 7.2.1. JDBC Driver Configurations JDBC-enabled data objects: 7.2.4. JDBC-Enabled Data Objects multi-database applications: 7.3. Multi-Database Applications JIT (just-in-time) compilers: 3.7.1. The Language Barrier: Advantage or Disadvantage? joinGroup( ): 2.1.3. Multicast Sockets JVM (see Java Virtual Machine) Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved. Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Index: K Key interface: 5.4.3. Keys in the Java Security API KeyGenerator class: 5.4.3. Keys in the Java Security API KeyPair class: 5.4.3. Keys in the Java Security API KeyPairGenerator class: 5.4.3. Keys in the Java Security API keys: 5.4. Keys: Public, Private, and Secret certified public, distributing: 5.5.5. Distributing Certified Public Keys public key encryption: 5.4.2. Public Key Methods public key signatures: 5.5.2. Public Key Signatures for Authentication public vs. private: 5.4.2. Public Key Methods secret: 5.4.1. Secret Keys Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved. Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Index: L leaveGroup( ): 2.1.3. Multicast Sockets legal issues and cryptography: 5.7.1.5. Financial and legal issues licenses for cryptography: 5.7.1.5. Financial and legal issues limited bandwidth (see bandwidth-limited systems) list( ) Naming interface: D.1. The java.rmi Package Remote interface: D.2. The java.rmi.registry Package listen( ): 1.3.5. Network Support loadClass( ) ClassLoader class: 2.3. The ClassLoader 2.3.1. Loading Classes from the Network LoaderHandler interface: D.3. The java.rmi.server Package RMIClassLoader class: D.3. The java.rmi.server Package loadElements( ): 8.5.2. Web Browsing 8.5.2. Web Browsing LoaderHandler interface: D.3. The java.rmi.server Package loading classes: 2.3. The ClassLoader object serialization versus: 3.6.6. Serializing Objects LocateRegistry interface: D.2. The java.rmi.registry Package locking classes for threads: 4.3.1. Synchronizing Threads log( ): D.3. The java.rmi.server Package LogStream class: D.3. The java.rmi.server Package lookup( ) Naming interface: 3.6.3. The RMI Registry D.1. The java.rmi Package Remote interface: D.2. The java.rmi.registry Package lookupSecretKey( ): 5.6.2. Back to Our Credit Agent Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved. Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Index: M managing bandwidth: 8.2.2. Managing Bandwidth 8.5. Bandwidth Management streaming audio example: 8.5.1. Streaming Multimedia web browser example: 8.5.2. Web Browsing MarshalException: D.1. The java.rmi Package marshaling data: 3.2.2. Remote Method Calls MD5 message digest format: 5.2.1.2. The Provider API Mediator interface (example): 9.3.1. Building the Infrastructure with Message Passing MediatorMessage class (example): 9.3.1. Building the Infrastructure with Message Passing mediators: 9.3. A Basic Collaborative Infrastructure 9.3.1. Building the Infrastructure with Message Passing Message class (example): 6.5.4. An Adaptable Message Handler message handlers: 6.3. Message Processing adaptable: 6.5.4. An Adaptable Message Handler asynchronous vs. synchronous: 6.3.1. Asychronous vs. Synchronous Message Handling example processor: 6.3.2. A Basic Message Processor for heterogeneous argument lists: 6.4.1. Heterogeneous Argument Lists message-passing systems advantages to: 6.2. Why Do We Need Messages? chess-playing agents example: 6.4. Fixed Protocols collaborative: 9.3.1. Building the Infrastructure with Message Passing databases and remote data: 7.2.6.1. Message passing with the data server Java events with: 6.6. Message Passing with Java Events remote objects for: 6.7. Using Remote Objects MessageCollaborator interface (example): 9.3.1. Building the Infrastructure with Message Passing 9.3.1. Building the Infrastructure with Message Passing as applet: A.1. Whiteboard Applet MessageHandler class (example): 6.5.4. An Adaptable Message Handler collaboration by using: 9.3.1. Building the Infrastructure with Message Passing MessageMediator class (example): 9.3.1. Building the Infrastructure with Message Passing as applet: A.1. Whiteboard Applet messages adaptable message types: 6.5.3. Adaptable Message Types adaptable protocols for: 6.5. Adaptable Protocols definition of: 6.1. Messages Defined fixed protocols for: 6.4. Fixed Protocols heterogeneous argument lists: 6.4.1. Heterogeneous Argument Lists identifiers for: 6.1. Messages Defined objects as arguments: 6.4.2. Objects as Message Arguments rationale for: 6.2. Why Do We Need Messages? variable arguments: 6.5.1. Variable Number of Arguments methods Method class: 3.2.2. Remote Method Calls public key: 5.4.2. Public Key Methods remote invocation of: 3.2.2. Remote Method Calls synchronized: 4.3.1. Synchronizing Threads monitoring bandwidth: 8.2.1. Monitoring Bandwidth raw data throughput: 8.4.1. Raw Data Monitoring real data throughput: 8.4.2. Real Data Monitoring monitoring sytem performance: 4.4.3. Improving Efficiency with Thread Priorities mouse events browser example and: 8.5.2. Web Browsing whiteboard example and: 10.2. A Shared Whiteboard mouseDragged( ): 8.5.2. Web Browsing moveAccepted( ): 6.4. Fixed Protocols MoveMessage class (example): 6.4. Fixed Protocols 6.4.1. Heterogeneous Argument Lists adaptable version of: 6.5.4. An Adaptable Message Handler with object arguments: 6.4.2. Objects as Message Arguments MsgWhiteboardUser class (example): A.1. Whiteboard Applet multi-database applications: 7.3. Multi-Database Applications multi-way agent authentication: 5.7.1.3. One-, two-, and many-way cryptography multicast sockets: 2.1.3. Multicast Sockets multicasting: 2.1.3. Multicast Sockets MulticastSocket class: 2.1.3. Multicast Sockets multimedia, streaming (example): 8.5.1. Streaming Multimedia multithreading (see threads) Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved. Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Index: N NameComponent class: B.1. Naming Service Naming interface: 3.6.3. The RMI Registry quick reference for: D.1. The java.rmi Package naming service: 3.2.3. Other Issues 3.3.3. Registration/Naming Service CORBA: 3.5.3. Server Implementations 3.5.5.5. Pulling it all together B.1. Naming Service java.rmi.Naming vs. CORBA: B.1.1. Comparison to the RMI Registry RMI Registry: 3.6.3. The RMI Registry NamingContext interface: B.1. Naming Service network communications ClassLoader class: 2.3. The ClassLoader object serialization versus: 3.6.6. Serializing Objects collaboration and: 9.2.1. Communication Needs eavesdropping on: 5.1. Security Issues and Concerns 5.6. Data Encryption HTTP protocol support: 2.2. URLs, URLConnections, and ContentHandlers Java support for: 1.3.5. Network Support multicasting: 2.1.3. Multicast Sockets object communication protocol: 3.3.4. Object Communication Protocol protocol requirements: 1.2.2. Flexible, Extendible Communication Protocols remote transaction security: 1.3.6.2. Secure remote transactions sockets and streams: 2.1. Sockets and Streams threads and: 4.4. Networked Threads newCall( ): D.3. The java.rmi.server Package newCopy( ): 6.5.4. An Adaptable Message Handler newInstance( ): 3.2.1. Creating Remote Objects newMember( ): 9.3.1. Building the Infrastructure with Message Passing nextMove( ): 6.4. Fixed Protocols non-repudiation facilities (CORBA): B.3.1. Service Types NoSuchObjectException: D.1. The java.rmi Package NotBoundException: D.1. The java.rmi Package notify( ) Collaborator interface: 9.3.1. Building the Infrastructure with Message Passing JavaSpace interface: C.4.4. notify( ) NRCredentials interface: B.3.2. Security Model Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved. Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Index: O Object Management Group (OMG): 3.5. CORBA object manager: 3.3.2. Object Manager CORBA's ORB: 3.5.1. The Object Request Broker (ORB) RMI Registry: 3.6.3. The RMI Registry object-oriented programming: 1.3.1. Object-Oriented Environment object references: 3.2.1. Creating Remote Objects Object Request Broker (see ORB) objects abstract interfaces for: 1.3.2. Abstract Interfaces binding: B.1. Naming Service client stub: 3.3. Features of Distributed Object Systems IDL interface and: 3.5.4. Client Stubs 3.5.5.2. The client stubs Java RMI and: 3.6.4. Client Stubs and Server Skeletons of databases, defining: 7.2.2. Defining the Data Objects scheduling system example: 7.2.3. A Scheduling Example dynamic activation: 3.3.2. Object Manager interface specification: 3.3. Features of Distributed Object Systems as message arguments: 6.4.2. Objects as Message Arguments persistence: B.4. Other Key CORBA Services registration/naming service: 3.2.3. Other Issues 3.3.3. Registration/Naming Service CORBA and: 3.5.3. Server Implementations 3.5.5.5. Pulling it all together RMI Registry: 3.6.3. The RMI Registry remote communication protocol: 3.3.4. Object Communication Protocol creating: 3.2.1. Creating Remote Objects for message passing: 6.7. Using Remote Objects registering (RMI): 3.6.5. Registering and Using a Remote Object remote interfaces: 3.6.1. Remote Object Interfaces serializing: 3.2.1. Creating Remote Objects 3.6.6. Serializing Objects C.2. Entry and EntryRep server skeleton: 3.3. Features of Distributed Object Systems IDL interface and: 3.5.3. Server Implementations 3.5.5.3. The server skeleton and implementation Java RMI and: 3.6.4. Client Stubs and Server Skeletons verifying incoming: 5.1. Security Issues and Concerns ObjID class: D.3. The java.rmi.server Package obtain_pull_consumer( ): B.2.2. Interface Specifics obtain_push_consumer( ): B.2.2. Interface Specifics ODBC database drivers: 7.2.1. JDBC Driver Configurations OMG (Object Management Group): 3.5. CORBA one-way agent authentication: 5.7.1.3. One-, two-, and many-way cryptography openConnection( ): 2.2. URLs, URLConnections, and ContentHandlers openStream( ): 2.2. URLs, URLConnections, and ContentHandlers Operation class: D.3. The java.rmi.server Package ORB (Object Request Broker): 3.5. CORBA Internet Inter-ORB Protocol (IIOP): 3.5. CORBA out keyword (IDL): 3.5.2. The Interface Definition Language (IDL) OutputStream classes: 2.1.4. Streams, Readers, and Writers for Input and Output 4.2.1. Implementing Runnable OutputStreamWriter class: 2.1.4. Streams, Readers, and Writers for Input and Output Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved. Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Index: P parseClassName( ): 2.3.1. Loading Classes from the Network parseLevel( ): D.3. The java.rmi.server Package partitioning data and functions: 1.2.1. Partitioning and Distributing Data and Functions performance collaboration and: 9.2.4. Performance distribution of workload: 3.2.3. Other Issues monitoring: 4.4.3. Improving Efficiency with Thread Priorities multithreading and: 1.2.3. Multithreading Requirements thread management: 1.3.7. Multithreading Support thread priorities: 4.3.3. Priorities 4.4.3. Improving Efficiency with Thread Priorities PermissionImpl class: 5.3.1. Access Control Lists permissions, adding to ACL entries: 5.3.1. Access Control Lists persistent objects: B.4. Other Key CORBA Services PGP (Pretty Good Privacy): 5.7.3.2. Pretty Good Privacy (PGP) PipedClient class (example): 2.1.4. Streams, Readers, and Writers for Input and Output PipedInputStream class: 2.1.4. Streams, Readers, and Writers for Input and Output PipedOutputStream class: 2.1.4. Streams, Readers, and Writers for Input and Output PipedServer class (example): 2.1.4. Streams, Readers, and Writers for Input and Output platform independence: 1.3.3. Platform Independence Java RMI versus CORBA: 3.7.1. The Language Barrier: Advantage or Disadvantage? specifying object interfaces: 3.3.1. Object Interface Specification port numbers: 2.1.1. IP Addressing PostCmd class (example): 1.3.5. Network Support postConsume( ): 8.4.2. Real Data Monitoring postProduction( ): 8.4.2. Real Data Monitoring preConsume( ): 8.4.2. Real Data Monitoring prepareCall( ): 7.1.2.3. Statement PreparedStatement class: 7.1.2.3. Statement prepareStatement( ): 7.1.2.3. Statement preProduction( ): 8.4.2. Real Data Monitoring Pretty Good Privacy (PGP): 5.7.3.2. Pretty Good Privacy (PGP) Principal interface: 5.3. Identities and Access Control PrincipalAuthenticator interface: B.3.2. Security Model PrincipalImpl class: 5.3.1. Access Control Lists priorities, thread: 1.3.7. Multithreading Support 4.3.3. Priorities 4.4.3. Improving Efficiency with Thread Priorities private keys: 5.4.2. Public Key Methods PrivateKey class: 5.4.3. Keys in the Java Security API privileges for database objects: 7.2.3. A Scheduling Example ProblemSet interface (example): 3.4. Distributed Object Schemes for Java in CORBA environment: 3.5.5. A CORBA Solver Runnable interface with: 4.2.1. Implementing Runnable using Java RMI: 3.6.7. An RMI Solver processes: 1.1. Anatomy of a Distributed Application processing messages (see message handlers) produce( ): 8.4.2. Real Data Monitoring produceAll( ) AudioProducer class: 8.5.1. Streaming Multimedia ContentProducer class: 8.4.2. Real Data Monitoring production pipelines: 8.4.2. Real Data Monitoring provider API (java.security): 5.2.1.2. The Provider API Provider interface: 5.2.1.2. The Provider API pseudo-random number generator: 5.4.3. Keys in the Java Security API public keys certificates: 5.4.2. Public Key Methods digital signatures and: 5.5.2. Public Key Signatures for Authentication distributing: 5.5.5. Distributing Certified Public Keys encryption: 5.4.2. Public Key Methods PublicKey class: 5.4.3. Keys in the Java Security API 5.5.5. Distributing Certified Public Keys RSA encryption: 5.7.2.1. Encryption techniques pull( ): B.2. Event Service push( ): B.2. Event Service PushbackInputStream class: 2.1.4. Streams, Readers, and Writers for Input and Output PushbackReader class: 2.1.4. Streams, Readers, and Writers for Input and Output PushSupplier interface: B.2.2. Interface Specifics Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved. Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Index: Q quality of service, event channel: B.2.1. Quality of Service for Channels query service (CORBA): B.4. Other Key CORBA Services query statements: 7.1.2.3. Statement Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved. Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Index: R random number generator: 5.4.3. Keys in the Java Security API raw data throughput: 8.4.1. Raw Data Monitoring read( ) JavaSpace interface: C.4.2. read( ) ObjID class: D.3. The java.rmi.server Package UID class: D.3. The java.rmi.server Package readArgs( ): 6.4.1. Heterogeneous Argument Lists readClass( ): 2.3.1. Loading Classes from the Network Reader classes: 2.1.4. Streams, Readers, and Writers for Input and Output readMsg( ): 6.3.2. A Basic Message Processor 6.4.1. Heterogeneous Argument Lists 9.3.1. Building the Infrastructure with Message Passing real data throughput: 8.4.2. Real Data Monitoring real-time (see bandwidth-limited applications) Real-Time Control Protocol (RTCP): 8.2.3. Levels of Monitoring and Management Real-Time Protocol (RTP): 8.2.3. Levels of Monitoring and Management rebind( ) Naming interface: D.1. The java.rmi Package Remote interface: D.2. The java.rmi.registry Package receiveEvent( ): 6.6.2. Distributed Events registration service: 3.3. Features of Distributed Object Systems 3.3.3. Registration/Naming Service CORBA and: 3.5.3. Server Implementations 3.5.5.5. Pulling it all together RMI Registry: 3.6.3. The RMI Registry Registry interface: D.2. The java.rmi.registry Package Registry, Java RMI: 3.6.3. The RMI Registry RegistryHandler interface: D.2. The java.rmi.registry Package registryImpl( ): D.2. The java.rmi.registry Package registryStub( ): D.2. The java.rmi.registry Package RejectMoveMessage class (example): 6.4. Fixed Protocols releaseInputStream( ): D.3. The java.rmi.server Package releaseOutputStream( ): D.3. The java.rmi.server Package remote database data servers: 7.2.6. Remote Data Servers databases: 7.2. Remote Database Applications method invocation: 3.2.2. Remote Method Calls object interfaces: 3.6.1. Remote Object Interfaces object references: 3.2.1. Creating Remote Objects objects communication protocol for: 3.3.4. Object Communication Protocol creating: 3.2.1. Creating Remote Objects for message passing: 6.7. Using Remote Objects registering (RMI): 3.6.5. Registering and Using a Remote Object Remote interface: 3.6.1. Remote Object Interfaces D.1. The java.rmi Package Remote Method Invocation (see Java RMI) RemoteCall interface: D.3. The java.rmi.server Package RemoteException: 3.6.1. Remote Object Interfaces C.2. Entry and EntryRep D.1. The java.rmi Package RemoteObject class: D.3. The java.rmi.server Package RemoteRef interface: D.3. The java.rmi.server Package RemoteServer class: 3.6.2. Server Implementations D.3. The java.rmi.server Package RemoteStub class: D.3. The java.rmi.server Package transaction security: 1.3.6.2. Secure remote transactions remoteEquals( ): D.3. The java.rmi.server Package remoteHashCode( ): D.3. The java.rmi.server Package remoteToString( ): D.3. The java.rmi.server Package removeHandler( ): 6.6.2. Distributed Events removeMember( ): 9.3.1. Building the Infrastructure with Message Passing renew( ): C.4.5. renew( ) ResAssignment class (example): 7.2.4. JDBC-Enabled Data Objects 7.2.4. JDBC-Enabled Data Objects resizeBuffer( ): 8.5.1. Streaming Multimedia resolving object names: B.1. Naming Service ResultSet class: 7.1.1. Data Retrieval Example 7.1.2.4. ResultSet resume( ): 4.4.2. Distributed ThreadGroups RMI (see Java RMI) rmic compiler: 3.6.4. Client Stubs and Server Skeletons RMIChatClient class (example): 10.1. A Simple Chat System RMIChessMove interface (example): 6.7. Using Remote Objects RMIChessMoveImpl class (example): 6.7. Using Remote Objects RMIChessPlayer interface (example): 6.7. Using Remote Objects RMIChessPlayerImpl class (example): 6.7. Using Remote Objects RMIClassLoader class: D.3. The java.rmi.server Package RMICollaborator interface (example): 9.3.2. Collaborating with RMI 9.3.2. Collaborating with RMI RMICollaboratorImpl class (example): 9.3.2. Collaborating with RMI 9.3.2. Collaborating with RMI 10.1. A Simple Chat System 10.2. A Shared Whiteboard RMIDatabaseItem interface (example): 7.2.6.2. Distributed objects from the data server RMIFailureHandler interface: D.3. The java.rmi.server Package RMIMediator interface (example): 9.3.2. Collaborating with RMI 9.3.2. Collaborating with RMI RMIMediatorImpl class (example): 9.3.2. Collaborating with RMI 10.2. A Shared Whiteboard rmiregistry command: 3.6.3. The RMI Registry RMISchedDbase interface (example): 7.2.6.2. Distributed objects from the data server RMIScheduler class (example): 7.2.6.2. Distributed objects from the data server RMISecurityException: D.1. The java.rmi Package RMISecurityManager class: D.1. The java.rmi Package RMISocketFactory class: D.3. The java.rmi.server Package RMISolver interface (example): 3.6.7. An RMI Solver RmtThreadGroup class (example): 4.4.2. Distributed ThreadGroups rollback( ): 7.1.2.3. Statement RSA public key encryption: 5.7.2.1. Encryption techniques RSAKeyPairGenerator class: 5.4.3. Keys in the Java Security API RTCP (Real-Time Control Protocol): 8.2.3. Levels of Monitoring and Management RTInputStream class (example): 8.4.1. Raw Data Monitoring RTOutputStream class (example): 8.4.1. Raw Data Monitoring RTP (Real-Time Protocol): 8.2.3. Levels of Monitoring and Management run( ): 1.3.7. Multithreading Support 4.1. Thread and Runnable Runnable interface: 1.3.7. Multithreading Support 4.1. Thread and Runnable for asynchronous message passing: 6.3.2. A Basic Message Processor implementing: 4.2.1. Implementing Runnable RunnableSolver class (example): 4.2.1. Implementing Runnable RunnableSolverClient class (example): 4.2.1. Implementing Runnable RunnableSolveServer class (example): 4.2.1. Implementing Runnable runtime environment Java RMI Registry: 3.6.3. The RMI Registry loading class definitions: 2.3. The ClassLoader object serialization versus: 3.6.6. Serializing Objects managing threads: 4.3. Managing Threads at Runtime remote objects and: 3.3. Features of Distributed Object Systems security and: 1.3.6.1. Runtime environment Runtime interface: 2.1.4. Streams, Readers, and Writers for Input and Output Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved. Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Index: S SchedDbaseImpl class (example): 7.2.6.2. Distributed objects from the data server SchedResource class (example): 7.2.4. JDBC-Enabled Data Objects data caching and: 7.2.5. Data Caching Issues message-passing version: 7.2.6.1. Message passing with the data server RMI-enabled version: 7.2.6.2. Distributed objects from the data server SchedResourceImpl class (example): 7.2.6.2. Distributed objects from the data server SchedTask class (example): 7.2.4. JDBC-Enabled Data Objects 7.2.4. JDBC-Enabled Data Objects scheduling system (example): 7.2.3. A Scheduling Example data caching: 7.2.5. Data Caching Issues with JDBC-enabled data objects: 7.2.4. JDBC-Enabled Data Objects secret keys: 5.4.1. Secret Keys SecretKey class: 5.4.3. Keys in the Java Security API Secure Socket Layer (SSL): 5.7.3.1. Secure Socket Layer (SSL) SecureAgent client (example): 5.6.2. Back to Our Credit Agent SecureRandom class: 5.4.3. Keys in the Java Security API security: 1.2.4. Security Issues 1.3.6. Security 5.1. Security Issues and Concerns authentication (see authentication) certification (see certification) development object systems and: 3.3.6. Security encryption (see encryption) general protocols for: 5.7.3. General Security Protocols Java API for (see Java Security API) keys (see keys) RMI security manager: 3.6.5. Registering and Using a Remote Object Security Service (CORBA): B.3. Security Service send( ) Collaborator interface: 9.3.1. Building the Infrastructure with Message Passing Mediator interface: 9.3.1. Building the Infrastructure with Message Passing MulticastSocket class: 2.1.3. Multicast Sockets RMICollaboratorImpl class (example): 9.3.2. Collaborating with RMI sendEvent( ): 6.6.2. Distributed Events sendMsg( ): 9.3.1. Building the Infrastructure with Message Passing serialization: 3.2.1. Creating Remote Objects 3.6.6. Serializing Objects JavaSpace interface and: C.2. Entry and EntryRep Serializable interface: 1.3.5. Network Support 3.6.6. Serializing Objects servers BankServer interface (example): 3.5.2. The Interface Definition Language (IDL) ChessServer class (example): 6.4. Fixed Protocols 6.4. Fixed Protocols implementation of object classes: 3.3. Features of Distributed Object Systems java.rmi.server package: D.3. The java.rmi.server Package object skeleton: 3.3. Features of Distributed Object Systems IDL interface and: 3.5.3. Server Implementations 3.5.5.3. The server skeleton and implementation Java RMI and: 3.6.4. Client Stubs and Server Skeletons PipedServer class (example): 2.1.4. Streams, Readers, and Writers for Input and Output registration/naming service: 3.3. Features of Distributed Object Systems 3.3.3. Registration/Naming Service CORBA and: 3.5.3. Server Implementations 3.5.5.5. Pulling it all together remote database data servers: 7.2.6. Remote Data Servers RemoteServer class: 3.6.2. Server Implementations D.3. The java.rmi.server Package RMI implementation: 3.6.2. Server Implementations RunnableSolveServer class (example): 4.2.1. Implementing Runnable ServerCloneException: D.3. The java.rmi.server Package ServerError: D.1. The java.rmi Package ServerException: D.1. The java.rmi Package ServerNotActiveException: D.3. The java.rmi.server Package ServerRef interface: D.3. The java.rmi.server Package ServerRuntimeException: D.1. The java.rmi Package ServerSocket class: 2.1.2. Your Basic Socket SimpleServer class (example): 1.3.5. Network Support setAutoCommit( ): 7.1.2.3. Statement setDefaultStream( ): D.3. The java.rmi.server Package setLog( ): D.3. The java.rmi.server Package setOutputStream( ): D.3. The java.rmi.server Package setPrincipal( ): 5.3.1. Access Control Lists setRef( ): D.3. The java.rmi.server Package shared data, collaboration and: 9.2.3. Shared State Information shared whiteboard (example): 9.2.2. Maintaining Agent Identities 10.2. A Shared Whiteboard sharing, systems of (see collaborative systems) sign( ): 5.5.2. Public Key Signatures for Authentication signatures digital: 5.2.2. The Core Security API 5.5. Digital Signatures DSA (Digital Signature Algorithm): 5.2.1.1. The User API 5.7.2.1. Encryption techniques public key: 5.5.2. Public Key Signatures for Authentication Signature class: 5.5.2. Public Key Signatures for Authentication SimpleAgent client (example): 5.2.2. The Core Security API certification and: 5.5.1. A Motivating Example: A Credit Agent SimpleClient class (example): 1.3.5. Network Support SimpleCmd class (example): 1.3.5. Network Support SimpleCmdInputStream class (example): 1.3.5. Network Support SimpleServer class (example): 1.3.5. Network Support skeleton, server: 3.3. Features of Distributed Object Systems IDL interface and: 3.5.3. Server Implementations Solver interface (example): 3.5.5.3. The server skeleton and implementation Java RMI and: 3.6.4. Client Stubs and Server Skeletons Skeleton class: D.3. The java.rmi.server Package SkeletonMismatchException: D.3. The java.rmi.server Package SkeletonNotFoundException: D.3. The java.rmi.server Package sockets: 2.1.2. Your Basic Socket DatagramSocket class: 2.1.2. Your Basic Socket multicast: 2.1.3. Multicast Sockets Socket class: 2.1.2. Your Basic Socket SocketSecurityException: D.3. The java.rmi.server Package Solver interface (example): 3.4. Distributed Object Schemes for Java in CORBA environment: 3.5.5. A CORBA Solver Runnable interface with: 4.2.1. Implementing Runnable using Java RMI: 3.6.7. An RMI Solver sophistication of cryptographic algorithms: 5.7.1.2. Sophistication and complexity source code, obtaining: 0.3. About the Source Code speed (see performance) SQL (see databases) SSL (Secure Socket Layer): 5.7.3.1. Secure Socket Layer (SSL) standards for distributed computing: 0. Preface start( ): 4.3.2. Thread Groups state information, sharing: 9.2.3. Shared State Information Statement class: 7.1.1. Data Retrieval Example 7.1.2.3. Statement StreamClassLoader class (example): 2.3.1. Loading Classes from the Network streaming audio example: 8.5.1. Streaming Multimedia streams: 2.1.4. Streams, Readers, and Writers for Input and Output StringBufferInputStream class: 2.1.4. Streams, Readers, and Writers for Input and Output StringReader class: 2.1.4. Streams, Readers, and Writers for Input and Output StringWriter class: 2.1.4. Streams, Readers, and Writers for Input and Output stub, client: 3.3. Features of Distributed Object Systems IDL interface and: 3.5.4. Client Stubs Solver base interface (example): 3.5.5.2. The client stubs Java RMI and: 3.6.4. Client Stubs and Server Skeletons to remote data objects: 7.2.6.2. Distributed objects from the data server StubNotFoundException: D.1. The java.rmi Package sun.security.acl package: 5.3.1. Access Control Lists SupplierAdmin interface: B.2.2. Interface Specifics SurrogateActionListener interface (example): 6.6.3. Pros and Cons suspend( ): 4.4.2. Distributed ThreadGroups symmetric encryption techniques: 5.6.1. Ciphers for Secure Data Transfers synchronization of threads: 4.3.1. Synchronizing Threads 4.4.4. Synchronizing Distributed Threads synchronized statement: 4.3.1. Synchronizing Threads synchronous message handling: 6.3.1. Asychronous vs. Synchronous Message Handling system performance (see performance) Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved. Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Index: T take( ): C.4.3. take( ) TCP (Transport Control Protocol): 2.1.2. Your Basic Socket threads: 1.1. Anatomy of a Distributed Application 4. Threads asynchronous agents: 4.4.1. Asynchronous Agents creating: 4.2. Making a Thread distributed ThreadGroups: 4.4.2. Distributed ThreadGroups groups of: 4.3.2. Thread Groups 4.4.2. Distributed ThreadGroups I/O between: 2.1.4. Streams, Readers, and Writers for Input and Output Java's multithreading support: 1.3.7. Multithreading Support managing: 4.3. Managing Threads at Runtime multithreading requirements: 1.2.3. Multithreading Requirements networked: 4.4. Networked Threads priorities for: 4.3.3. Priorities 4.4.3. Improving Efficiency with Thread Priorities synchronizing: 4.3.1. Synchronizing Threads 4.4.4. Synchronizing Distributed Threads TheadGroup class distributed ThreadGroups: 4.4.2. Distributed ThreadGroups Thread class: 1.3.7. Multithreading Support 4.1. Thread and Runnable extending (example): 4.2.2. Extending Thread ThreadedWhiteboardUser class (example): 10.2.1. Problems with the First Version ThreadGroup class: 4.3.2. Thread Groups ThreadSolver class (example): 4.2.2. Extending Thread throughput monitoring raw data: 8.4.1. Raw Data Monitoring real data: 8.4.2. Real Data Monitoring Throwable interface: 1.3.4. Fault Tolerance Through Exception Handling TimeConstraint class (example): 7.2.4. JDBC-Enabled Data Objects 7.2.4. JDBC-Enabled Data Objects tokens: 6.3.2. A Basic Message Processor toString( ) LogStream class: D.3. The java.rmi.server Package ObjID class: D.3. The java.rmi.server Package Operation class: D.3. The java.rmi.server Package RemoteObject class: D.3. The java.rmi.server Package UID class: D.3. The java.rmi.server Package Transaction class (JavaSpaces): C.3. Transactions transaction service (CORBA): B.4. Other Key CORBA Services transactions, JavaSpace: C.1. Overview of JavaSpaces transactions, remote: 1.3.6.2. Secure remote transactions transceivers, event: 6.6.2. Distributed Events Transport Control Protocol (TCP): 2.1.2. Your Basic Socket try/catch/finally statements: 1.3.4. Fault Tolerance Through Exception Handling two-way agent authentication: 5.7.1.3. One-, two-, and many-way cryptography Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved. Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Index: U UDP (Unreliable Datagram Protocol): 2.1.2. Your Basic Socket UID class: D.3. The java.rmi.server Package unbind( ) Naming interface: D.1. The java.rmi Package Remote interface: D.2. The java.rmi.registry Package UnexpectedException: D.1. The java.rmi Package UnicastRemoteObject class: 3.6.2. Server Implementations D.3. The java.rmi.server Package Uniform Resource Locators (see URLs) UnknownHostException: D.1. The java.rmi Package UnmarshalException: D.1. The java.rmi Package unreferenced( ): D.3. The java.rmi.server Package Unreferenced interface: D.3. The java.rmi.server Package Unreliable Datagram Protocol (UDP): 2.1.2. Your Basic Socket UnusableEntryException: C.2. Entry and EntryRep update( ): 5.5.2. Public Key Signatures for Authentication updateFromDbase( ): 7.2.4. JDBC-Enabled Data Objects 7.2.4. JDBC-Enabled Data Objects 7.3. Multi-Database Applications updateToDbase( ): 7.2.4. JDBC-Enabled Data Objects 7.3. Multi-Database Applications URLs (Uniform Resource Locators): 2.2. URLs, URLConnections, and ContentHandlers loading classes from (example): 2.3.1. Loading Classes from the Network URL class: 2.2. URLs, URLConnections, and ContentHandlers URLClassLoader class (example): 2.3.1. Loading Classes from the Network URLConnection class: 2.2. URLs, URLConnections, and ContentHandlers user API (java.security): 5.2.1.1. The User API user authentication (see authentication) Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved. Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Index: V verify( ): 5.5.2. Public Key Signatures for Authentication verifying agent identity: 5.1. Security Issues and Concerns 5.5.5. Distributing Certified Public Keys digital signatures: 5.5.2. Public Key Signatures for Authentication incoming objects: 5.1. Security Issues and Concerns visiting agents: 5.1. Security Issues and Concerns Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved. Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Index: W web browser example: 8.5.2. Web Browsing whiteboard example: A.1. Whiteboard Applet mouse events and: 10.2. A Shared Whiteboard shared: 9.2.2. Maintaining Agent Identities 10.2. A Shared Whiteboard WhiteboardApplet class (example): A.1. Whiteboard Applet WhiteboardMediator class (example): 10.2.2.1. List of current users WhiteboardUser class (example): 10.2. A Shared Whiteboard workload distribution: 3.2.3. Other Issues write( ) JavaSpace interface: C.4.1. write( ) LogStream class: D.3. The java.rmi.server Package ObjID class: D.3. The java.rmi.server Package UID class: D.3. The java.rmi.server Package writeArgs( ): 6.4.1. Heterogeneous Argument Lists Writer classes: 2.1.4. Streams, Readers, and Writers for Input and Output Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved. Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Index: X X.509 standard certificate format: 5.7.2.2. Certificates and authentication techniques XDR-formatted data I/O (example): 2.1.4. Streams, Readers, and Writers for Input and Output Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved. Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Index: Y There are no index entries for this letter. Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved. Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Index: Z Zimmerman, Phil: 5.7.3.2. Pretty Good Privacy (PGP) Symbols | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z Copyright © 2001 O'Reilly & Associates, Inc. All Rights Reserved. Search Product List Press Room Jobs Resource Centers Perl Java Web & Internet Open Source XML Linux Unix Python Macintosh Windows .NET Oracle Security Sys/Network Admin C/C++ Programming Design & Graphics Visual Basic Special Interest Ask Tim Frankly Speaking Ron's VB Forum Beta Chapters Letters elists Events Palm OS Missing Manual User Groups Table of Contents Index Examples Sample Chapter Author Interview JDC Online Seminar source Errata Colophon Media Reviews Reader Reviews Register Your Book Join Email List How to Order Java Distributed Computing By Jim Farley January 1998 1-56592-206-9, Order Number: 2069 382 pages, $34.95 US $51.95 CA £24.95 UK Add to Shopping Cart View Shopping Cart Read Online--Safari Java Distributed Computing offers a general introduction to distributed computing, meaning programs that run on two or more systems. It focuses primarily on how to structure and write distributed applications and discusses issues like designing protocols, security, working with databases, and dealing with low bandwidth situations. [Full Description] Related O'Reilly Titles: Developing Java Beans Java Examples in a Nutshell, 2nd Edition Java Cryptography Java Threads, 2nd Edition Java Servlet Programming, 2nd Edition Java in a Nutshell, 3rd Edition Java Security, 2nd Edition Learning Java oreilly.com Home | O'Reilly Bookstores | How to Order O'Reilly Contacts International |About O'Reilly | Affiliated Companies | Privacy Policy © 2001, O'Reilly & Associates, Inc. webmaster@oreilly.com Catalog Request Specials Write for Us
还剩132页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 20 金币 [ 分享pdf获得金币 ] 0 人已下载

下载pdf

pdf贡献者

sonicthink

贡献于2011-08-21

下载需要 20 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf