Você está na página 1de 68

Practical Workbook

Introduction to Distributed Systems

Name

: ________________________

Year

: ________________________

Batch

: ________________________

Roll No

: ________________________

Department: ________________________

1st Edition 2013

Department of Computer & Information Systems Engineering


NED University of Engineering & Technology,
Karachi 75270, Pakistan

INTRODUCTION
Introduction to Distributed Systems is a very important course offered in final year of
engineering. In an age of ever increasing information collection and the need to evaluate it,
building systems which utilize the available compute resources in everyones home and
hands should be driving the development of more sophisticated distributed computing
systems. Learning about this area of engineering is the need of the day.

The first and second lab sessions discuss Linux local sockets and Linux sockets over network
respectively in detail. In this way, students are familiarized with another classical inter
process communication mechanism. All the Linux system calls with the complete
implementation of client side & server side algorithms are discussed in first two lab sessions.

Lab Session three, four & five introduces XML. XML's set of tools allows developers to
create web pages, allow developers to set standards defining the information that should
appear in a document, it makes it possible to define the content of a document separately from
its formatting, making it easy to reuse that content in other applications or for other
presentation environments. XML is an international standard and its beneficial to learn it.

In lab session six, programming in java is introduced. In lab session seven and eight Java
Remote Method Invocation (RMI) is discussed. This is a brief introduction to Java Remote
Method Invocation (RMI). Java RMI is a mechanism that allows one to invoke a method on
an object that exists in another address space (either on same or different machine).

Lab session nine discusses indirect communication mechanism with group communication. It
covers complete programming model and implementation issues. It also covers basics of
JGroup toolkit. Lab session ten deals with implementing & using message queues using Java
messaging service (JMS). It covers programming details with JMS including the
implementation (with installation and execution steps) of standard JMS specification,
OpenJMS.

CONTENTS
Lab Session No.

Object

PageNo

Socket programming in Linux local sockets

Socket programming in Linux over the network

Getting acquainted with XML

16

Understanding and creating DTD in XML

20

Understanding the concept of root elements and attributes in XML

28

Introduction to Java Programming

34

Creating a distributed version of the classic Hello World program using Java
Remote Method Invocation (RMI) (Part 1)

38

Creating a distributed version of the classic Hello World program using Java
Remote Method Invocation (RMI) (Part 2)

46

Understanding the concept of Indirect Communication and exploring group


communication mechanism via JGroup Toolkit.

51

10

Understanding the concept of message queues via Java Messaging Service


(JMS)

57

Introduction to Distributed Systems

___

Lab Session 01

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

Lab Session 01
OBJECT
Socket programming in Linux local sockets

THEORY
A socket is a bidirectional communication device that can be used to communicate with
another process on the same machine or with a process running on other machines.
System calls for sockets
Theseare the system calls involving sockets:
a) socketCreates a socket
#include <sys/socket.h>
sockfd = socket(int protocol_family, int socket_type, int
protocol);
The protocol modules are grouped into protocol families like AF_INET, AF_IPX,
AF_PACKET and socket types like SOCK_STREAM or SOCK_DGRAM.
Protocol Families
Name
Purpose
AF_UNIX, AF_LOCAL Local communication
AF_INET
IPv4 Internet protocols
AF_INET6
IPv6 Internet protocols

SOCK_STREAM provides sequenced, reliable, two-way, connection-based byte streams. An


out-of-band data transmission mechanism may be supported. SOCK_DGRAM supports
datagrams (connectionless, unreliable messages of a fixed maximum length).
The protocol specifies a particular protocol to be used with the socket. Normally only a single
protocol exists to support a particular socket type within a given protocol family, in which
case protocol can be specified as 0. However, it is possible that many protocols may exist, in
which case a particular protocol must be specified in this manner.
On success, a file descriptor for the new socket is returned. On error, -1 is returned, and errno
is set appropriately.
b) closeDestroys a socket
#include <unistd.h>
int close(intfd);
close() closes a file descriptor, so that it no longer refers to any file and may be reused.
close() returns zero on success. On error, -1 is returned, and errno is set appropriately.

Introduction to Distributed Systems

___

Lab Session 01

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

c) connectCreates a connection between two sockets


#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr, socklen_t
addrlen);
The connect() system call connects the socket referred to by the file descriptor sockfd to the
address specified by addr. The addrlen argument specifies the size of addr. The format of the
address in addr is determined by the address space of the socket sockfd.
The sockaddr structure is the basic structure for all system calls and functions that deal with
socket addresses. All pointers to other socket address structures are often cast to pointers to
sockaddr before use in various functions and system calls:
#include <netinet/in.h>
struct sockaddr {
unsigned short sa_family;
// address family, AF_xxx
char sa_data[14];
// 14 bytes of protocol address
};
The Unix domain socket address structure is:
#include <sys/un.h>
struct sockaddr_un{
short sun_family;
//AF_UNIX
char sun_PATH[108]; // path name
};
If the socket sockfd is of type SOCK_DGRAM then addr is the address to which datagrams
are sent by default, and the only address from which datagrams are received. If the socket is
of type SOCK_STREAM, this call attempts to make a connection to the socket that is bound
to the address specified by addr. Generally, connection-based protocol sockets may
successfully connect() only once; connectionless protocol sockets may use connect() multiple
times to change their association.
If the connection or binding succeeds, zero is returned. On error, -1 is returned, and errno is
set appropriately.
d) bindLabels a socket with an address
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t
addrlen);
When a socket is created with socket(), it exists in a name space (address family) but has no
address assigned to it. bind() assigns the address specified to by addr to the socket referred to
by the file descriptor sockfd. addrlen specifies the size, in bytes, of the address structure
pointed to by addr. Traditionally, this operation is called "assigning a name to a socket". It is
normally necessary to assign a local address using bind() before a SOCK_STREAM socket
may receive connections.
On success, zero is returned. On error, -1 is returned, and errno is set appropriately.

Introduction to Distributed Systems

___

Lab Session 01

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

e) listenConfigures a socket to accept conditions


#include <sys/socket.h>
int listen(int sockfd, int backlog);
listen() marks the socket referred to by sockfd as a passive socket, that is, as a socket that will
be used to accept incoming connection requests using accept(). The backlog argument defines
the maximum length to which the queue of pending connections for sockfd may grow. If a
connection request arrives when the queue is full, the client may receive an error with an
indication of ECONNREFUSED or, if the underlying protocol supports retransmission, the
request may be ignored so that a later reattempt at connection succeeds.
On success, zero is returned. On error, -1 is returned, and errno is set appropriately.
f) acceptAccepts a connection and creates a new socket for the connection
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t
*addrlen);
The accept() system call is used with connection-based socket types (SOCK_STREAM). It
extracts the first connection request on the queue of pending connections for the listening
socket, sockfd, creates a new connected socket, and returns a new file descriptor referring to
that socket. The newly created socket is not in the listening state. The original socket sockfd is
unaffected by this call. The argument addr is a pointer to a sockaddr structure. This structure
is filled in with the address of the peer socket, as known to the communications layer. When
addr is NULL, nothing is filled in; in this case, addrlen is not used, and should also be NULL.
The addrlen argument is a value-result argument: the caller must initialize it to contain the
size (in bytes) of the structure pointed to by addr; on return it will contain the actual size of
the peer address. The returned address is truncated if the buffer provided is too small; in this
case, addrlen will return a value greater than was supplied to the call.
If no pending connections are present on the queue, and the socket is not marked as nonblocking, accept() blocks the caller until a connection is present. If the socket is marked nonblocking and no pending connections are present on the queue, accept() fails with the error
EAGAIN or EWOULDBLOCK. In order to be notified of incoming connections on a socket,
you can use select() or poll(). A readable event will be delivered when a new connection is
attempted and you may then call accept() to get a socket for that connection.
On success, this returns a nonnegative integer that is a descriptor for the accepted socket. On
error, -1 is returned, and errno is set appropriately.
Making a server
The steps involved in establishing a socket on the server side are as follows:
1. Create a socket with the socket() system call.
2. Bind the socket to an address using the bind() system call. For a server socket on the
Internet, an address consists of a port number on the host machine.
3. Listen for connections with the listen() system call.
4. Accept a connection with the accept() system call. This call typically blocks until a client
connects with the server.

Introduction to Distributed Systems

___

Lab Session 01

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

5. Send and receive data.


Data isnt read and written directly via the server socket; instead, each time a program accepts anew
connection, Linux creates a separate socket to use in transferring data over that connection.

Making a client
The steps involved in establishing a socket on the client side are as follows:
1. Create a socket with the socket() system call.
2. Connect the socket to the address of the server using the connect() system call.
3. Send and receive data. There are a number of ways to do this, but the simplest is to use the
read() and write() system calls.
Local Sockets
Sockets connecting processes on the same computer can use the local namespace represented by the
synonyms AF_LOCAL and AF_UNIX. These are called local sockets or UNIX-domain sockets. Their
socket addresses, specified by filenames, are used only when creating connections.
The sockets name is specified in struct sockaddr_un. We must set the sun_family field to
AF_LOCAL, indicating that this is a local namespace.
The sun_path field specifies the filename to use and may be, at most, 108 bytes long. Any filename
can be used, but the process must have directory write permissions, which permit adding files to the
directory. To connect to a socket, a process must have read permission for the file. Even though
different computers may share the same file system, only processes running on the same computer can
communicate with local namespace sockets.
The only permissible protocol for the local namespace is 0.Because it resides in a file system, a local
socket is listed as a file.

Compilation and Execution


Use the following format for compiling the codes:
gcc sourcefile.c o outputfile
As a result you should get two output files. Run the output files in two separate terminals,
making sure you pass the socket filename as argument to the Unix server at the command
line.

CODING
un_server.c
//The pathname of the socket address is passed as an argument.
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/un.h>
#include <stdio.h>

Introduction to Distributed Systems

___

Lab Session 01

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

void error(const char *)


{
perror(msg);
exit(0);
}
int main(intargc, char *argv[])
{
int sockfd, newsockfd, servlen, n;
socklen_t clilen;
struct sockaddr_un cli_addr, serv_addr;
char buf[80];
if ((sockfd = socket(AF_UNIX,SOCK_STREAM,0)) < 0)
error("creating socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sun_family = AF_UNIX;
strcpy(serv_addr.sun_path, argv[1]);
servlen=strlen(serv_addr.sun_path)
+
sizeof(serv_addr.sun_family);
if(bind(sockfd,(struct sockaddr *)&serv_addr, servlen)<0)
error("binding socket");
listen(sockfd,5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd,(struct sockaddr)&cli_addr,&clilen);
if (newsockfd< 0)
error("accepting");
n=read(newsockfd,buf,80);
printf("A connection has been established\n");
write(1,buf,n);
write(newsockfd,"I got your message\n",19);
close(newsockfd);
close(sockfd);
return 0;
}
un_client.c
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
void error(const char *)
{
perror(msg);
exit(0);
}
int main(intargc, char *argv[])
{
int sockfd, servlen,n;

Introduction to Distributed Systems

___

Lab Session 01

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

struct sockaddr_un serv_addr;


char buffer[82];
bzero((char *)&serv_addr,sizeof(serv_addr));
serv_addr.sun_family = AF_UNIX;
strcpy(serv_addr.sun_path, argv[1]);
servlen = strlen(serv_addr.sun_path) +
sizeof(serv_addr.sun_family);
if ((sockfd = socket(AF_UNIX, SOCK_STREAM,0)) < 0)
error("Creating socket");
if (connect(sockfd, (struct sockaddr*)&serv_addr, servlen)< 0)
error("Connecting");
printf("Please enter your message: ");
bzero(buffer,82);
fgets(buffer,80,stdin);
write(sockfd,buffer,strlen(buffer));
n=read(sockfd,buffer,80);
printf("The return message was\n");
write(1,buffer,n);
close(sockfd);
return 0;
}

EXERCISES
a. Implement the above server and client on your Linux machine and write at least two
sample inputs and outputs.

Introduction to Distributed Systems

___

Lab Session 01

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

b. List three other mechanisms of inter process communication that are implemented in
Linux, and explain how they work.

c. What does 1 represent in the line write(1,buffer,n)? What would 0 or 2 represent


in the same place?

d. Explain the following:


i. void perror(const char *s);
ii. void bzero(void *s, size_t n);
iii. ssize_t read(intfd, void *buf, size_t count);
iv.
ssize_t write(intfd, const void *buf, size_t count);
v. socklen_t

Introduction to Distributed Systems

___

Lab Session 01

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

Introduction to Distributed Systems

___

Lab Session 02

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

Lab Session 02
OBJECT
Socket programming in Linux over the network

THEORY
A socket is a bidirectional communication device that can be used to communicate with
another process on the same machine or with a process running on other machines. Internet
programs such as Telnet, rlogin, FTP, talk, and the World Wide Web use sockets.
For example, you can obtain the WWW page from a Web server using the Telnet program
because they both use sockets for network communications. To open a connection to a WWW
server at www.codesourcery.com, use telnet www.codesourcery.com 80.The magic constant
80 specifies a connection to the Web server programming running www.codesourcery.com
instead of some other process. Try typing GET /after the connection is established. This sends
a message through the socket to the Web server, which replies by sending the homepages
HTML source and then closing the connectionfor example:
% telnet www.codesourcery.com 80
Connected to merlin.codesourcery.com (206.168.99.1).
Escape character is ^].
GET /
<html>
<head>
<meta http-equiv=Content-Type content=text/html;
charset=iso-8859-1>
...
Here, we focus on sockets set up over a network, enabling communication between two
different machines. The protocol families for such sockets are AF_INET and AF_INET6.
The socket address structure for IPv4 sockets is:
Struct sockaddr_in {
Short sin_family;
// e.g. AF_INET, AF_INET6
unsigned short sin_port; // e.g. htons(3490)
struct in_addr sin_addr; // see structin_addr, below
char sin_zero[8];
// zero this if you want to
};
struct in_addr {
unsigned long s_addr;
// load with inet_pton()
};
The socket address structure for IPv6 sockets is:
struct sockaddr_in6 {
u_int16_t sin6_family;
// AF_INET6
u_int16_t sin6_port;
// port number, Network Byte Order
u_int32_t sin6_flowinfo;
// IPv6 flow information

Introduction to Distributed Systems

___

Lab Session 02

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

struct in6_addr sin6_addr;


u_int32_t sin6_scope_id;
};
struct in6_addr {
unsigned char s6_addr[16];
};

// IPv6 address
// Scope ID

// load with inet_pton()

Pointers to both the above structures have to be type casted to sockaddr structure pointers.
The sockaddr structure has already been described in the previous lab dealing with local
sockets.
A function that requires mention is:
#include <netdb.h>
struct hostent *gethostbyname(const char *name);
The gethostbyname() function returns a structure of type hostent for the given host name.
Here name is either a hostname, or an IPv4 address in standard dot notation, or an IPv6
address in colon (and possibly dot) notation. The hostent structure is defined as follows:
struct hostent {
char *h_name;
//official name of host
char **h_aliases;
//alias list
int h_addrtype;
//host address type
int h_length;
//length of address
char **h_addr_list;
//list of addresses
}
#define h_addr h_addr_list[0] //for backward compatibility
Another function that you may use is:
#include <netinet/in.h>
uint16_t htons(uint16_t hostshort);
The htons() function converts the unsigned short integer hostshort from host byte order to
network byte order.
Compilation and execution shall be done on two separate machines.

ALGORITHMS
Algorithm A1: Setting up a simple server in the internet domain using TCP
The port number is passed as an argument at the command line.
1. If the port number has not been passed as argument by the user, report missing port
number and exit.
2. Create a stream socket of AF_INET family with TCP protocol.
3. Initialize structure serv_addr, of type sockaddr_in, to zero.
4. Prepare the elements of serv_addr in the following manner:
a. Assign AF_INET to sin_family.
b. Convert the port number from ascii to integer.
c. Use htons(port_no) to fill in sin_port.

10

Introduction to Distributed Systems

___

Lab Session 02

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

d. Assign INADDR_ANY to s_addr in sin_addr structure in serv_addr.


5. Bind the socket with the serv_addr structure.
6. Listen for connections to this socket.
7. Accept a connection to this socket. (A new socket will be established)
8. Initialize an array buffer of adequate size to zero.
9. Read from the new socket into the buffer array, and display its contents.
10. Write to the new socket: I got your message.
11. Close the new socket.
12. Close the original listening socket.
Algorithm A2: Setting up a simple client in the internet domain using TCP
The servers hostname and server port number are passed as arguments at the command line.
1. If the servers hostname has not been passed as argument by the user, report missing
hostname and exit.
2. If the port number has not been passed as argument by the user, report missing port
number and exit.
3. Create a stream socket of AF_INET family with TCP protocol.
4. Initialize structure serv_addr, of type sockaddr_in, to zero.
5. Prepare the elements of serv_addr in the following manner:
a. Assign AF_INET to sin_family.
b. Convert the port number from ascii to integer. Use htons(port_no) to fill in sin_port.
c. Use gethostbyname(server_hostname) to get a hostent structure for the server.
d. Copy the servers address from the h_addr element of the hostent structure returned to
s_addr in sin_addr structure in serv_addr.
6. Connect to the server using the serv_addr structure and the socket established in step 3.
7. Initialize an array buffer of adequate size to zero.
8. Prompt the user for input.
9. Store the users input in the buffer array.
10. Write the buffer array to the socket.
11. Reinitialize the array buffer to zero.
12. Read from the socket into the buffer array, and display its contents.
13. Close the socket.

EXERCISES
a. Implement the given server algorithm in C for your Linux machine.

11

Introduction to Distributed Systems

___

Lab Session 02

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

12

Introduction to Distributed Systems

___

Lab Session 02

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

b. Implement the given client algorithm in C for your Linux machine.

13

Introduction to Distributed Systems

___

Lab Session 02

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

c. Why do we assign INADDR_ANY to s_addr in sin_addr structure in serv_addr?

d. Implement the given server and client algorithms in C for your Linux machine, changing
them such that:
Datagram connections are formed using UDP,
The server keeps accepting client connections and never closes the socket.

14

Introduction to Distributed Systems

___

Lab Session 02

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

15

Introduction to Distributed Computer Systems

Lab Session 03

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

Lab Session 03
OBJECTIVE
Getting acquainted with XML

THEORY
XML was released in the late 90's and has since received a great amount of hype. The XML
standard was created by W3C to provide an easy to use and standardized way to store selfdescribing data (self-describing data is data that describes both its content and its structure).
XML is nothing by itself. XML is more of a "common ground" standard. The main benefit of
XML is that you can use it to take data from a program like Microsoft SQL, convert it into XML,
and then share that XML with a slough of other programs and platforms. Each of these receiving
platforms can then convert the XML into a structure the platform uses normally.
What makes XML truly powerful is the international acceptance it has received. Many
individuals and corporations have put forth their hard work to make XML interfaces for
databases, programming, office application, mobile phones and more. It is because of this hard
work that the tools exist to do these conversions from whatever platform into standardized XML
data or convert XML into a format used by that platform.
In the past, attempts at creating a standardized format for data that could be interpreted by many
different platforms (or applications) failed miserably. XML has largely succeeded in doing this.
Before continuing you should have a basic understanding of the following:
HTML
JavaScript
Applications of XML
Although there are countless numbers of applications that use XML, here are a few examples of
the current platforms and applications that are making use of this technology:

Cell Phones - XML data is sent to some cell phones. The data is then formatted by the
specification of the cell phone software designer to display text or images, and even to play
sounds!
File Converters - Many applications have been written to convert existing documents into the
XML standard. An example is a PDF to XML converter.
VoiceXML - Converts XML documents into an audio format so that you can listen to an
XML document.

If you are attempting to use XML for the first time, chances are you don't know or have the tools
that are necessary to view XML files. The good news is there are surpluses of free viewers
readily available to you. Chances are the web browser you have on your computer is XML ready,
so you need not bother.

16

Introduction to Distributed Computer Systems

Lab Session 03

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

If you have already programmed in HTML, XML syntax shouldn't be that much of a leap to
grasp. While there are a couple of new items in XML, it is still just a markup language that relies
on tags to get the job done.
For example, this XML document was used to keep track of students in a Computer Application's
Course.
XML Code:
<?xml version="1.0" encoding="ISO-8859-15"?>
<class_list>
<student>
<name>Robert</name>
<grade>A+</grade>
</student>
<student>
<name>Lenard</name>
<grade>A-</grade>
</student>
</class_list>
If you spend a few moments reading through the above XML document, you can see it has two
students, Robert and Lenard. This simple XML document readily displays the benefits of XML.
The data seems to almost describe itself, which is one of the main reasons XML was created!
Lets take a look at XML syntax by looking at the different parts of above example.
I think the only thing not easily understandable in above XML document example is that first
line with all the symbols and attributes. This rather confusing line in above example is referred to
as the XML Prolog.
XML Prolog
The prolog is an optional component of the XML document. If included, the prolog must
appear before the root element. A prolog consists of two parts: the XML declaration and the Document
Type Declaration (DTD). Depending on your needs, you can choose to include both, either, or neither of
these items in your XML document.
The Document Type Declaration is a file that contains the necessary rules that the XML code in this file
must follow. You may think of the DTD as the grammar that the XML document must abide by to be a
valid XML file. This is where you define what version of XML you are using. The current version is 1.0,
which it has been for quite some time now.
Note: DTD will be discussed in detail in upcoming lab sessions.

<?xml version="1.0" encoding="ISO-8859-15"?>


This line with special symbols and attributes is what is referred to as the XML declaration. It
simply states what version of XML you are using and the type of encoding you are using. Don't
worry too much about this line; just always include it exactly as we have done above.

17

Introduction to Distributed Computer Systems

Lab Session 03

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

XML Tag
The XML tag is very similar to that of the HTML tag. Each element is marked with an opening
tag and a closing tag. Below, we have highlighted both the opening and closing tags from a piece
of our example XML file.
<name>Robert</name>
<grade>A+</grade>
XML Elements
XML Elements are the meat and potatoes of XML. They contain the opening and closing tags,
child elements, and data. In our XML document the student element comprisesall of the above
information. Notice how it has a couple of child elements.
<student>
<name>Robert</name>
<grade>A+</grade>
</student>
XML Attributes:
Our simple XML document above did not include any XML attribute. Attributes are used to
specify additional information about the element. It may help to think of attributes as a means of
specializing generic elements to fit your needs. An attribute for an element appears within the
opening tag.
If there are multiple values an attribute may have, then the value of the attribute must be
specified. For example, if a tag had a color attribute then the value would be: red, blue, green,
etc.
The syntax for including an attribute in an element is:
<element attributeName="value">
In this example we will be using a made up XML element named "friend" that has an optional
attribute age.
XML Code:
<friend age="23">Jaseem</friend>
Note:
Elements are used to classify data in an XML document so that the data becomes "selfexplanatory".
Opening and closing tags represent the start and end of an element.
Attributes are used to include additional information on top of the data that falls between the
opening and closing tag.

18

Introduction to Distributed Computer Systems

Lab Session 03

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

EXERCISES
a. What does XML stand for?

b. There is a way of describing XML data, how?

c. XMLs goal is to replace HTML, justify.

d. What is the correct syntax of the declaration which defines the XML version?

e. What does DTD stand for?

19

Introduction to Distributed Computer Systems

Lab Session 04

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

Lab Session 04
OBJECTIVE
Understanding and creating DTD in XML

THEORY
XML is a standard, simple, self-describing way of encoding both text and data so that content
can be processed with relatively little human intervention and exchanged across diverse
hardware, operating systems, and applications.
XML offers a widely adopted standard way of representing text and data in a format that can be
processed without much human or machine intelligence. Information formatted in XML can be
exchanged across platforms, languages, and applications, and can be used with a wide range of
development tools and utilities.
XML is similar enough to HTML in its actual format (both are closely related to the SGML
markup definition language that has been an ISO standard since 1986) so that those familiar with
HTML can fairly easily pick up basic XML knowledge. But there are two fundamental
differences:

Separation of form and content -- HTML mostly consists of tags defining the appearance
of text; in XML the tags generally define the structure and content of the data, with actual
appearance specified by a specific application or an associated style sheet.
XML is extensible -- tags can be defined by individuals or organizations for some
specific application, whereas the HTML standard tag set is defined by the World Wide
Web Consortium (W3C).

There are two types of XML documents: well-formed or valid. The only difference between the
two is that one uses a DTD and the other doesn't.
Well-formed XML:
Well-formed documents conform with XML syntax. They contain text and XML tags.
Everything is entered correctly. They do not, however, refer to a DTD.
Valid XML:
Valid documents not only conform to XML syntax but they also are error checked against a
Document Type Definition (DTD). A DTD, as defined in previous lab, is a set of rules outlining
which tags are allowed, what values those tags may contain, and how the tags relate to each
other.
Typically, you'll use a valid document when you have documents that require error checking, that
use an enforced structure, or are part of a company- or industry-wide environment in which many
documents need to follow the same guidelines.
DTD:
A Document Type Definition (DTD) is a set of rules that defines the elements, element attribute
and attribute values, and the relationship between elements in a document.
20

Introduction to Distributed Computer Systems

Lab Session 04

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

When your XML document is processed, it is compared to its associated DTD to be sure it is
structured correctly and all tags are used in the proper manner. This comparison process is called
validation and is performed by a tool called a parser.
Note: you don't need to have a DTD to create an XML document; you only need a DTD for a
valid XML document.
Here are a few reasons you'd want to use a DTD:
Your document is part of a larger document set and you want to ensure that the whole set
follows the same rules.
Your document must contain a specific set of data and you want to ensure that all
required data has been included.
Your document is used across your industry and need to match other industry-specific
documents.
You want to be able to error check your document for accuracy of tag use.
Deciding on a DTD
Using a DTD doesn't necessarily mean you have to create one from scratch. There are a number
of existing DTDs, with more being added every day.
Shared DTDs
As XML becomes wide-spread, your industry association or company is likely to have one or
more published DTDs that you can use and link to. These DTDs define tags for elements that are
commonly used in your applications. You don't need to recreate these DTDs -- you just point to
them in your doctype tag in your XML file, and follow their rules when you create your XML
document.
Some of these DTDs may be public DTDs, like the HTML DTD. Others may belong to your
company. If you are interested in using a DTD, ask around and see if there is a good match that
already exists.
Create Your Own DTD
Another option is to create your own DTD. The DTD can be very simple and basic or it can be
large and complex. The DTD will be a reflection of the needs of your document.
It is perfectly acceptable to have a DTD with just four or five basic elements if that is what your
document needs. Don't feel that creating a DTD necessarily needs to be a huge undertaking.
However, if your documents are complex, do plan on setting aside time -- several days or several
weeks -- to understand the document and the document elements and create a solid DTD that will
really work for you over time.
Make an Internal DTD
You can insert DTD data within your DOCTYPE definition. If you're worked with CSS styles,
you can think of this as being a little like putting style data into your file header. DTDs inserted
this way are used in that specific XML document. This might be the approach to take if you want
to validate the use of a small number of tags in a single document or to make elements that will
be used only for one document.
Remember, the primary use for a DTD is to validate that the tags you enter in your XML
document are entered as specified in the DTD. It is an error-checking process that ensures your
data conforms to a set of rules.

21

Introduction to Distributed Computer Systems

Lab Session 04

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

Going back to the types of XML documents:


Well-formed XML
A document that conforms to the XML syntax rules is called "well-formed" if all your tags are
correctly formed and follow XML guidelines then your document is considered a well-formed
XML document. That's one of the nice things about XML - you don't need to have a DTD in
order to use it.
To begin a well-formed document, type the XML declaration:
<?xml version="1.0" standalone="yes" encoding="UTF-8"?>
If you are embedding XML, it will go after the <HTML> and <HEAD> tags, and before any
Javascript.
If you are creating an XML-only document, it will be the first thing in the file.
Version
You must include the version attribute for the XML declaration. The version is currently "1.0."
Defining the version lets the browser know that the document that follows is an XML document,
using XML 1.0 structure and syntax.
Standalone
The next step is to declare that the document "stands alone." The application that is processing
this document knows that it doesn't need to look for a DTD and validate the XML tags.
Encoding
Finally, declare the encoding of the document. In this case, the encoding is UTF-8, which is the
default encoding for XML. You can leave off this attribute and the processor will default to UTF8.
Remember the root element
After the declaration, enter the tag for the root element of your document. This is the top-most
element, under which all elements are grouped.

Valid XML
A valid document conforms to the XML syntax rules and follows the guidelines of a Document
Type Definition (DTD).
The process of comparing the XML document to the DTD is called validation. This process is
performed by a tool called a parser.
To begin a well-formed document, type the XML declaration:
<?xml version="1.0" standalone="no" encode="UTF-8"?>
If you are embedding XML, it will go after the <HTML> and <HEAD> tags, and before any
Javascript.
If you are creating an XML-only document, it will be the first thing in the file.
Version
You must include the version attribute for the XML declaration. The version is currently "1.0."
22

Introduction to Distributed Computer Systems

Lab Session 04

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

Defining the version lets the browser know that the document that follows is an XML document,
using XML 1.0 structure and syntax.
Standalone
The standalone="no" attribute tells the computer that it must look for a DTD and validate the
XML tags.
Encoding
Finally, declare the encoding of the document. You can leave off this attribute and the processor
will default to UTF-8.
To learn XML, open a text editor like SimpleText or Notepad and type:
<?xml version="1.0"?>
<PARENT>
<CHILD>
This is content.
</CHILD>
<EMPTY/>
</PARENT>
Save this as wellform.xml.
Description:
<?xml version="1.0"?> declares your XML is version 1.0, so programs know to use it
like XML 1.0.
<PARENT> is markup. XML is divided into markup and content. Markup is information about
content, describing it to any level of detail desired. Correct markup must follow certain rules.
First, markup containing content must have opening and closing tags. <PARENT> is an opening
tag </PARENT> is a closing tag. Opening tags start with < and close with >. Closing tags start
with </ and close with >.
Second, markup must nest properly. Markup tags divide into parents and children. Parent markup
encloses child markup. A child's opening and closing tags must be contained within its parent's
opening and closing tags.
You can have
<PARENT>
<CHILD>
This is content.
</CHILD>
</PARENT>

<PARENT>
<CHILD>
This is content.
...but not... </PARENT>
</CHILD>

<CHILD>
<PARENT>
This is content.
...or... </CHILD>
</PARENT>

Third, if markup contains no content, it must begin with < and end with /> like <EMPTY/>.
So if you declare your XML version, begin and end opening tags with < and > and closing tags
with </ and > , and insure child markup nests completely within parent markup. Start empty
markup with < and end it with />.
23

Introduction to Distributed Computer Systems

Lab Session 04

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

This XML is well-formed. wellform.xml is the simplest XML possible. If you need more power,
you need valid XML. Using your text editor, type in:
<?xml version="1.0"?>
<!DOCTYPE PARENT [
<!ELEMENT PARENT (CHILD*)>
<!ELEMENT CHILD (MARK?,NAME+)>
<!ELEMENT MARK EMPTY>
<!ELEMENT NAME (LASTNAME+,FIRSTNAME+)*>
<!ELEMENT LASTNAME (#PCDATA)>
<!ELEMENT FIRSTNAME (#PCDATA)>
<!ATTLIST MARK
NUMBER ID #REQUIRED
LISTED CDATA #FIXED "yes"
TYPE (natural|adopted) "natural">
<!ENTITY STATEMENT "This is well-formed XML">
]>
<PARENT>
&STATEMENT;
<CHILD>
<MARK NUMBER="1" LISTED="yes" TYPE="natural"/>
<NAME>
<LASTNAME>child</LASTNAME>
<FIRSTNAME>second</FIRSTNAME>
</NAME>
</CHILD>
</PARENT>
Save it as valid.xml. Valid XML is more complex than the well-formed XML used
in simple.xml
Description:
<?xml version="1.0"?>, fills the same role it did in simple.xml. The second line, <!DOCTYPE
PARENT [, declares this section is a document type definition or DTD and its name
(PARENT).
A DTD is the primary distinction between well-formed and valid XML. Well-formed XML can
give you a vague idea of an XML document's purpose but leaves room for doubt. A DTD
eliminates this by providing a stringent standard to measure a document against.
A DTD declares each part of an XML document and its proper form exactly. This DTD is
named PARENT. DTD's are enclosed between an opening [ and a closing ]>. <!ELEMENT
PARENT (CHILD)*>, shows a DTD's most basic part, the element.
An element defines markup's name and form.
<!ELEMENT PARENT (CHILD*)> declares:
The markup tag's name (PARENT).
The name of any child markup found within it (CHILD).

24

Introduction to Distributed Computer Systems

Lab Session 04

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

How often it and any child markup within it are needed and can appear. (Both are optional
and can appear more than once, as indicated by the *).

The next line, <!ELEMENT CHILD (MARK?,NAME+)>, lists the children of the child
CHILD. It lists:
The element's name (CHILD).
The name of its children (MARK and NAME).
That some of its children appear once or not at all (MARK, as indicated by the ?).
That one of the children must appear one or more times (NAME, as indicated by the +).
You can have
<CHILD>
<NAME>
</NAME>
</CHILD>

Or

<CHILD>
<MARK/>
<NAME>
</NAME>
</CHILD>

but never

<CHILD>
<MARK/>
</CHILD>

<!ELEMENT MARK EMPTY>shows the element value EMPTY. This indicates markup
containing no content like...
<MARK/>
...or...
<EMPTY/>
from simple.xml.
The following line, <!ELEMENT NAME (LASTNAME+,FIRSTNAME+)*>, tells us:
The element name (NAME).
That the children of the element must appear sequentially (as indicated by the comma).
That these choices may be made more than once or not at all (as indicated by the *).
The next two lines contain #PCDATA. #PCDATA indicates when markup contains content.
This can be anything and does not have to follow the same rules as markup.
The following line contains another DTD fundamental, the attribute. An attribute is a description
given to an element to further define it. Attributes are declared in attribute lists. The attribute list
in valid.xml is
<!ATTLIST MARK
NUMBER ID #REQUIRED
LISTED CDATA #FIXED "yes"
TYPE (natural|adopted) "natural">
This tells you:
The element the attribute list is attached to (MARK).
That the first attribute (NUMBER) is unique text (as indicated by ID) and required (as
indicated by #REQUIRED).
That the second attribute (LISTED) is regular text (as indicated by CDATA) and fixed (as
indicated by #FIXED).
That the third attribute (TYPE) is a choice (as indicated by the |) between two values
"natural" and "adopted") and what the default choice is ("natural").
25

Introduction to Distributed Computer Systems

Lab Session 04

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

The result is:


<MARK NUMBER="1" LISTED="yes" TYPE="natural"/> where, of the attributes
of MARK, "1" is required and unique, "yes" is regular text and fixed, and "natural" is the
chosen, default choice.
VALID.XML next brings up a third DTD part, the entity. The entity points to a something that
can be inserted at any point in the XML document. The line <!ENTITY STATEMENT "This is
well-formed XML"> inserts This is well-formed XML whenever &STATEMENT appears.
The DTD then closes with]> and the rest of the XML document follows it as outlined.

EXERCISES
a. Is this a "well formed" XML document?
<?xml version="1.0"?>
<note>
<to>Jaseem</to>
<from>Kashif</from>
<heading>Reminder</heading>
<body>Don't forget to take me to ARENA this weekend!</body>
</note>

b. Is this a "well formed" XML document?


<?xml
<to>Kashif</to>
<from>Jaseem</from>
<heading>Reminder</heading>
<body>Don't forget me for dinner this weekend!</body>

c.

Which statement is true?


All XML elements must be lower case
All the statements are true
All XML documents must have a DTD
All XML elements must be properly closed

d. Is this a "well formed" XML document?


<?xml version="1.0"?>
<note>
<to age="29">Farrukh</to>
<from>Jaseem</from>
</note>
26

version="1.0"?>

Introduction to Distributed Computer Systems

Lab Session 04

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

e. Is this a "well formed" XML document?


<?xml version="1.0"?>
<note>
<to age=29>Farrukh</to>
<from>Jaseem</from>
</note>

27

Introduction to Distributed Computer Systems

Lab Session 05

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

Lab Session 05
OBJECTIVE
Understanding the concept of root elements and attributes in XML

THEORY
In any markup language, the first element to appear is called the "root element", which defines
what kind of document the file will be. In an HTML file, the <html> tag is the root element. An
HTML file will always have the HTML element as the root element, while in an XML file, it can
be anything.
An element is the basic building block of HTML and XML documents. Elements are identified
by a tag. The tag consists of angle brackets and content, and looks like this:
<AUTHOR>Syed Jaseemuddin</AUTHOR>
In HTML, you use a pre-defined set of elements. In XML you create your own set of elements.
Attributes are like adjectives, in that they further describe elements. Each attribute has a name
and a value. Attributes contain an attribute values. The value might be a number, a word, or a
URL. Attribute values follow the attribute and an equal sign. In XML, attribute values are always
surrounded by quotation marks. Attributes are entered as part of the tag, like this:
<AUTHOR dob="1986">Syed Jaseemuddin</AUTHOR>
You use a tag to identify a piece of data by element name. Tags usually appear in pairs,
surrounding the data. The opening tag contains the element name. The closing tag contains a
slash and the element's name, like this:
<AUTHOR>Syed Jaseemuddin</AUTHOR>
The DTD defines the elements, attributes, and relationships between elements for an XML
document. A DTD is a way to check that the document is structured correctly, but you do not
need to use one in order to use XML, as debated earlier.
Now the root element, also referred to as the "document", dictates what kind of XML document
it is. When creating an HTML file that is XML complaint, the root element will be <html>. The
root element must be the first element in an XML document and there can only be one root
element per file!
The core of an XML document comes from the elements that are contained within the root
element. Each element represents a different type of data that is being stored in the document.
The element <p> might represent paragraph text, while the element <gif> may contain data for a
GIF image.
Although not required, elements often have attributes that are associated with them. XML
attributes are similar to HTML attributes in that they have a name: value relationship. An
28

Introduction to Distributed Computer Systems

Lab Session 05

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

example attribute for an <img> element might be "src", which represents the source location of
the image.
XML Element & Attribute Code:
<imgsrc = "C:/MyDocs/Happy.gif"></img>
In addition to the information stored in the element itself (attributes), the bulk of data in XML
usually appears between the opening and closing tag of an XML element. This is often referred
to as the XML's "content". Below, we have an imaginary XML document that stores a story.
XML Code:
<story>
<author>Jill Doe</author>
<title>The Truth About the Family</title>
<page>
<paragraph>Here's a story of a polite person, Jaseem, who...</paragraph>
<paragraph>...he became the lecturer at NED...</paragraph>
</page>
</story>
Can you tell which element is the root element in the above XML code?

As specified earlier that in an XML file, there can only be one root element. The root element
must encapsulate all other elements-meaning; these other elements must show up after the
opening root tag and before the closing root tag. Here is an example of an XML document with
the root element "phonebook".
<phonebook>
<number>
</number>
<name>
</name>
</phonebook>
Notice how the root element "phonebook" surrounds the other elements in XML file. Below is a
broken XML file. Try to see if you can find what is wrong with this file before reading the
caption below.
<phonebook>
<number>
</number>
<name>
</phonebook>
</name>
29

Introduction to Distributed Computer Systems

Lab Session 05

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

You should have noticed that the root element "phonebook" did not contain all other elements
because the closing name tag </name> is not between the root element tags <phonebook> and
</phonebook>
Another rule for XML files is that only one root element per file is allowed. Our previous
example followed this rule, but our example below does not because it has two root elements.
<phonebook>
<number>
</number>
<name>
</name>
</phonebook>
<diary>
<date>
</date>
</diary>
What are the two root elements? If you said the two root elements were "phonebook" and
"diary", then you got it right! Phone book is the first element to appear in this file, so it is
automatically a root element.
After the phonebook element is closed, no other elements should follow because XML can only
have one root element per file. Because the "diary" element did not follow this rule, it
transformed this XML file into a lawless, rule-breaking file!

EXERCISES
a. <breakfast_menu>...</breakfast_menu>
Above XML is a compressed XML document for food menu
This is how it looks like after expanding:
<breakfast_menu>
<food>
<name>Belgian Waffles</name>
<price>$5.95</price>
<description>
two of our famous Belgian Waffles with plenty of real maple syrup
</description>
<calories>650</calories>
</food>
<food>
<name>Strawberry Belgian Waffles</name>
<price>$7.95</price>
<description>
light Belgian waffles covered with strawberries and whipped cream
</description>
<calories>900</calories>
</food>
<food>
<name>Berry-Berry Belgian Waffles</name>
<price>$8.95</price>
30

Introduction to Distributed Computer Systems

Lab Session 05

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

<description>

light Belgian waffles covered with an assortment of fresh berriesand whipped cream
</description>
<calories>900</calories>
</food>
<food>

<name>French Toast</name>
<price>$4.50</price>
<description>
thick slices made from our homemade sourdough bread
</description>
<calories>600</calories>
</food>
<food>

<name>Homestyle Breakfast</name>
<price>$6.95</price>
<description>
two eggs, bacon or sausage, toast, and our ever-popular hash browns
</description>
<calories>950</calories>
</food>
</breakfast_menu>
Identify the root elements if any.

b. Write an XML CD catalogue document having CATALOG as the root element and following
sub-elements: [Assume their attributes if possible.]
Sub-elements: TITLE, ARTIST, COUNTRY, COMPANY, PRICE and YEAR
Note: Should cover at least 10 different titles.

31

Introduction to Distributed Computer Systems

Lab Session 05

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

c. Write an XML Students catalogue document having UNDERGRAD as the root element and

following sub-elements: [Assume their attributes yourself.]


Sub-elements: NAME, DEPARTMENT, YEAR etc. as per your convenience.
Note: Should cover at least 10 different names.

32

Introduction to Distributed Computer Systems

Lab Session 05

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

33

Introduction to Distributed Computer Systems

Lab Session 06

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

Lab Session 06
OBJECTIVE
Introduction to Java Programming

THEORY
The objects that interact in a distributed system need to be dealt with in ways that are intrinsically
different from objects that interact in a single address space. These differences are required because
distributed systems require that the programmer be aware of latency, have a different model of memory
access, and take into account issues of concurrency and partial failure.

Why Java?
Java is not restricted to any one medium, domain or technology. It is an ideal language for development
on the server. Its garbage collection support removes the tiresome need for developers to concern
themselves with the ownership semantics for objects, at the cost of some performance. Its simplistic
syntax reduces the learning curve for developers new to Java and its similarity to C++ allows for easy
migration of C++ developers to Java.
ClassLoaders
ClassLoaders are one of the most powerful technologies in Java; by allowing us, as developers, to control
from where code can be loaded, we can now distribute applications in ways that we couldnt dream about
five years ago.
Consider a system in which customized behavior needs to be developed for a series of clients, varying not
only on a per-client basis, but on a per-entity basis within the client. For example, an insurance company
wants to perform different tasks on the call-center representatives PC during an insurance sales call,
depending on what data is entered. Some sample ideas might be:
Pop up a message box reminding the rep to suggestive-sell life-insurance policies to callers over
the age of 30
Introduce new specials on various policies, but only if the candidate fits a particular criteria
Remind the call center rep of the months current internal promotional program, reminding
him/her to undertake particular actions based on the reps proximity to the promotional target
Realistically, these sorts of monthly changes could drive a developer mad a new release every month?
Recording, retesting, everything, every month?
Instead of coding these sorts of mutable rules directly within the application code, a custom ClassLoader
is set up. Create the custom ClassLoader at a particular point during the call and load code associated with
this call directly from the database, or from a socket, so long as the code is coming from a code source
separate from the application itself. This allows the developers to change the code associated with the
database without having to modify the existing code base.
On-the-fly code upgrades
For years, developers have been searching for ways to upgrade code without bringing the server (or any
clients using the code at the time of upgrade) completely down. Java allows us to do this sort of dynamic,
on-the-fly upgrade.

Your First Java Program


Let us lead you into the world of Java programming by taking you through the three basic steps required
to get a simple program running. The Java system is a collection of applications not unlike any of the
other applications that you are accustomed to using (such as your word processor, e-mail program, or
34

Introduction to Distributed Computer Systems

Lab Session 06

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

internet browser). As with any application, you need to be sure that Java is properly installed on your
computer. You also need an editor and a terminal application.
Programming in Java
We break the process of programming in Java into three steps:
1. Create the program by typing it into a text editor and saving it to a file named, say,
MyProgram.java.

2. Compile it by typing "javac MyProgram.java" in the terminal window.


3. Run (or execute)it by typing "java MyProgram" in the terminal window.
The first step creates the program; the second translates it into a language more suitable for machine
execution (and puts the result in a file named MyProgram.class); the third actually runs the program.

Creating a Java program:. A program is nothing more than a sequence of characters, like
a sentence, a paragraph, or a poem. To create one, we need only define that sequence
characters using a text editor. HelloWorld.java is an example program. Type these
characters into your text editor and save it into a file namedHelloWorld.java.
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World");
}
}

Compiling a Java program: At first, it might seem to you as though the Java
programming language is designed to be best understood by the computer. Actually, to
the contrary, the language is designed to be best understood by the programmer (that's
you). A compiler is an application that translates programs from the Java language to a
language more suitable for executing on the computer. It takes a text file with the.java
extension as input (your program) and produces a file with a .class extension (the
computer-language version). To compile HelloWorld.java type the boldfaced text
below at the terminal. (We use the % symbol to denote the command prompt, but it may
appear different depending on your system.)
% javac HelloWorld.java
If you typed in the program correctly, you should see no error messages. Otherwise, go
back and make sure you typed in the program exactly as it appears above.

Executing a Java program: Once you compile your program, you can run it. This is the
exciting part, where the computer follows your instructions. To run the
HelloWorldprogram, type the following at the terminal:
%java HelloWorld
If all goes well, you should see the following response:
Hello World

EXERCISES
a. Write a program TenHelloWorlds.java that prints "Hello World" ten times?

35

Introduction to Distributed Computer Systems

Lab Session 06

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

b. Describe what happens if, in HelloWorld.java, you omit:


i. public
ii. static
iii. void
iv.
args

36

Introduction to Distributed Computer Systems

Lab Session 06

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

c. Describe what happens if, in HelloWorld.java, you misspell (by, say, omitting the second
letter)
i. public
ii. static
iii. void
iv.
args

d. I typed in the following program. It compiles fine, but when I execute it, I get the error
java.lang.NoSuchMethodError: main. What am I doing wrong?
Public class Hello {
Public static void main() {
System.out.println(Doesnt execute);

37

Introduction to Distributed Computer Systems

Lab Session 07

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

Lab Session 07
OBJECTIVE
Creating a distributed version of the classic Hello World program using Java Remote Method
Invocation (RMI) (Part 1)

THEORY
The distributed Hello World example uses an applet to make a remote method call to an RMI
server, running on the host from which the applet was downloaded. When the applet runs,
"Hello World" is displayed on the client browser.
This lab session is organized in three steps:
1. The steps to write the source files and the HTML file
2. The steps to compile and deploy class files and the HTML file
3. The steps to start the RMI registry, server, and applet
The first step will be covered in Lab session 7 and rest of the two steps will be covered in Lab
session 8.
The files needed for this example are:
Hello.java - a remote interface
HelloImpl.java
a
remote
object
implementation
that
examples.hello.Hello
HelloApplet.java - an applet that invokes the remote method, sayHello
hello.html - the HTML page that references the applet

implements

The source and HTML files


Because the Java programming language requires a mapping between the fully-qualified package
name of a class and the directory path to that class, you should decide on package and directory
names before you begin writing any code written in the Java programming language. This
mapping allows the compiler for the Java programming language to know the directory in which
to find the class files mentioned in a program. For the programs in this example, the package
name is examples.hello and the source directory is $HOME/mysrc/examples/hello.
To create the directory for your source files in Microsoft Windows platforms, you would go to
the directory of your choice, and type:
mkdir mysrc
mkdir mysrc\examples
mkdir mysrc\examples\hello
There are three tasks to be completed in this session:
1. Define the functions of the remote class as an interface written in the Java programming
language
2. Write the implementation and server classes
3. Write a client program that uses the remote service
38

Introduction to Distributed Computer Systems

Lab Session 07

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

The functions of the remote class as an interface written in the Java programming language
In the Java programming language, a remote object is an instance of a class that implements a
Remote interface. Your remote interface will declare each of the methods that you would like
to call from other Java virtual machines (JVMs).
Remote interfaces have the following characteristics:

The remote interface must be declared public. Otherwise, a client will get an error
when attempting to load a remote object that implements the remote interface, unless that
client is in the same package as the remote interface.
The remote interface extends the java.rmi.Remote interface.
Each method must declare java.rmi.RemoteException (or a superclass of
RemoteException) in its throws clause, in addition to any application-specific
exceptions.
The data type of any remote object that is passed as an argument or return value (either
directly or embedded within a local object) must be declared as the remote interface type
(for example, Hello) not the implementation class (HelloImpl).

Here is the interface definition for the remote interface, examples.hello.Hello. The
interface contains just one method, sayHello, which returns a string to the caller:
package examples.hello;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Hello extends Remote {
String sayHello() throws RemoteException;
}
Remote method invocations can fail in very different ways from local method invocations (due to
network-related communication problems and server problems), remote methods will report
communication failures by throwing a java.rmi.RemoteException.
The implementation and server classes
At a minimum, a remote object implementation class must:
i. Declare that it implements at least one remote interface
ii. Define the constructor for the remote object
iii. Provide implementations for the methods that can be invoked remotely
A "server" class, in this context, is the class which has a main method that creates an instance of
the remote object implementation, and binds that instance to a name in the rmiregistry. The
class that contains this main method could be the implementation class itself or another class
entirely.
In this example, the main method is part of examples.hello.HelloImpl. The server
program needs to:
i. Create and install a security manager
39

Introduction to Distributed Computer Systems

Lab Session 07

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

ii.
iii.

Create one or more instances of a remote object


Register at least one of the remote objects with the RMI remote object registry, for
bootstrapping purposes

An explanation of each of the preceding six steps follows the source for HelloImpl.java:
package examples.hello;
import
import
import
import

java.rmi.Naming;
java.rmi.RemoteException;
java.rmi.RMISecurityManager;
java.rmi.server.UnicastRemoteObject;

public
class
implements Hello {

HelloImpl

extends

UnicastRemoteObject

public HelloImpl() throws RemoteException {


super();
}
public String sayHello() {
return "Hello World!";
}
public static void main(String args[]) {
// Create and install a security manager
if (System.getSecurityManager() == null) {
System.setSecurityManager(new RMISecurityManager());
}
try {
HelloImplobj = new HelloImpl();
//

Bind

this

object

instance

to

the

name

"HelloServer"
Naming.rebind("//myhost/HelloServer", obj);
System.out.println("HelloServer bound in registry");
} catch (Exception e) {
System.out.println("HelloImpl err: " + e.getMessage());
e.printStackTrace();
}
}
}
Implement a remote interface
In the Java programming language, when a class declares that it implements an interface, a
contract is formed between the class and the compiler. By entering into this contract, the class is
promising that it will provide method bodies, or definitions, for each of the method signatures
40

Introduction to Distributed Computer Systems

Lab Session 07

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

declared in that interface. Interface methods are implicitly public and abstract, so if the
implementation class doesn't fulfill its contract, it becomes by definition an abstract class,
and the compiler will point out this fact if the class was not declared abstract.
The implementation class in this example is examples.hello.HelloImpl. The
implementation class declares which remote interface(s) it is implementing. Here is the
HelloImplclass declaration:
public class HelloImpl extends UnicastRemoteObject
implements Hello {
As a convenience, the implementation class can extend a remote class, which in this example is
java.rmi.server.UnicastRemoteObject.
By
extending
UnicastRemoteObject, the HelloImplclass can be used to create a remote object that:
Uses RMI's default sockets-based transport for communication
Runs all the time
Define the constructor for the remote object
The constructor for a remote class provides the same functionality as the constructor for a nonremote class: it initializes the variables of each newly created instance of the class, and returns an
instance of the class to the program which called the constructor.
In addition, the remote object instance will need to be "exported". Exporting a remote object
makes it available to accept incoming remote method requests, by listening for incoming calls to
the
remote
object
on
an
anonymous
port.
When
you
extend
java.rmi.server.UnicastRemoteObjectorjava.rmi.activation.Activata
ble, your class will be exported automatically upon creation.
If you choose to extend a remote object from any class other than UnicastRemoteObject or
Activatable, you will need to explicitly export the remote object by calling either the
UnicastRemoteObject.exportObject
method
or
the
Activatable.exportObject method from your class's constructor (or another
initialization method, as appropriate).
Because the object export could potentially throw a java.rmi.RemoteException, you
must define a constructor that throws a RemoteException, even if the constructor does
nothing else. If you forget the constructor, javac will produce the following error message:
HelloImpl.java:13: Exception java.rmi.RemoteException
caught, or it must be
declared in the throws clause of this method.
super();
^
1 error
Here is the constructor for the examples.hello.HelloImpl class:
public HelloImpl() throws RemoteException {
41

must

be

Introduction to Distributed Computer Systems

Lab Session 07

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

super();
}

The super
method call
invokes the no-argument constructor of
java.rmi.server.UnicastRemoteObject, which exports the remote object.
The constructor must throw java.rmi.RemoteException, because RMI's attempt
to export a remote object during construction might fail if communication resources are
not available.

Provide an implementation for each remote method


The implementation class for a remote object contains the code that implements each of the
remote methods specified in the remote interface. For example, here is the implementation for
the sayHello method, which returns the string "Hello World" to the caller:
public String sayHello() throws RemoteException {
return "Hello World!";
}
Arguments to, or return values from, remote methods can be any data type for the Java platform,
including objects, as long as those objects implement the interface java.io.Serializable.
Most of the core classes in java.lang and java.util implement the Serializable
interface.
Create and install a security manager
The main method of the server first needs to create and install a security manager: either the
RMISecurityManageror one that you have defined yourself. For example:
if (System.getSecurityManager() == null) {
System.setSecurityManager(new RMISecurityManager());
}
A security manager needs to be running so that it can guarantee that the classes that get loaded do
not perform operations that they are not allowed to perform. If no security manager is specified
no class loading, by RMI clients or servers, is allowed, aside from what can be found in the local
CLASSPATH. In this example, a security manager is not installed in the client code because
applets use the security manager already installed in the client browser. If the client were an
application rather than an applet, however, you would need to use the same procedure as is used
above to install a security manager in the client. A security manager is required in any JVM that
needs to download code, and RMI clients need to download RMI stubs (as well as any other
custom classes or interfaces needed to communicate with the RMI server).
Create one or more instances of a remote object
The main method of the server needs to create one or more instances of the remote object
implementation which provides the service. For example:
HelloImpl obj = new HelloImpl();
The constructor exports the remote object, which means that once created, the remote object is
ready to accept incoming calls.
42

Introduction to Distributed Computer Systems

Lab Session 07

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

Register the remote object


For a caller (client, peer, or applet) to be able to invoke a method on a remote object, that caller
must first obtain a reference to the remote object.
For bootstrapping, the RMI system provides a remote object registry that allows you to bind a
URL-formatted name of the form "//host/objectname" to the remote object, where
objectname is a simple string name.
The RMI registry is a simple server-side name service that allows remote clients to get a
reference to a remote object. It is typically used only to locate the first remote object an RMI
client needs to talk to. Then that first object would in turn provide application-specific support
for finding other objects.
For example, the reference can be obtained as a parameter to, or a return value from, another
remote method call.
Once a remote object is registered on the server, callers can look up the object by name, obtain a
remote object reference, and then remotely invoke methods on the object. For example, the
following code binds the name "HelloServer" to a reference for the remote object:
Naming.rebind("//myhost/HelloServer", obj);
Note the following about the arguments to the rebind method call:
The first parameter is a URL-formatted java.lang.String, representing the location
and name of the remote object.
o No protocol needs to be specified in the URL-formatted string.
o You will need to change the value of myhost to be the name or IP address of
your server machine; otherwise, the remote object host defaults to the current
host. For example, "HelloServer" is a valid name string that refers to a remote
object bound to the name HelloServer, running on the local host.
o Optionally, a port number can be supplied in the URL-formatted string.
Specifying the port number is necessary when the registry that needs to be
contacted is running on a port other than the default port, 1099. For example,
"//myhost:1234/HelloServer" is a valid name string for the
HelloServer remote object, reachable through an RMI registry that is running
on the host myhost and is listening for incoming calls on port 1234.
The second parameter is a reference to the object implementation, on which remote
methods will be invoked.
Once an object is exported, the RMI runtime substitutes a reference to the remote object's
stub for the actual remote object reference specified by the obj argument. When a client
performs a lookup in a server's remote object registry, a serialized instance of the stub for
the implementation is returned.
Write a client program that uses the remote service
The applet in this example remotely invokes the sayHello method in order to get the string
"Hello World!" to display when the applet runs. Here is the code for the applet:
package examples.hello;
43

Introduction to Distributed Computer Systems

Lab Session 07

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

import
import
import
import

java.applet.Applet;
java.awt.Graphics;
java.rmi.Naming;
java.rmi.RemoteException;

public class HelloApplet extends Applet {


String message = "blank";
// "obj" is the identifier that we'll use to refer
// to the remote object that implements the "Hello"
// interface
Hello obj = null;
public void init() {
try {
obj = (Hello)Naming.lookup("//" +
getCodeBase().getHost() + "/HelloServer");
message = obj.sayHello();
} catch (Exception e) {
System.out.println("HelloApplet exception: " + e.getMessage());
e.printStackTrace();
}
}
public void paint(Graphics g) {
g.drawString(message, 25, 50);
}
}
1. First, the applet gets a reference to the remote object implementation (advertised as
"HelloServer") from the server host's rmiregistry. Like the Naming.rebind
method, the Naming.lookup method takes a URL-formatted java.lang.String.
In this example, the applet constructs the URL string by using the getCodeBase
method in conjunction with the getHost method. Naming.lookup takes care of the
following tasks:
o Constructing a registry stub instance (to contact the server's registry) using the
hostname and port number supplied as arguments to Naming.lookup
o Using the registry stub to call the remote lookup method on the registry, using
the URL's name component ("HelloServer")
The registry returns the HelloImpl_Stub instance bound to that name
The lookup method receives the remote object's (HelloImpl) stub
instance
and
loads
the
stub
class(examples.hello.HelloImpl_Stub) from the CLASSPATH
or the applet's codebase
o Naming.lookupreturns the stub to its caller (HelloApplet)
2. The applet invokes the remote sayHello method on the server's remote object
o RMI serializes and returns the reply string "Hello World!"
o RMI deserializes the string and stores it in a variable named message.
44

Introduction to Distributed Computer Systems

Lab Session 07

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

3. The applet paint invokes the method, causing the string "Hello World!" to be displayed
in the drawing area of the applet.
The URL-formatted string that is passed as a parameter to the Naming.lookup method must
include the server's hostname. Otherwise, the applet's lookup attempt will default to the client,
and the AppletSecurityManagerwill throw an exception because the applet cannot access
the local system, but is instead limited to only communicating with the applet's host.
Here is the HTML code for the web page that references the Hello World applet:
<HTML>
<title>Hello World</title>
<center><h1>Hello World</h1></center>
<applet codebase="myclasses/"
code="examples.hello.HelloApplet"
width=500 height=120>
</applet>
</HTML>
Note the following:
There needs to be an HTTP server running on the machine from which you want to
download classes.
The codebase in the HTML file specifies a directory below the directory from which
the web page was itself loaded. Using this kind of relative path is usually a good idea. For
example, if the codebase directory (where the applet's class files live), referenced by
the applet's HTML, was in the directory above the HTML directory, you would use the
relative path, "../".
The applet's code attribute specifies the fully-qualified package name of the applet, in
this example examples.hello.HelloApplet:
code="examples.hello.HelloApplet"

45

Introduction to Distributed Computer Systems

Lab Session 10

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

Lab Session 08
OBJECTIVE
Creating a distributed version of the classic Hello World program using Java Remote Method
Invocation (RMI) (Part 2)

THEORY
The lab session 2 was organized in three steps:
1. The steps to write the source files and the HTML file
2. The steps to compile and deploy class files and the HTML file
3. The steps to start the RMI registry, server, and applet
The first step was covered in Lab session 7 and the rest of the two steps are to be covered in this
Lab session.
Compile and Deploy Class Files and HTML Files
The
source
code
for
this
example
is
now
complete
and
the
$HOME/mysrc/examples/hello directory has four files:
Hello.java contains the source code for the Hello remote interface.
HelloImpl.java contains the source code for the HelloImpl remote object
implementation and the RMI server for the applet.
HelloApplet.java contains the source code for the applet.
hello.html is the web page that references the Hello World applet.
In this section, you will compile the .java source files to create .class files. You then run
the rmic compiler to create stubs and skeletons. A stub is a client-side proxy for a remote object
which forwards RMI calls to the server-side dispatcher, which in turn forwards the call to the
actual remote object implementation.
When you use the javac and rmic compilers, you must specify where the resulting class files
should reside. For applets, all files should be in the applet's codebase directory. For our example,
this directory is $HOME/public_html/myclasses.
Some web servers allow accessing a user's public_html directory via an HTTP URL constructed
as "http://host/~username/". If your web server does not support this convention, you
could use a file URL of the form "file:/home/username/public_html" for testing,
but this approach will limit you to communicating between a client and server that have access to
the same physical file system. As an alternative, you can use an HTTP URL by setting up a
minimal web server on your system.
There are four tasks to complete in this section:
1. Compile the source files
2. Use rmic to generate stubs and skeletons
3. Move the HTML file to the deployment directory
4. Set paths for runtime
46

Introduction to Distributed Computer Systems

Lab Session 10

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

Compile the source files


Make sure that the deployment directory $HOME/public_html/myclasses and the
development directory $HOME/mysrc/examples/hello are each accessible through the
local CLASSPATH on the development machine before attempting to compile.
To compile the source files, run the javac command as follows:
javac -d $HOME/public_html/myclasses Hello.java
HelloImpl.java HelloApplet.java
This command creates the directory examples/hello (if it does not already exist) in the
directory $HOME/public_html/myclasses. The command then writes to that directory the
files Hello.class, HelloImpl.class, and HelloApplet.class. These are the
remote interface, the implementation, and the applet respectively.
Use rmic to generate skeletons and/or stubs
To create stub and skeleton files, run the rmic compiler on the fully-qualified package names of
compiled class files that contain remote object implementations, like my.package.MyImpl.
The rmic command takes one or more class names as an argument and produces class files of
the form MyImpl_Skel.class and MyImpl_Stub.class.
By default, in the Java 2 SDK, v1.2 and later, rmic runs with the -vcompat flag on, which
produces stubs and skeletons that support access to:
1. Unicast (not Activatable) remote objects from 1.1 clients and
2. All types of remote objects from 1.2 (and later) clients
If you will never need support for 1.1 clients, rmic can be run with the -v1.2 option. For
example, to create the stub and skeleton for the HelloImpl remote object implementation, run
rmic like this:
rmic -d

$HOME/public_html/myclasses

examples.hello.HelloImpl

The "-d" option indicates the root directory in which to place the compiled stub and skeleton
class files. So the preceding command creates the following files in the directory
$HOME/public_html/myclasses/examples/hello:

HelloImpl_Stub.class
HelloImpl_Skel.class

The generated stub class implements exactly the same set of remote interfaces as the remote
object itself. This means that a client can use the Java programming language's built-in operators
for casting and type checking. It also means that remote objects written for the Java platform
support true object-oriented polymorphism.
Move the HTML file to the deployment directory
To make the web page that references the applet visible to clients, the hello.html file must be
moved from the development directory to the applet's codebase directory. For example:

47

Introduction to Distributed Computer Systems

Lab Session 10

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

mv

$HOME/mysrc/examples/hello/hello.html

$HOME/public_html/

Set paths for runtime


Make sure that the $HOME/public_html/myclasses directory is available through the
server's local CLASSPATH when you run the HelloImpl server.
Start the RMI registry, server, and applet
There are three tasks to complete in this section:
i. Start the RMI registry
ii. Start the server
iii. Run the applet
Start the RMI registry
The RMI registry is a simple server-side name server that allows remote clients to get a reference
to a remote object. Typically, it is used only to locate the first remote object an application needs
to talk to. Then that object in turn would provide application-specific support for finding other
objects.
Before you start the rmiregistry, you must make sure that the shell or window in which you
will run the registry either has no CLASSPATH set or has a CLASSPATH that does not include
the path to any classes that you want downloaded to your client, including the stubs for your
remote object implementation classes.
If you start the rmiregistry, and it can find your stub classes in its CLASSPATH, it will
ignore the server's java.rmi.server.codebaseproperty, and as a result, your client(s)
will not be able to download the stub code for your remote object.
To start the registry on the server, execute the rmiregistry command. This command
produces no output and is typically run in the background.
For example, on Microsoft Windows 95 systems:
startrmiregistry (Use javaw if start is not available.)
By default, the registry runs on port 1099. To start the registry on a different port, specify the
port number from the command line. For example, to start the registry on port 2001 on a
Microsoft Windows NT system:
startrmiregistry 2001
If the registry is running on a port other than 1099, you'll need to specify the port number in the
name handed to the URL-based methods of the java.rmi.Naming class when making calls to
the registry. For example, if the registry is running on port 2001 in this example, the call required
to bind the name "HelloServer" to the remote object reference would be:
Naming.rebind("//myhost:2001/HelloServer", obj);
You must stop and restart the registry any time you modify a remote interface or use
modified/additional remote interfaces in a remote object implementation. Otherwise, the type of
the object reference bound in the registry will not match the modified class.

48

Introduction to Distributed Computer Systems

Lab Session 10

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

Start the server


When starting the server, the java.rmi.server.codebase property must be specified, so
that the stub class can be dynamically downloaded to the registry and then to the client. Run the
server, setting the codebase property to be the location of the implementation stubs. Because the
codebase property in this example references a directory, make sure that any other classes that
may need to be downloaded have also been installed in the directory referenced by
java.rmi.server.codebase.
A stub class is dynamically downloaded to a client's virtual machine only when the class is not
already available locally and the java.rmi.server.codebase property has been set
properly to specify where the class files are located on the server.
There are four things that need to go on the same command line: the "java" command, followed
by two property name=value pairs (for the codebase property, note that there are no spaces
from the "-D" all the way though the last "/") and then the fully-qualified package name of the
server program. There should be a space just after the word "java", between the two properties,
and just before the word "examples" (which is very hard to see when you view this as text, in a
browser, or on paper). The following command shows how to start the HelloImpl server,
specifying the java.rmi.server.codebase and java.security.policy properties:
java
Djava.rmi.server.codebase=http://myhost/~myusrname/myclasses/
Djava.security.policy=$HOME/mysrc/policy
examples.hello.HelloImpl

In order to run this code on your system, you'll need to change the location of the policy file
to be the location of the directory on your system, where you've installed the example source
code.
Note: In this example, for simplicity, we will use a policy file that gives global permission to
anyone from anywhere. Do not use this policy file in a production environment.
The codebase property will be resolved to a URL, so it must have the form of
"http://aHost/somesource/" or "file:/myDirectory/location/" or, due to the
requirements of some operating systems, "file:///myDirectory/location/" (three
slashes after the "file:").
Please note that each of the URL strings above has a trailing "/". The trailing slash is a
requirement for the URL set by the java.rmi.server.codebase property, so the
implementation can resolve (find) your class definition(s) properly.
If you forget the trailing slash on the codebase property, or if the class files can't be located at
the source (they aren't really being made available for download) or if you misspell the property
name, you'll get thrown a java.lang.ClassNotFoundException. This exception will
be thrown when you try to bind your remote object to the rmiregistry, or when the first
client attempts to access that object's stub. If the latter case occurs, you have another problem as
well because the rmiregistrywas finding the stubs in its CLASSPATH.
The output should look like this:
HelloServer bound in registry
49

Introduction to Distributed Computer Systems

Lab Session 10

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

Run the applet


Once the registry and server are running, the applet can be run. An applet is run by loading its
web page into a browser or appletviewer, as shown here:
appletviewer http://myhost/~myusrname/hello.html &
After running the applet viewer, you will see output similar to the following on your display:

50

Introduction to Distributed Computer Systems

Lab Session 10

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

Lab Session 09
OBJECTIVE
Understanding the concept of Indirect Communication and exploring group communication
mechanism via JGroup Toolkit.

THEORY
Indirect Communication
Indirect communication is defined as communication between entities in a distributed system
through an intermediary with no direct coupling between the sender and the receiver(s). The
precise nature of the intermediary varies from approach to approach.
The techniques that are all based on a direct coupling between a sender and a receiver, and this
leads to a certain amount of rigidity in the system in terms of dealing with change. To illustrate
this, consider a simple client-server interaction. Because of the direct coupling, it is more
difficult to replace a server with an alternative one offering equivalent functionality. Similarly, if
the server fails, this directly affects the client, which must explicitly deal with the failure. In
contrast, indirect communication avoids this direct coupling and hence inherits interesting
properties. The literature refers to two key properties stemming from the use of an intermediary:
Space uncoupling, in which the sender does not know or need to know the identity of the
receiver(s), and vice versa. Because of this space uncoupling, the system developer has
many degrees of freedom in dealing with change: participants (senders or receivers) can
be replaced, updated, replicated or migrated.
Time uncoupling, in which the sender and receiver(s) can have independent lifetimes. In
other words, the sender and receiver(s) do not need to exist at the same time to
communicate. This has important benefits, for example, in more volatile environments
where senders and receivers may come and go.
Group Communication
Group communication provides our first example of an indirect communication paradigm. Group
communication offers a service whereby a message is sent to a group and then this message is
delivered to all members of the group. In this action, the sender is not aware of the identities of
the receivers. Group communication represents an abstraction over multicast communication and
may be implemented over IP multicast or an equivalent overlay network, adding significant extra
value in terms of managing group membership, detecting failures and providing reliability and
ordering guarantees.
The Programming Model
In group communication, the central concept is that of a group with associated group
membership, whereby processes may join or leave the group. Processes can then send a message
to this group and have it propagated to all members of the group with certain guarantees in terms
of reliability and ordering. Thus, group communication implements multicast communication, in
which a message is sent to all the members of the group by a single operation. Communication to
51

Introduction to Distributed Computer Systems

Lab Session 10

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

all processes in the system, as opposed to a subgroup of them, is known as broadcast, whereas
communication to a single process is known as unicast.
The essential feature of group communication is that a process issues only one multicast
operation to send a message to each of a group of processes (in Java this operation is
aGroup.send (aMessage)) instead of issuing multiple send operations to individual processes.
Process Groups and Object Groups
Most work on group services focuses on the concept of process groups, that is, groups where the
communicating entities are processes. Such services are relatively low-level in that:
Messages are delivered to processes and no further support for dispatching is provided.
Messages are typically unstructured byte arrays with no support for marshalling of complex
data types (as provided, for example, in RPC or RMI).
The level of service provided by process groups is therefore similar to that of sockets. In contrast,
object groups provide a higher-level approach to group computing. An object group is a
collection of objects (normally instances of the same class) that process the same set of
invocations concurrently, with each returning responses. Client objects need not be aware of the
replication. They invoke operations on a single, local object, which acts as a proxy for the group.
The proxy uses a group communication system to send the invocations to the members of the
object group. Object parameters and results are marshalled as in RMI and the associated calls are
dispatched automatically to the right destination objects/methods.
Other Key Distinctions
A wide range of group communication services has been developed, and they vary in the
assumptions they make:
Closed and Open Groups: A group is said to be closed if only members of the group may
multicast to it. A process in a closed group delivers to itself any message that it multicasts to the
group. A group is open if processes outside the group may send to it. (The categories open and
closed also apply with analogous meanings to mailing lists). Closed groups of processes are
useful, for example, for cooperating servers to send messages to one another that only they
should receive. Open groups are useful, for example, for delivering events to groups of interested
processes.
Overlapping and Non-Overlapping Groups: In overlapping groups, entities (processes or
objects) may be members of multiple groups, and non-overlapping groups imply that
membership does not overlap (that is, any process belongs to at most one group). Note that in
real-life systems, it is realistic to expect that group membership will overlap.
Implementation Issues

Reliability and Ordering In Multicast

In group communication, all members of a group must receive copies of the messages sent to the
group, generally with delivery guarantees. As well as reliability guarantees, group
communication demands extra guarantees in terms of the relative ordering of messages delivered
to multiple destinations.
52

Introduction to Distributed Computer Systems

Lab Session 10

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

FIFO Ordering: First-in-first-out (FIFO) ordering (also referred to as source ordering) is


concerned with preserving the order from the perspective of a sender process, in that if a
process sends one message before another, it will be delivered in this order at all
processes in the group.
Causal Ordering: Causal ordering takes into account causal relationships between
messages, in that if a message happens before another message in the distributed system
this so-called causal relationship will be preserved in the delivery of the associated
messages at all processes.
Total Ordering: In total ordering, if a message is delivered before another message at one
process, then the same order will be preserved at all processes.

Group Membership Management

Providing an interface for group membership changes: The membership service


provides operations to create and destroy process groups and to add or withdraw a
process to or from a group. In most systems, a single process may belong to several
groups at the same time (overlapping groups).
Failure detection: The service monitors the group members not only in case they should
crash, but also in case they should become unreachable because of a communication
failure. The detector marks processes as Suspected or Unsuspected. The service uses the
failure detector to reach a decision about the groups membership: it excludes a process
from membership if it is suspected to have failedor to have become unreachable.
Notifying members of group membership changes: The service notifies the groups
members when a process is added, or when a process is excluded (through failure or
when the process is deliberately withdrawn from the group)
Performing group address expansion: When a process multicasts a message, it supplies
the group identifier rather than a list of processes in the group. The membership
management service expands the identifier into the current group membership for
delivery.
The JGroup Toolkit
JGroups is a toolkit for reliable group communication written in Java
(http://www.jgroups.org/index.html). JGroups supports process groups in which processes are
able to join or leave a group, send a message to all members of the group or indeed to a single
member, and receive messages from the group. The toolkit supports a variety of reliability and
ordering guarantees, which are discussed in more detail below, and also offers a group
membership service.
The architecture of JGroups has the following main components of the JGroups implementation:

Channels represent the most primitive interface for application developers, offering the
core functions of joining, leaving, sending and receiving.
Building blocks offer higher-level abstractions, building on the underlying service offered
by channels.
Protocol Stack provides the underlying communication protocol, constructed as a stack of
protocol layers.

JGroup API
53

Introduction to Distributed Computer Systems

Lab Session 10

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

The API of JGroups is very simple. The code is always the same, regardless of the protocol stack
used.
To be able to send/receive messages, a channel has to be created. The reliability of a channel is
specified via XML, which then causes the creation of the underlying protocol stack.
The example below creates a channel and sends/receives 1 message:
JChannel channel=new JChannel("/home/bela/udp.xml");
channel.setReceiver(new ReceiverAdapter() {
public void receive(Message msg) {
System.out.println("received msg from " + msg.getSrc() + ": " +
msg.getObject());
}
});
channel.connect("MyCluster");
channel.send(new Message(null, "hello world"));
channel.close();
The channel's configuration is defined in the constructor. In the sample code, we use an XML file
with an absolute path. If we use a relative path, then the file is looked up on the classpath.
The XML file contains a list of protocols to be used by the new channel.
To join a cluster, connect() is called. It returns when the member has successfully joined the
cluster named "MyCluster", or when it has created a new cluster (if it is the first member).
Then a message is sent using the send() method. A message contains the receiver's address (null
= all cluster nodes) and a byte buffer. In the example, the string "hello world" is set to be the
message's contents. It is serialized into the message's byte buffer.
Since the message is sent to all members, the sender will also receive it. This is done via the
receive() callback, which was registered with the channel before.
Finally, the member closes the channel and thus leaves the cluster. This result in a notification
being sent to all members who are registered for membership change notifications.

JGroup Demos
Students are advised to visit these sites: http://www.jgroups.org/manual/html_single/#d0e226
and http://www.jgroups.org/demos.html in order to have an insight of installation &
configuration of toolkit and also to have clear understanding of different examples present in the
demonstration.

54

Introduction to Distributed Computer Systems

Lab Session 10

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

Exercises
Q.1) Explain briefly Indirect Communication with at least two examples. Why do we need
Group Communication?

Q.2) Explore JGroup Toolkit. Discuss its key features also explain its Flexible Protocol
Stack.

55

Introduction to Distributed Computer Systems

Lab Session 10

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

56

Introduction to Distributed Computer Systems

Lab Session 10

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

Lab Session 10
OBJECTIVE
Understanding the concept of message queues via Java Messaging Service (JMS)

THEORY
Message queues (or more accurately, distributed message queues) are another important category
of indirect communication systems. Whereas groups and publish subscribe provide a one-tomany style of communication, message queues provide a point-to-point service using the concept
of a message queue as an indirection, thus achieving the desired properties of space and time
uncoupling. Here sender places the message into a queue, and it is then removed by a single
process. Message queues are also referred to as Message-Oriented Middleware. This is a major
class of commercial middleware with key implementations including IBMs WebSphere MQ,
Microsofts MSMQ and Oracles Streams Advanced Queuing (AQ).
The Programming Model
The programming model offered by message queues is very simple. It offers an approach to
communication in distributed systems through queues. In particular, producer processes can send
messages to a specific queue and other (consumer) processes can then receive messages from this
queue. Three styles of receive are generally supported:
A blocking receive, which will block until an appropriate message is available;
A non-blocking receive (a polling operation), which will check the status of the queue
and return a message if available, or a not available indication otherwise;
A notify operation, which will issue an event notification when a message is available in
the associated queue.
A number of processes can send messages to the same queue, and likewise a number of receivers
can remove messages from a queue. The queuing policy is normally first-in-first-out (FIFO), but
most message queue implementations also support the concept of priority, with higher-priority
messages delivered first. Consumer processes can also select messages from the queue based on
properties of a message.
Java Messaging Service (JMS)
The Java Messaging Service (JMS) is a specification of a standardized way for distributed Java
programs to communicate indirectly. A wide variety of implementations of the common
specification are now available, including Joram from OW2, Java Messaging from JBoss, Suns
Open MQ, Apache ActiveMQ and OpenJMS. Other platforms, including WebSphere MQ, also
provide a JMS interface on to their underlying infrastructure.
JMS distinguishes between the following key roles:
A JMS client is a Java program or component that produces or consumes messages, a JMS
producer is a program that creates and produces messages and a JMS consumer is a program that
receives and consumes messages.
A JMS provider is any of the multiple systems that implement the JMS specification.
57

Introduction to Distributed Computer Systems

Lab Session 10

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

A JMS message is an object that is used to communicate information betweenJMS clients (from
producers to consumers).

Figure 1.1 JMS API Programming Model

Programming with JMS


The programming model offered by the JMS API is captured in Figure 1.1
To interact with a JMS provider, it is first necessary to create a connection between a client
program and the provider. This is created through a connection factory (a service responsible for
creating connections with the required properties). The resultant connection is a logical channel
between the client and provider; the underlying implementation may, for example, map onto a
TCP/IP socket if implemented over the Internet. Note that two types of connection can be
established, a TopicConnectionor a QueueConnection, thus enforcing a clear separation between
the two modes of operation within given connections. Connections can be used to create one or
more sessions a session is a series of operations involving the creation, production and
consumption of messages related to a logical task. The resultant session object also supports
operations to create transactions, supporting all-or-nothing execution of a series of operations.
There is a clear distinction between topic sessions and queue sessions in that a
TopicConnectioncan support one or more topic sessions and a QueueConnectioncan support one
or more queue sessions, but it is not possible to mix session styles in a connection. The session
object is central to the operation of JMS, supporting methods for the creation of messages,
message producers and message consumers.
In JMS, a message consists of three parts: a header, a set of properties and the body of the
message. The header contains all the information needed to identify and route the message.
Properties are all user-defined and can be used to associate other application-specific metadata
58

Introduction to Distributed Computer Systems

Lab Session 10

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

elements with a message. For example, if implementing a context-aware system, the properties
can be used to express additional context associated with the message, including a location field.
In JMS, the body can be any one of a text message, a byte stream, a serialized Java object, stream
of primitive Java values or a more structured set of name/value pairs.
Getting Started with OpenJMS
OpenJMS is an open source implementation of Sun Microsystems's Java Message Service API
1.1 Specification.
Downloads & Installation
Before you can start using OpenJMS, you need to download the OpenJMS distribution to your
system. OpenJMS releases are available in both install and source archives from the SourceForge
download page. (http://openjms.sourceforge.net/downloads.html) For convenience, they are
provided in zip and tar/gzip formats. These include the OpenJMS server, the OpenJMS client
JARS, 3rd party JARS required by the client and server, the complete set of documentation,
scripts to run the server on Windows and UNIX and sample programs.
After you have downloaded a distribution, you need to install this on your system before you can
start using OpenJMS (http://openjms.sourceforge.net/adminguide/install.html).OpenJMS will run
on any platform where there is a suitable Java 2 runtime environment. Then you need to unpack
install archive. The install archive contains everything required to run OpenJMS on your system.
The archive has a single top-level directory named openjms-0.7.7-beta-1 with all the OpenJMS
related files beneath that.
Install archives with a .zip extension can be unpacked using winzip, or the jar tool (distributed
with the Java 2 SDK). E.g.:
jarxvf openjms-0.7.7-beta-1.zip
Install archives with a .tar.gz extension can be unpacked with gzip and tar. E.g.:
gzip -cd openjms-0.7.7-beta-1.tar.gz | tar xvf The OpenJMS server uses the following Environment variables.

JAVA_HOME
OPENJMS_HOME

Java Development Kit installation directory.


OpenJMS installation directory.

Running OpenJMS
Once you've installed OpenJMS, you need to start the OpenJMSserver.To start the OpenJMS
server, open a command prompt and type:
cd %OPENJMS_HOME%\bin
startup

(In Windows)

cd $OPENJMS_HOME/bin
startup.sh

(In UNIX)

59

Introduction to Distributed Computer Systems

Lab Session 10

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

Executing Programs
OpenJMS is distributed with a number of example programs that demonstrate writing simple
applications using JMS.
Building the examples
Helper scripts are provided to compile the examples with the appropriate class path. To run these,
open a command prompt and type:
cd %OPENJMS_HOME%\examples\basic
build
(In Windows)
cd $OPENJMS_HOME/examples/basic
build.sh
(In UNIX)

Running the examples

Helper scripts are also provided to run the examples. To run these, open a command prompt and
type:
run<classname>
(In Windows)
run.sh <classname> (In UNIX)
Example Code
Sender.java
importjavax.jms.*;
importjavax.naming.*;
public class Sender {
public static void main(String[] args) {
Context context = null;
ConnectionFactory factory = null;
Connection connection = null;
String factoryName = "ConnectionFactory";
String destName = null;
Destination dest = null;
int count = 1;
Session session = null;
MessageProducer sender = null;
String text = "Message ";
try {
// create the JNDI initial context.
context = new InitialContext();
// look up the ConnectionFactory
factory = (ConnectionFactory) context.lookup(factoryName);
60

Introduction to Distributed Computer Systems

Lab Session 10

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

// look up the Destination


dest = (Destination) context.lookup(destName);
// create the connection
connection = factory.createConnection();
// create the session
session = connection.createSession(
false, Session.AUTO_ACKNOWLEDGE);
// create the sender
sender = session.createProducer(dest);
// start the connection, to enable message sends
connection.start();
for (int i = 0; i < count; ++i) {
TextMessage message = session.createTextMessage();
message.setText(text + (i + 1));
sender.send(message);
System.out.println("Sent: " + message.getText());
}
} catch (JMSException exception) {
exception.printStackTrace();
} catch (NamingException exception) {
exception.printStackTrace();
} finally {
// close the context
if (context != null) {
try {
context.close();
} catch (NamingException exception) {
exception.printStackTrace();
}
}
// close the connection
if (connection != null) {
try {
connection.close();
} catch (JMSException exception) {
exception.printStackTrace();
}
}
}
}
}
Receiver.java
61

Introduction to Distributed Computer Systems

Lab Session 10

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

importjavax.jms.*;
importjavax.naming.*;
public class Receiver {
public static void main(String[] args) {
Context context = null;
ConnectionFactory factory = null;
Connection connection = null;
String factoryName = "ConnectionFactory";
String destName = null;
Destination dest = null;
int count = 1;
Session session = null;
MessageConsumer receiver = null;
try {
// create the JNDI initial context
context = new InitialContext();
// look up the ConnectionFactory
factory = (ConnectionFactory) context.lookup(factoryName);
// look up the Destination
dest = (Destination) context.lookup(destName);
// create the connection
connection = factory.createConnection();
// create the session
session = connection.createSession(
false, Session.AUTO_ACKNOWLEDGE);
// create the receiver
receiver = session.createConsumer(dest);
// start the connection, to enable message receipt
connection.start();
for (int i = 0; i < count; ++i) {
Message message = receiver.receive();
if (message instanceofTextMessage) {
TextMessage text = (TextMessage) message;
System.out.println("Received: " + text.getText());
} else if (message != null) {
System.out.println("Received non text message");
}
}
} catch (JMSException exception) {
62

Introduction to Distributed Computer Systems

Lab Session 10

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

exception.printStackTrace();
} catch (NamingException exception) {
exception.printStackTrace();
} finally {
// close the context
if (context != null) {
try {
context.close();
} catch (NamingException exception) {
exception.printStackTrace();
}
}
// close the connection
if (connection != null) {
try {
connection.close();
} catch (JMSException exception) {
exception.printStackTrace();
}
}
}
}
}

Exercises
Q.1) Explain the basic building blocks of JMS API Programming Model.

63

Introduction to Distributed Computer Systems

Lab Session 10

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

Q.2) Give the step by step flow of example programs discussed in this lab session.

64

Introduction to Distributed Computer Systems

Lab Session 10

NED University of Engineering & Technology Department of Computer & Information Systems Engineering

65

Você também pode gostar