Excerpt for Advance Java Programming by , available in its entirety at Smashwords




ADVANCE JAVA PROGRAMMING




Dr.W.Regis Anne






Overview

1:Overview of I/O Streams 1

2: Networking 10

3: Multithreading 19

4: Collection Class & Data Structure 24

5: Event Handling 30

6: Object Serialization 38

7:Java RMI 42

8: CORBA Architecture 50

9: Overview of JINI 69

10: Java Beans 73

11: Overview of Swing 94

12: Java Native Interface 108

13: Servlets 114

14: Introduction to JSP 118

15:JDBC 124

16:EJB 129

17: Java Media Framework 137

18: Java 3D API 143

19: Deploying N-Tier Application 147











Chapter 1. Overview of I/O Streams



Java performs I/O through Streams. A Stream is linked to a physical layer by java I/O system to make input and output operation in java. In general, a stream means continuous flow of data. Streams are clean way to deal with input/output without having every part of your code understand the physical. To bring in information, a program opens a stream on an information source (a file, memory, a socket) and reads the information sequentially, as shown in the following Figure1.

Figure 1. Reading information into a program.

Similarly, a program can send information to an external destination by opening a stream to a destination and writing the information out sequentially, as shown in the following Figure 2.

Figure 2. Writing information out of a program.

No matter where the data is coming from or going to and no matter what its type, the algorithms for sequentially reading and writing data are basically the same. The java.io package contains a collection of stream classes that support these algorithms for reading and writing. To use these classes, a program needs to import the java.io package. The stream classes are divided into two classes,

1.Character Stream

2.Byte Stream

1.Character Streams

Reader and Writer are the abstract superclasses for character streams in java.io. Reader provides the API and partial implementation for readers — streams that read 16-bit characters — and Writer provides the API and partial implementation for writers — streams that write 16-bit characters. Subclasses of Reader and Writer implement specialized streams and are divided into two categories: those that read from or write to data sinks (shown in gray in the following figures) and those that perform some sort of processing (shown in white). The following Figure 3  shows the class hierarchies for theReader and Writer classes.

Figure 3. Classes for Reader and Writer.





Most programs should use readers and writers to read and write textual information. The reason is that they can handle any character in the Unicode character set, whereas the byte streams are limited to ISO-Latin-1 8-bit bytes.

2.Byte Streams

To read and write 8-bit bytes, programs should use the byte streams, descendents of InputStream and OutputStream. InputStream and OutputStream provide the API and partial implementation forinput streams (streams that read 8-bit bytes) and output streams (streams that write 8-bit bytes). These streams are typically used to read and write binary data such as images and sounds. Two of the byte stream classes, ObjectInputStream and ObjectOutputStream, are used for object serialization. As with Reader and Writer, subclasses of InputStream and OutputStream provide specialized I/O that falls into two categories, as shown in the following class hierarchy Figure 4. data sink streams (shaded) and processing streams (unshaded).

I

Figure 4. Classes for InputStream and OutputStream.

nputStream Methods

Commonly used Methods of InputStream class are as follows :

  • available() : returns the number of readable bytes from the input stream.

    public int available() throws IOException
     

  • close() : This method is used to close the input stream and the resource associated to the stream is get released.

    public void close() throws IOException
     

  • mark(int readLimit) : This method is used to mark the current position in the input stream.

    public void mark(int readlimit)
     

  • markSupported() : This method is used to specify that whether the input stream supports the mark and reset methods.

    public boolean markSupported()
     

  • read() : This method is used to read next byte of data of input stream.

    public abstract int read() throws IOException
     

  • read(byte[] b) : This method is used to read the byte from the input stream and kept them to the buffer array.

    public int read(byte[] b) throws IOException
     

  • read(byte[] b, int off, int len) : This method is used to read bytes from the input stream upto the len bytes.

    public int read(byte[] b, int off, int len) throws IOException
     

  • reset() : This method is used to repositioned the stream where the mark method was marked the current position in the input stream.

    public void reset() throws IOException
     

  • skip(long n) : This method is used to skipped over and discarded the data of n bytes from the input stream.

    public long skip(long n) throws IOException

Example:Write to a File

import java.io.*;

public class JavaApplication17 {

public static void main(String[] args) {

try{

FileOutputStream fout=new FileOutputStream("abc.txt"); //create file called abc.txt

String s="Sachin Tendulkar is my favourite player";

byte b[]=s.getBytes();

fout.write(b);

fout.close();

System.out.println("success...");

}catch(Exception e){

System.out.println("Error");

}

}

}

IO(input/output) is a package contains predefined methods and classes which are useful for taking real time input and printing output.A file output stream is an output stream for writing data to a File or to a FileDescriptor. Whether or not a file is available or may be created depends upon the underlying platform.getBytes(): Encodes this String into a sequence of bytes using the platform's default charset, storing the result into a new byte array.

Example:Read from a File

import java.io.*;

public class Simpleread {

public static void main(String args[])

{

try

{

FileInputStream fin=new FileInputStream("abc.txt");//read the content of the file called abc.txt

int i;

while((i=fin.read())!=-1)//check the file upto the end of the file

System.out.print((char)i);

fin.close();

}

catch(Exception e)

{

System.out.println("Errort");

}

}




Character Stream-Reading Console Input:

Java input console is accomplished by reading from System.in. To obtain a character-based stream that is attached to the console, you wrap System.in in a BufferedReader object, to create a character stream. Here is most common syntax to obtain BufferedReader:

BufferedReader br = new BufferedReader(new

InputStreamReader(System.in));

Once BufferedReader is obtained, we can use read( ) method to reach a character or readLine( ) method to read a string from the console.

Reading Characters from Console:

To read a character from a BufferedReader, we would read( ) method whose syntax is as follows:

int read( ) throws IOException

Each time that read( ) is called, it reads a character from the input stream and returns it as an integer value. It returns .1 when the end of the stream is encountered. As you can see, it can throw an IOException.

The following program demonstrates read( ) by reading characters from the console until the user types a "q":

// Use a BufferedReader to read characters from the console.


import java.io.*;


public class BRRead {

public static void main(String args[]) throws IOException

{

char c;

// Create a BufferedReader using System.in

BufferedReader br = new BufferedReader(new

InputStreamReader(System.in));

System.out.println("Enter characters, 'q' to quit.");

// read characters

do {

c = (char) br.read();

System.out.println(c);

} while(c != 'q');

}

}



Reader Class

The abstract class Reader provides a character stream analogous to the byte stream InputStream and the methods of Reader essentially mirror those of InputStream:

  • public int read() throws IOException

    • Reads a single character and returns it as an integer in the range 0 to 65535. If no character is available because the end of the stream has been reached, the value –1 is returned. This method blocks until input is available, the end of stream is found, or an exception is thrown.

  • public abstract int read(char[] buf, int offset, int count) throws IOException

    • Reads into a part of a char array. The maximum number of characters to read is count. The read characters are stored from buf[offset] up to a maximum of buf[offset+count-1]—all other values in buf are left unchanged. The number of characters actually read is returned. If no characters are read because the end of the stream was found, –1 is returned. If count is zero then no characters are read and zero is returned. This method blocks until input is available, the end of stream is found, or an exception is thrown. If the first character cannot be read for any reason other than finding the end of the stream—in particular, if the stream has already been closed—an IOException is thrown. Once a character has been read, any failure that occurs while trying to read characters does not cause an exception, but is treated just like finding the end of the stream—the method completes normally and returns the number of characters read before the failure occurred.

  • public int read(char[] buf) throws IOException

    • Equivalent to read(buf,0, buf.length).

  • public int read(java.nio.CharBuffer buf) throws IOException

    • Attempts to read as many characters as possible into the specified character buffer, without overflowing it. The number of characters actually read is returned. If no characters are read because the end of the stream was found, –1 is returned. This is equivalent to reading into an array that has the same length as the buffer has available capacity, and then copying the array into the buffer. This method is defined in the java.lang.Readable interface, and has no counterpart in InputStream.

  • public long skip(long count) throws IOException

    • Skips as many as count characters of input or until the end of the stream is found. Returns the actual number of characters skipped. The value of count must not be negative.

  • public boolean ready() throws IOException

    • Returns true if the stream is ready to read; that is, there is at least one character available to be read. Note that a return value of false does not guarantee that the next invocation of read will block because data could have become available by the time the invocation occurs.

  • public abstract void close() throws IOException

    • Closes the stream. This method should be invoked to release any resources (such as file descriptors) associated with the stream. Once a stream has been closed, further operations on the stream will throw an IOException. Closing a previously closed stream has no effect.

The implementation of Reader requires that a subclass provide an implementation of both the read method that reads into a char array, and the close method. Many subclasses will be able to improve performance if they also override some of the other methods.

There are a number of differences between Reader and InputStream. With Reader the fundamental reading method reads into a char array and the other read methods are defined in terms of this method. In contrast the InputStream class uses the single-byte read method as its fundamental reading method. In the Reader class subclasses must implement the abstract close method in contrast to inheriting an empty implementation—many stream classes will at least need to track whether or not they have been closed and so close will usually need to be overridden. Finally, where InputStream had an available method to tell you how much data was available to read, Reader simply has a ready method that tells you if there is any data.

As an example, the following program counts the number of whitespace characters in a character stream:

import java.io.*;


class CountSpace {

public static void main(String[] args)

throws IOException

{

Reader in;

if (args.length == 0)

in = new InputStreamReader(System.in);

else

in = new FileReader(args[0]);

int ch;

int total;

int spaces = 0;

for (total = 0; (ch = in.read()) != -1; total++) {

if (Character.isWhitespace((char) ch))

spaces++;

}

System.out.println(total + " chars, "

+ spaces + " spaces");

}

}

This program takes a filename from the command line. The variable in represents the character stream. If a filename is not provided, the standard input stream, System.in, is used after wrapping it in an InputStreamReader, which converts an input byte stream into an input character stream; if a filename is provided, an object of type FileReader is created, which is a subclass of Reader.The for loop counts the total number of characters in the file and the number of spaces, using the Character class's isWhitespace method to test whether a character is whitespace.

Writer Class

The abstract class Writer provides a stream analogous to OutputStream but designed for use with characters instead of bytes. The methods of Writer essentially mirror those of OutputStream, but add some other useful forms of write:

  • public void write(int ch) throws IOException

    • Writes ch as a character. The character is passed as an int but only the lowest 16 bits of the integer are written. This method blocks until the character is written.

  • public abstract void write(char[] buf, int offset, int count) throws IOException

    • Writes part of an array of characters, starting at buf[offset] and writing count characters. This method blocks until the characters have been written.

  • public void write(char[] buf) throws IOException

    • Equivalent to write(buf,0, buf.length).

  • public void write(String str, int offset, int count) throws IOException

    • Writes count characters from the string str onto the stream, starting with str.charAt(offset).

  • public void write(String str) throws IOException

    • Equivalent to write(str,0, str.length()).

  • public abstract void flush() throws IOException

    • Flushes the stream. If the stream has buffered any characters from the various write methods, flush immediately writes them to their destination. Then, if that destination is another stream, it is also flushed. One flush invocation will flush all the buffers in a chain of streams. If a stream is not buffered flush will do nothing.

  • public abstract void close() throws IOException

    • Closes the stream, flushing if necessary. This method should be invoked to release any resources (such as file descriptors) associated with the stream. Once a stream has been closed, further operations on the stream will throw an IOException. Closing a previously closed stream has no effect.

The append(charc) method is equivalent to write(c); the append methods that take a CharSequence are equivalent to passing the String representations of the CharSequence objects to the write(Stringstr) method.

PrintWriter

The PrintWriter class enables you to write formatted data to an underlying Writer. For instance, writing int, long and other primtive data formatted as text, rather than as their byte values.


Example

Import java.io.*;

class test

{

Public static void main(String args[])

{

try

{

PrintWriter pw=new PrintWriter(Sytem.out);

pw.println(true);

pw.println(‘B’);

pw.println(10.22);

pw.println(“Sachin”);

pw.close();

}

catch(Exception e)

{

System.out.println(“Error”);}}}




















Chapter 2. Networking

The term network programming refers to writing programs that execute across multiple devices (computers), in which the devices are all connected to each other using a network.The java.net package of the J2SE APIs contains a collection of classes and interfaces that provide the low-level communication details, allowing you to write programs that focus on solving the problem at hand.The java.net package provides support for the two common network protocols:

  • TCP: TCP stands for Transmission Control Protocol, which allows for reliable communication between two applications. TCP is typically used over the Internet Protocol, which is referred to as TCP/IP.

  • UDP: UDP stands for User Datagram Protocol, a connection-less protocol that allows for packets of data to be transmitted between applications.

If you are programming a client, then you would open a socket like this:

Socket MyClient;

MyClient = new Socket("Machine name", PortNumber);

Where Machine name is the machine you are trying to open a connection to, and PortNumber is the port (a number) on which the server you are trying to connect to is running. When selecting a port number, you should note that port numbers between 0 and 1,023 are reserved for privileged users (that is, super user or root). These port numbers are reserved for standard services, such as email, FTP, and HTTP. When selecting a port number for your server, select one that is greater than 1,023!

In the example above, we didn't make use of exception handling, however, it is a good idea to handle exceptions. (From now on, all our code will handle exceptions!) The above can be written as:

Socket MyClient;

try {

MyClient = new Socket("Machine name", PortNumber);

}

catch (IOException e) {

System.out.println(e);

}

If you are programming a server, then this is how you open a socket:

ServerSocket MyService;

try {

MyServerice = new ServerSocket(PortNumber);

}

catch (IOException e) {

System.out.println(e);

}

When implementing a server you also need to create a socket object from the ServerSocket in order to listen for and accept connections from clients.

Socket clientSocket = null;

try {

serviceSocket = MyService.accept();

}

catch (IOException e) {

System.out.println(e);

}

How do I create an input stream?

On the client side, you can use the DataInputStream class to create an input stream to receive response from the server:

DataInputStream input;

try {

input = new DataInputStream(MyClient.getInputStream());

}

catch (IOException e) {

System.out.println(e);

}

The class DataInputStream allows you to read lines of text and Java primitive data types in a portable way. It has methods such as read, readChar, readInt, readDouble, and readLine,. Use whichever function you think suits your needs depending on the type of data that you receive from the server. On the server side, you can use DataInputStream to receive input from the client:

DataInputStream input;

try {

input = new DataInputStream(serviceSocket.getInputStream());

}

catch (IOException e) {

System.out.println(e);

}

On the client side, you can create an output stream to send information to the server socket using the class PrintStream or DataOutputStream of java.io:

PrintStream output;

try {

output = new PrintStream(MyClient.getOutputStream());

}

catch (IOException e) {

System.out.println(e);

}

The class PrintStream has methods for displaying textual representation of Java primitive data types. Its Write and println methods are important here. Also, you may want to use the DataOutputStream:

DataOutputStream output;

try {

output = new DataOutputStream(MyClient.getOutputStream());

}

catch (IOException e) {

System.out.println(e);

}

The class DataOutputStream allows you to write Java primitive data types; many of its methods write a single Java primitive type to the output stream. The method writeBytes is a useful one.

On the server side, you can use the class PrintStream to send information to the client.

PrintStream output;

try {

output = new PrintStream(serviceSocket.getOutputStream());

}

catch (IOException e) {

System.out.println(e);

}


Example- Simple TCP Client/Server

The following program send the string called ‘welcome’ from server to client

Server

import java.io.*;

import java.net.*;

public class JavaApplication2 {

public static void main(String[] args) {

String s="Welcome";

try

// TODO code application logic here

ServerSocket obj=new ServerSocket(100);//Server wait in this port number for the client request

Socket obj1=obj.accept();//Once server accept the client request JVM will invoke the accept method

PrintWriter p=new PrintWriter(obj1.getOutputStream(),true);//Pass the string to client

p.print(s);

p.close();

obj1.close();

}

catch(Exception e)

{

System.out.println("Server Busy....");

}

}}



Client

import java.net.*;

import java.io.*;

public class Client {

public static void main(String agrs[])

{

try

{

Socket s1=new Socket("localhost",100);//Server Host,Port number of the server

InputStreamReader i=new InputStreamReader(s1.getInputStream());//read the content from the server

BufferedReader b1=new BufferedReader(i);

System.out.println(b1.readLine());

b1.close();

s1.close();

}

catch(Exception e)

{

System.out.println("Client Not Responding");

}}}



TCP Chat Applications

Server

import java.net.*;

import java.io.*;

public class Server {

public static void main(String[] args) throws Exception

{

ServerSocket sersock = new ServerSocket(3000);

System.out.println("Server ready for chatting");

Socket sock = sersock.accept( );

// reading from keyboard (keyRead object)

BufferedReader keyRead = new BufferedReader(new InputStreamReader(System.in));

// sending to client (pwrite object)

OutputStream ostream = sock.getOutputStream();

PrintWriter pwrite = new PrintWriter(ostream, true);

// receiving from server ( receiveRead object)

InputStream istream = sock.getInputStream();

BufferedReader receiveRead = new BufferedReader(new InputStreamReader(istream));

String receiveMessage, sendMessage;

while(true)

{

if((receiveMessage = receiveRead.readLine()) != null)

{

System.out.println(receiveMessage);

}

sendMessage = keyRead.readLine();

pwrite.println(sendMessage);

System.out.flush();

}

}


Client

import java.net.*;

import java.io.*;

public class Client {

public static void main(String[] args) throws Exception

{

Socket sock = new Socket("127.0.0.1", 3000);

// reading from keyboard (keyRead object)

BufferedReader keyRead = new BufferedReader(new InputStreamReader(System.in));

// sending to client

OutputStream ostream = sock.getOutputStream();

PrintWriter pwrite = new PrintWriter(ostream, true);

// receiving from server

InputStream istream = sock.getInputStream();

BufferedReader receiveRead = new BufferedReader(new InputStreamReader(istream));

System.out.println("Start the chitchat, type and press Enter key");

String receiveMessage, sendMessage;

while(true)

{

sendMessage = keyRead.readLine(); // keyboard reading

pwrite.println(sendMessage); // sending to server

System.out.flush(); // flush the data

if((receiveMessage = receiveRead.readLine()) != null) //receive from server

{

System.out.println(receiveMessage); // displaying at DOS prompt

}

}

} }



UDP- DatagramSockets



  • Datagram packets are used to implement a connectionless packet delivery service

  • supported by the UDP

  • Each message is transferred from source machine to destination based on

  • information contained within that packet.

  • That means, each packet needs to have destination address and each packet

  • might be routed differently, and might arrive in any order.

  • Packet delivery is not guaranteed.

Example-UDP Datagram

Sender

import java.net.*;

public class DSender{

public static void main(String[] args) throws Exception {

DatagramSocket ds = new DatagramSocket();

String str = "Welcome java";

InetAddress ip = InetAddress.getByName("127.0.0.1");

DatagramPacket dp = new DatagramPacket(str.getBytes(), str.length(), ip, 3000);

ds.send(dp);

ds.close();

}

}



Receiver

import java.net.*;

public class DReceiver{

public static void main(String[] args) throws Exception {

DatagramSocket ds = new DatagramSocket(3000);

byte[] buf = new byte[1024];

DatagramPacket dp = new DatagramPacket(buf, 1024);

ds.receive(dp);

String str = new String(dp.getData(), 0, dp.getLength());

System.out.println(str);

ds.close();

}

}

Example-UDP Chat Program



import java.net.*;

class UDPServer

{

public static DatagramSocket serversocket;

public static DatagramPacket dp;

public static BufferedReader dis;



public static InetAddress ia;

public static byte buf[] = new byte[1024];

public static int cport = 789,sport=790;

public static void main(String[] a) throws IOException

{

serversocket = new DatagramSocket(sport);

dp = new DatagramPacket(buf,buf.length);

dis = new BufferedReader

(new InputStreamReader(System.in));

ia = InetAddress.getLocalHost();

System.out.println("Server is Running...");

while(true)

{

serversocket.receive(dp);

String str = new String(dp.getData(), 0,

dp.getLength());

if(str.equals("STOP"))

{

System.out.println("Terminated...");

break;

}

System.out.println("Client: " + str);

String str1 = new String(dis.readLine());

buf = str1.getBytes();

serversocket.send(new

DatagramPacket(buf,str1.length(), ia, cport));

}

}

}



import java.net.*;

class UDPClient

{

public static DatagramSocket clientsocket;

public static DatagramPacket dp;

public static BufferedReader dis;

public static InetAddress ia;

public static byte buf[] = new byte[1024];

public static int cport = 789, sport = 790;

public static void main(String[] a) throws IOException

{

clientsocket = new DatagramSocket(cport);

dp = new DatagramPacket(buf, buf.length);

dis = new BufferedReader(new

InputStreamReader(System.in));

ia = InetAddress.getLocalHost();

System.out.println("Client is Running... Type 'STOP'

to Quit");

while(true)

{

String str = new String(dis.readLine());

buf = str.getBytes();

if(str.equals("STOP"))

{

System.out.println("Terminated...");

clientsocket.send(new

DatagramPacket(buf,str.length(), ia,

sport));

break;

}

clientsocket.send(new DatagramPacket(buf,

str.length(), ia, sport));

clientsocket.receive(dp);

String str2 = new String(dp.getData(), 0,

dp.getLength());

System.out.println("Server: " + str2);

}

}

}























Chapter 3.Multithreading



A thread can be defined as a flow of control within a program. The notion of thread is similar to the more familiar notion of process. The difference between a thread and a process becomes clear when we think about the virtualsation of system resources. A process virtualises the operating system resources - a process considers that it owns all the system resources. A thread however virtualises only the program resources - a thread considers that it owns all adress space of the program. The operating system can run a lot of programs (processes) and a program can run a lot of threads. Typically threads are used to do background work in a program. At any given time, there may be many such background threads, performing activities in parallel in an application, like requesting images, updating the screen, playing audio, and so on. But often the threads provide the only way to effectively handle a number of tasks. That is why it is important to understand and to know how to use threads in concurent programming in Java.

Life Cycle of Thread

A thread can be in one of the five states in the thread. According to sun, there is only 4 states new, runnable, non-runnable and terminated. There is no running state. But for better understanding the threads, we are explaining it in the 5 states. The life cycle of the thread is controlled by JVM. The thread states are as follows:

  1. New

  2. Runnable

  3. Running

  4. Non-Runnable (Blocked)

  5. Terminated

1)New

The thread is in new state if you create an instance of Thread class but before the invocation of start() method.

2)Runnable

The thread is in runnable state after invocation of start() method, but the thread scheduler has not selected it to be the running thread.

3)Running

The thread is in running state if the thread scheduler has selected it.

4)Non-Runnable (Blocked)

This is the state when the thread is still alive, but is currently not eligible to run.

5)Terminated

A thread is in terminated or dead state when its run() method exits.

Creating threads

There are two modalities to create threads in Java:

  • Using Thread class;

  • using the Runnable interface

Using Thread Class

public class test extends Thread { //using Thread Class

public void run()

{

try

{

for (int i = 0; i <= 10; i++) {


System.out.println("i::"+i);

}

}catch(Interrupted Exception e)

{

System.out.println(“Error”);

}}}

class sample

{

public static void main(String[] args) {

test t1 = new test();

t1.start();//To Start the Thread

}

}


Using Runnable Interface


public class test implement Runnable {//using Runnable interface

public void run()

{

try

{

for (int i = 0; i <= 10; i++) {


System.out.println("i::"+i);

}

}catch(Interrupted Exception e)

{

System.out.println(“Error”);

}}}

class sample

{

public static void main(String[] args) {

test t1 = new test();

Thread t2 = new Thread(t1);//pass the instance of the class as a parameter of Thread class

t2.start();

}

}

Thread Priority

In Java, thread scheduler can use the thread priorities in the form of integer value to each of its thread to determine the execution schedule of threads . Thread gets the ready-to-run state according to their priorities. The thread scheduler provides the CPU time to thread of highest priority during ready-to-run state.  


 Constant  Description

 Thread.MIN_PRIORITY  The maximum priority of any thread (an int value of 10)

 Thread.MAX_PRIORITY  The minimum priority of any thread (an int value of 1)

 Thread.NORM_PRIORITY  The normal priority of any thread (an int value of 5)


Priorities are integer values from 1 (lowest priority given by the constant. Thread.MIN_PRIORITY) to 10 (highest priority given by the constant Thread.MAX_PRIORITY). The default priority is 5(Thread.NORM_PRIORITY).  


The methods that are used to set the priority of thread shown as:

 

 Method  Description

 setPriority()  This is method is used to set the priority of thread.  

 getPriority()  This method is used to get the priority of thread.





Example

class A extends Thread


{



    public void run()


    {



        System.out.println("Thread A started");


        for(int i=1;i<4;i++)




            System.out.println("Thread A : i="+i); 


        System.out.println("Exit from Thread A ");



    }


}  



 



class B extends Thread


{



    public void run()


    {



        System.out.println("Thread B started");


        for(int i=1;i<4;i++)



            System.out.println("Thread B : i="+i);


        System.out.println("Exit from Thread B");

    }



}  


 



class C extends Thread

{


    public void run()

    {


        System.out.println("Thread C started");

        for(int i=1;i<4;i++)



            System.out.println("Thread C : i="+i);


        System.out.println("Exit from Thread C");



    }

}


 

class ThreadPriority28


{

    public static void main(String args[])


    {

        A threadA = new A();


        B threadB = new B();

        C threadC = new C();


        threadC.setPriority(Thread.MAX_PRIORITY);

        threadB.setPriority(threadA.getPriority);


        threadA.setPriority(Thread.MIN_PRIORITY);

        System.out.println("Start Thread A");  


        threadB.start();

        System.out.println("Start Thread B");  


        threadC.start();

        System.out.println("Start Thread C");  


        threadA.start();

       System.out.println("End of main Thread ");

}

}

}



   
















































Chapter 4.Collection Class & Data Structure

The Java Collections API's provide Java developers with a set of classes and interfaces that makes it easier to handle collections of objects. In a sense Collection's works a bit like arrays, except their size can change dynamically, and they have more advanced behaviour than arrays.The following interfaces (collection types) extends the Collection interface:

  • List

  • Set

  • Map

  • Stack

  • Queue

List

The java.util.List interface is a subtype of the java.util.Collection interface. It represents an ordered list of objects, meaning you can access the elements of a List in a specific order, and by an index too. You can also add the same element more than once to a List.Being a Collection subtype all methods in the Collection interface are also available in the List interface. Since List is an interface you need to instantiate a concrete implementation of the interface in order to use it. You can choose between the following List implementations in the Java Collections API:

  • java.util.ArrayList

  • java.util.LinkedList

  • java.util.Vector

  • java.util.Stack



1)Array List

Arraylist provides methods to manipulate the size of the array that is used internally to store the list. ArrayList extends AbstractList and implements List, Cloneable, Serializable.  ArrayList capacity .grows automatically. The ArrayList is not synchronized. It permits all elements including null.In this program we are inserting a value. We are using three methods of ArrayList class.

  • add(Object o): Appends the specified element to the end of this list. It returns a boolean value.

  • size():  Returns the number of elements in this list.

  • remove(int index): Removes the element at the specified position in this list. It returns the element that was removed from the list. It throws IndexOutOfBoundsException : if index is out of range.

Example

import java.util.*;


public class ArrayListDemo {

public static void main(String args[]) {

// create an array list

ArrayList al = new ArrayList();

System.out.println("Initial size of al: " + al.size());


// add elements to the array list

al.add("C");

al.add("A");

al.add("E");

al.add("B");

al.add("D");

al.add("F");

al.add(1, "A2");

System.out.println("Size of al after additions: " + al.size());


// display the array list

System.out.println("Contents of al: " + al);

// Remove elements from the array list

al.remove("F");

al.remove(2);

System.out.println("Size of al after deletions: " + al.size());

System.out.println("Contents of al: " + al);

}

}



2)LinkedList

The LinkedList is a part of collection that constructs a list containing the elements of the specified collection.If you want to insert the data in the linkedList then use add() method. The hasNext() method returns true if the iterator contains more elements and the next() method returns the next element in the iteration. To insert and remove the data at first, last and specified position in the linkedList, you use theaddFirst()addLast()add()removeFirst()removeLast() and remove() methods. To retrieve the element with respect to a specified position use the getFirst()getLast() and get() methods.

Example

import java.util.*;


public class LinkedListDemo {

public static void main(String args[]) {

// create a linked list

LinkedList ll = new LinkedList();

ll.add("F");

ll.add("B");

ll.add("D");

ll.add("E");

ll.add("C");

ll.addLast("Z");

ll.addFirst("A");

ll.add(1, "A2");

System.out.println("Original contents of ll: " + ll);


// remove elements from the linked list

ll.remove("F");

ll.remove(2);

System.out.println("Contents of ll after deletion: " + ll);

// remove first and last elements

ll.removeFirst();

ll.removeLast();

System.out.println("ll after deleting first and last: "+ ll);

}

}


3.Stack

Stack class is in java.util package of java. Stack works like last in first out policy. Stack does not require any fix dimension like String array and int array. Stack contains many useful methods. To add element in Stack, we can use push() method of Stack class.To get value from Stack, Stack provides pop() method and Stack size() method. Size() method returns total number of elements in Stack. peek() method looks at the object at the top of this stack without removing it from the stack

Example

import java.util.*;

public class StackDemo {

public static void main(String args[]) {

// creating stack

Stack st = new Stack();

// populating stack

st.push("Java");

st.push("Source");

st.push("code");

// removing top object

System.out.println("Removed object is: "+st.pop());

// elements after remove

System.out.println("Elements after remove: "+st);

}

}


Set

A Set is a Collection that cannot contain duplicate elements. It models the mathematical set abstraction.The Set interface contains only methods inherited from Collection and adds the restriction that duplicate elements are prohibited.There are two types

i)HashSet

ii)TreeSet




HashSet

HashSet is Implemented using a hash table. Elements are not ordered. The addremove, and containsmethods have constant time complexity O(1).HashSet  uses equals() method in Java for comparison .


Example:

import java.util.*;

public class HashSetDemo {

public static void main(String args[]) {

// create a hash set

HashSet hs = new HashSet();

hs.add("B");

hs.add("B");//not allow the dublication

hs.add("D"

hs.add("C");

System.out.println(hs);

}

}

Output

C,B,D


TreeSet

TreeSet is implemented using a tree structure(red-black tree in algorithm book). The elements in a set are sorted, but the addremove, and contains methods has time complexity of O(log (n)). TreeSet usescompareTo() method for maintaining ordering

Example:

import java.util.*;

public class HashSetDemo {

public static void main(String args[]) {

// create a Tree set

TreeSet hs = new TreeSet();

hs.add("B");

hs.add("B");//not allow the dublication

hs.add("D"

hs.add("C");

System.out.println(hs);

}

}

Output

B,C,D




Map


The java.util.Map interface represents a mapping between a key and a value. The Map interface is not a subtype of the Collection interface. Therefore it behaves a bit different from the rest of the collection types.There are two types


i)HashMap

ii)TreeMap


i)HashMap

 HashMap is a a data structure, based on hashing, which allows you to store object as key value pair, advantage of using HashMap is that, you can retrieve object on constant time i.e. O(1), if you know the key


Example

import java.util.*;  

class Simple{  

 public static void main(String args[]){  

  HashMap hm=new HashMap();  

  hm.put(100,"Amit");  

  hm.put(101,"Vijay");  

  hm.put(102,"Rahul");  

  Set set=hm.entrySet();  

  Iterator itr=set.iterator();  

  while(itr.hasNext()){  

  Map.Entry m=(Map.Entry)itr.next();  

   System.out.println(m.getKey()+" "+m.getValue());   }  }  }  


Use of Iterator Class

Iterator in Java is nothing but a traversing object, made specifically for Collection objects like List and Set. we have already aware about different kind of traversing methods like for-loop ,while loop,do-while,for each lop etc,they all are  index based traversing but as we know Java is purely object oriented language there is always possible ways of doing things using objects so Iterator is a way to traverse as well as access the data from the collection


Example

public class HashSetExample {

public static void main(String[] args) {

HashSet<String> hs=new HashSet<String>();


// duplicate element is not permitted

hs.add("b");

hs.add("a");

hs.add("c");

hs.add("d");

hs.add("d");

Iterator it=hs.iterator();

while(it.hasNext())

{

String value =(String)it.next();


System.out.println("Value :"+value);

}


//find size of hashSet


System.out.println("Size :"+hs.size());


// Remove element from hashSet :

hs.remove("d");


// To remove all object from hashSet

hs.clear();

}


Difference between Set, List and Map



This data structure is used to contain list of elements. In case you need list of elements and the list may contain duplicate values, then you have to use List- It has some similarities with List, but it can't contain duplicate elements. So when you need a set of data where duplicates are not allowed, you need this data structure.- It contains data as key value pair. When you have to store data in key value pair, so that latter you can retrieve data using the key, you have to use Map data structure.

List allows duplicates -Set doesn't allow duplicates-Map  holds two object per Entry e.g. key and value and It may contain duplicate values but keys are always unique.

If you need to access elements frequently by using index, than List is a way to go. Its implementation e.g. ArrayList provides faster access if you know index. If you want to store elements and want them to maintain an order on which they are inserted into collection then go for List again, as List is an ordered collection and maintain insertion order.- If you want to create collection of unique elements and don't want any duplicate than choose any Set implementation e.g.HashSet, LinkedHashSet or TreeSet-If you store data in form of key and value than Map is the way to go. You can choose from HashtableHashMapTreeMap based upon your subsequent need.



























Chapter 5. Event Handling


Events are supported in java.awt.event.* package.The Delegation Event Model – Event Handling Mechanism .A source generates an event and sends it to one or more listeners. The listener receives the event, processes the events and returns back.

  • Events - Is an object that describes a state change in the source. Ex: Interacting thru the mouse , keyboard click

  • Sources- Is an object that generates an event.Every source can generate more than one event.Every source must register with a listener to receive the notifications. Ex:button

  • Event Listeners-Is an object that is notified when an even occurs.Every source must be registered with a listener so that a listener can receive the notifications when an even occurs.Every listener must implement methods to receive and process the notifications

Event
An event is an object which describes a state change in a source. Events are generally generated when a user interacts with the GUI. Some examples of user generated events are: mouse click, key press, button click etc… Some example of non-user generated events are: timeouts, h/w failures, interrupts etc… Events are reflected as classes in Java.

Event Source
A source is an object on which events are generated. A source can generate more than one event. When an event is generated, there is some change in the state of the event. A source must register with a listener, for the events to be detected. When a listener detects an event, it passes the event to an event handler. Examples of event sources are: button, textbox, list box, drop down box, scrollbars, checkbox, radiobuttons etc…

Event Listeners
A listener is an object which is notified when an event occurs. There are two major requirements that must be satisfied by a listener.It must register with one or more sources to receive events . It must provide event handlers for handling the events. Listeners are reflected as interfaces in Java.

Event Classes
In Java, event classes are the corner stones in event handling. For every event, there is a predefined class in Java. The root class for all the event classes in Java is “EventObject” 
•Almost all the event classes are available in the “java.awt.event” package. The root class for all the event classes in “java.awt” package is “AWTEvent”.





Event Classes-Listener Interfaces

ActionEvent-ActionListener

MouseEvent-MouseListener and MouseMotionListener

MouseWheelEvent-MouseWheelListener

KeyEvent-KeyListener

ItemEvent-ItemListener

TextEvent-TextListener

AdjustmentEvent-AdjustmentListener

WindowEvent-WindowListener

ComponentEvent-ComponentListener

ContainerEvent-ContainerListener

FocusEvent-FocusListener

Steps to perform EventHandling:

Following steps are required to perform event handling :

  1. Implement the Listener interface and overrides its methods

  2. Register the component with the Listener

For registering the component with the Listener, many classes provide the registration methods. For example:

  • Button

    • public void addActionListener(ActionListener a){}

  • MenuItem

    • public void addActionListener(ActionListener a){}

  • TextField

    • public void addActionListener(ActionListener a){}

    • public void addTextListener(TextListener a){}

  • TextArea

    • public void addTextListener(TextListener a){}

  • Checkbox

    • public void addItemListener(ItemListener a){}

  • Choice

    • public void addItemListener(ItemListener a){}

  • List

    • public void addActionListener(ActionListener a){}

    • public void addItemListener(ItemListener a){}

Event Listeners:

•The ActionListener Interface: 
This interface defines the actionPerformed( ) method that is invoked when an action event occurs. Its general form is shown here: 
void actionPerformed(ActionEvent ae) 

•The AdjustmentListener Interface: 
This interface defines the adjustmentValueChanged( ) method that is invoked when an adjustment event occurs. Its general form is shown here: 
void adjustmentValueChanged(AdjustmentEvent ae)

•The ComponentListener Interface: 
This interface defines four methods that are invoked when a component is resized, moved, shown, or hidden. Their general forms are shown here: 
void componentResized(ComponentEvent ce) 
void componentMoved(ComponentEvent ce) 
void componentShown(ComponentEvent ce) 
void componentHidden(ComponentEvent ce) 


The ContainerListener Interface: 
This interface contains two methods. When a component is added to a container, 
componentAdded( ) is invoked. When a component is removed from a container, 
componentRemoved( ) is invoked. Their general forms are shown here: 
void componentAdded(ContainerEvent ce) 
void componentRemoved(ContainerEvent ce)

•The FocusListener Interface: 
This interface defines two methods. When a component obtains keyboard focus, focusGained( ) is invoked. When a component loses keyboard focus, focusLost( ) is called. Their general forms are shown here: 
void focusGained(FocusEvent fe) 
void focusLost(FocusEvent fe) 

•The ItemListener Interface: 
This interface defines the itemStateChanged( ) method that is invoked when the state of an item changes. Its general form is shown here: 
void itemStateChanged(ItemEvent ie)

•The KeyListener Interface: 
This interface defines three methods. The keyPressed( ) and keyReleased( ) methods are invoked when a key is pressed and released, respectively. The keyTyped( ) method is invoked when a character has been entered. 
The general forms of these methods are shown here: 
void keyPressed(KeyEvent ke) 
void keyReleased(KeyEvent ke) 
void keyTyped(KeyEvent ke) 

•The MouseListener Interface: 
This interface defines five methods. If the mouse is pressed and released at the same point, mouseClicked( ) is invoked. When the mouse enters a component, the mouseEntered( ) method is called. When it leaves, mouseExited( ) is called. The mousePressed( ) and mouseReleased( ) methods are invoked when the mouse is pressed and released, respectively.
The general forms of these methods are shown here: 
void mouseClicked(MouseEvent me) 
void mouseEntered(MouseEvent me) 
void mouseExited(MouseEvent me) 
void mousePressed(MouseEvent me) 
void mouseReleased(MouseEvent me)

•The MouseMotionListener Interface
This interface defines two methods. The mouseDragged( ) method is called multiple times as the mouse is dragged. The mouseMoved( ) method is called multiple times as the mouse is moved. Their general forms are shown here: 
void mouseDragged(MouseEvent me) 
void mouseMoved(MouseEvent me) 

•The MouseWheelListener Interface: 
This interface defines the mouseWheelMoved( ) method that is invoked when the mouse wheel is moved. Its general form is shown here: 
void mouseWheelMoved(MouseWheelEvent mwe) 

•The TextListener Interface: 
This interface defines the textChanged( ) method that is invoked when a change occurs in a text area or text field. Its general form is shown here: 
void textChanged(TextEvent te)

•The WindowFocusListener Interface: 
This interface defines two methods: windowGainedFocus( ) and windowLostFocus( ). These are called when a window gains or loses input focus. Their general forms are shown here: 
void windowGainedFocus(WindowEvent we) 
void windowLostFocus(WindowEvent we)

•The WindowListener Interface: 
This interface defines seven methods. The windowActivated( ) and windowDeactivated( ) methods are invoked when a window is activated or deactivated, respectively. If a window is iconified, the windowIconified( ) method is called. When a window is deiconified, the windowDeiconified( ) method is called. When a window is opened or closed, the windowOpened( ) or windowClosed( ) methods are called, respectively. The windowClosing( ) method is called when a window is being closed. The general forms of these methods are: 
void windowActivated(WindowEvent we) 
void windowClosed(WindowEvent we) 
void windowClosing(WindowEvent we) 
void windowDeactivated(WindowEvent we) 
void windowDeiconified(WindowEvent we) 
void windowIconified(WindowEvent we) 
void windowOpened(WindowEvent we)

Example

import java.awt.*;  

import java.awt.event.*;  

 class AEvent extends Frame implements ActionListener{  

TextField tf;  

AEvent(){   

tf=new TextField();  

tf.setBounds(60,50,170,20);  

Button b=new Button("click me");  

b.setBounds(100,120,80,30);  

b.addActionListener(this);  

add(b);

add(tf);  

setSize(300,300);  

setLayout(null);  

setVisible(true);  

  }  

  public void actionPerformed(ActionEvent e){  

tf.setText("Welcome");  

}  

  public static void main(String args[]){  

new AEvent();  

}  

}  

public void setBounds(int xaxis, int yaxis, int width, int height); have been used in the above example that sets the position of the component it may be button, textfield etc.








Output of the above program

Mouse Event Handling Program

import java.awt.*;

import java.awt.event.*;

import java.applet.*;

/*

<applet code="MouseEvents" width=300 height=100>

</applet>

*/


public class MouseEvents extends Applet

implements MouseListener, MouseMotionListener {


String msg = "";

int mouseX = 0, mouseY = 0; // coordinates of mouse


public void init() {

addMouseListener(this);

addMouseMotionListener(this);

}


// Handle mouse clicked.

public void mouseClicked(MouseEvent me) {

// save coordinates

mouseX = 0;

mouseY = 10;

msg = "Mouse clicked.";

repaint();

}


// Handle mouse entered.

public void mouseEntered(MouseEvent me) {

// save coordinates

mouseX = 0;

mouseY = 10;

msg = "Mouse entered.";

repaint();

}


// Handle mouse exited.

public void mouseExited(MouseEvent me) {

// save coordinates

mouseX = 0;

mouseY = 10;

msg = "Mouse exited.";

repaint();

}


// Handle button pressed.

public void mousePressed(MouseEvent me) {

// save coordinates

mouseX = me.getX();

mouseY = me.getY();

msg = "Down";

repaint();

}


// Handle button released.

public void mouseReleased(MouseEvent me) {

// save coordinates

mouseX = me.getX();

mouseY = me.getY();

msg = "Up";

repaint();

}


// Handle mouse dragged.

public void mouseDragged(MouseEvent me) {

// save coordinates

mouseX = me.getX();

mouseY = me.getY();

msg = "*";

showStatus("Dragging mouse at " + mouseX + ", " + mouseY);

repaint();

}


// Handle mouse moved.

public void mouseMoved(MouseEvent me) {

// show status

showStatus("Moving mouse at " + me.getX() + ", " + me.getY());

}


// Display msg in applet window at current X,Y location.

public void paint(Graphics g) {

g.drawString(msg, mouseX, mouseY);

}

}

Chapter 6. Object Serialization


Serialization is a mechanism of writing the state of an object into a byte stream. Java provides a mechanism, called object serialization where an object can be represented as a sequence of bytes that includes the object's data as well as information about the object's type and the types of data stored in the object. After a serialized object has been written into a file, it can be read from the file and deserialized that is, the type information and bytes that represent the object and its data can be used to recreate the object in memory. Most impressive is that the entire process is JVM independent, meaning an object can be serialized on one platform and deserialized on an an entirely different platform. classes ObjectInputStream and  ObjectOutputStream  are high-level streams that contain the methods for serializing and deserializing an object. The ObjectOutputStream class contains many write methods for writing various data types, but one method in particular stands out:

public final void writeObject(Object x) throws IOException

The above method serializes an Object and sends it to the output stream. Similarly, the ObjectInputStream class contains the following method for deserializing an object:

public final Object readObject() throws IOException, ClassNotFoundException

This method retrieves the next Object out of the stream and deserializes it. The return value is Object, so you will need to cast it to its appropriate data type.



Example of Serialization

In this example, we are going to serialize the object of Student class. The writeObject() method of ObjectOutputStream class provides the functionality to serialize the object. We are saving the state of the object in the file named f.txt.

import java.io.*;  

class Persist{  

public static void main(String args[])throws Exception{  

  Student s1 =new Student(211,"sachin");  

  FileOutputStream fout=new FileOutputStream("f.txt");  

  ObjectOutputStream out=new ObjectOutputStream(fout);  

  out.writeObject(s1);  

  out.flush();  

  System.out.println("success");  

 }  }  





ObjectInputStream class:

An ObjectInputStream deserializes objects and primitive data written using an ObjectOutputStream.

Commonly used Constructors:

1) public ObjectInputStream(InputStream in) throws IOException {}creates an ObjectInputStream that reads from the specified InputStream.

Commonly used Methods:

1)public final Object readObject() throws IOException, ClassNotFoundException{}reads an object from the input stream.



Example of Deserialization(for the above program):

import java.io.*;  

class Depersist{  

 public static void main(String args[])throws Exception{   

ObjectInputStream in=new ObjectInputStream(new FileInputStream("f.txt"));  

  Student s=(Student)in.readObject();  

  System.out.println(s.id+" "+s.name); 

  in.close();  

 }  }  



Example Program

import java.io.*;
public class JavaApplication2 {
    public static void main(String[] args) {
        try
        {
            Employee obj=new Employee("prabu",2000,70.12);
            FileOutputStream f=new FileOutputStream("a.txt");
            ObjectOutputStream ob=new ObjectOutputStream(f);
            ob.writeObject(obj);
            ob.flush();
            ob.close();
        }
        catch(Exception e)
        {
            System.out.println("Error");
            System.exit(0);
        }
        try
        {
            Employee obj2;
            FileInputStream fis=new FileInputStream("a.txt");
            ObjectInputStream ob1=new ObjectInputStream(fis);
            obj2=(Employee)ob1.readObject();
            ob1.close();
            System.out.println(obj2);
        }
          catch(Exception e)
        {
            System.out.println("Error");
            System.exit(0);
        }
        
        }
        // TODO code application logic here
    }
class Employee implements Serializable
{
    String name;
    int salary;
    double incentive;
    public Employee(String name,int salary,double incentive)
    {
        this.name=name;
        this.salary=salary;
        this.incentive=incentive;
    }
    public String toString()
    {
        return "name="+name+"Salary="+salary+ "Incentives="+incentive;
    }
}









































Chapter 7. Java RMI


Remote Method Invocation (RMI) is an API that provides a mechanism to create distributed application in java. The RMI allows an object to invoke methods on an object running in another JVM.The RMI provides remote communication between the applications using two objects stub and skeleton.

stub

The stub is an object, acts as a gateway for the client side. All the outgoing requests are routed through it. It resides at the client side and represents the remote object. When the caller invokes method on the stub object, it does the following tasks:

  1. It initiates a connection with remote Virtual Machine (JVM),

  2. It writes and transmits (marshals) the parameters to the remote Virtual Machine (JVM),

  3. It waits for the result

  4. It reads (unmarshals) the return value or exception, and

  5. It finally, returns the value to the caller.

skeleton

The skeleton is an object, acts as a gateway for the server side object. All the incoming requests are routed through it. When the skeleton receives the incoming request, it does the following tasks:

  1. It reads the parameter for the remote method

  2. It invokes the method on the actual remote object, and

  3. It writes and transmits (marshals) the result to the caller.



RMI Architecture

The RMI Architecture (System) has a FOUR layer,

(1)  Application Layer

(2)  Proxy Layer

(3)  Remote Reference Layer

(4)  Transport Layer



RMI Architecture Diagram:

 

(1)  Application Layer:

It’s a responsible for the actual logic (implementation) of the client and server applications.Generally at the server side class contain implementation logic and also apply the reference to the appropriate object as per the requirement of the logic in application.

(2)  Proxy Layer:

It’s also called the “Stub/Skeleton layer”.A Stub class is a client side proxy handles the remote objects which are getting from the reference.A Skeleton class is a server side proxy that set the reference to the objects which are communicates with the Stub.

(3)  Remote Reference Layer (RRL):

It’s a responsible for manage the references made by the client to the remote object on the server so it is available on both JVM (Client and Server).The Client side RRL receives the request for methods from the Stub that is transferred into byte stream process called serialization (Marshaling) and then these data are send to the Server side RRL.The Server side RRL doing reverse process and convert the binary data into object. This process called deserialization or unmarshaling and then sent to the Skeleton class.

(4)  Transport Layer:

It’s also called the “Connection layer”.It’s a responsible for the managing the existing connection and also setting up new connections.So it is a work like a link between the RRL on the Client side and the RRL on the Server side.

Example:

Step 1:Declare the Remote Interface

According to RMI specification, a remote interface is an interface that extends java.rmi.Remote interface and declares a set of methods that may be invoked from a remote Java Virtual Machine(JVM). Note that the java.rmi.Remote interface serves as a mark to tell the system that methods declared within this interface may be invoked from a non-local virtual machine.A remote method is a method that is declared inside a remote interface

importjava.rmi.*;


public interface AddServerIntf extends Remote {

double add(double d1, double d2) throws RemoteException;

}


Here AddServerIntf is remote interface and add Remote method.You may be wondering why the method must throw RemoteException. Because remote method invocation may fail in many ways, like server down, resources unavailable, the method itself may throw exception, etc. If the failure happens, the client should be able to know it via the RemoteException.


Step 2:Implementation class for the above interface


According to the RMI specification, a remote object is one whose methods can be invoked from another Java virtual machine, potentially on a different host(JVM). Do you remember that you have not implemented the remote method add(). The implementation class is a remote object. So we need to design a class which implements the remote interfaceAddServerIntf  and defines the remote method –add()

importjava.rmi.*;

importjava.rmi.server.*;


public class AddServerImpl extends UnicastRemoteObject

implementsAddServerIntf {


publicAddServerImpl() throws RemoteException {

}

public double add(double d1, double d2) throws RemoteException {

return d1 + d2;

}

}




Step 3:Define RMI Server

A typical RMI server is an application that creates a number of remote objects, makes references to those remote objects and waits for clients to invoke methods on those remote objects.In this context, a server is a class. In this class, we need a main method that creates an instance of the remote object, exports the remote object, and then binds that instance to a name in a Java RMI registry

import java.net.*;

importjava.rmi.*;


public class AddServer {

public static void main(String args[]) {

try {

AddServerImpladdServerImpl = new AddServerImpl();

Naming.rebind("AddServer", addServerImpl);

}

catch(Exception e) {

System.out.println("Exception: " + e);

}

}

}



Step 4:Define RMI Client

A typical RMI cient is an application that gets a remote reference to one or more remote objects in the server, then invokes methods on these remote objects.The application forms an URL string using the rmi protocol, the first command line argument and the name "AddServer" that is used by naming registry of the server. The the program calls the method lookup() of theNaming class to find a reference to a remote object. All remote method invocations can then be directed to this object.The client program illustrates the remote call by using the method add(d1,d2) that will be invoked on the remote server machine from the local client machine where the client runs

importjava.rmi.*;

public class AddClient {

public static void main(String args[]) {

try {

String addServerURL = "rmi://" + args[0] + "/AddServer";

AddServerIntfaddServerIntf =

(AddServerIntf)Naming.lookup(addServerURL);

System.out.println("The first number is: " + args[1]);

double d1 = Double.valueOf(args[1]).doubleValue();

System.out.println("The second number is: " + args[2]);


double d2 = Double.valueOf(args[2]).doubleValue();

System.out.println("The sum is: " + addServerIntf.add(d1, d2));

}

catch(Exception e) {

System.out.println("Exception: " + e);

}

}

}

Example 2:Sorting Numbers

AddServerIntf.java


importjava.rmi.*;

public interface AddServerIntf extends Remote {

int[] sort(int a[],int n) throws RemoteException;

}


AddServerImpl.java


importjava.rmi.*;

importjava.rmi.server.*;

public class AddServerImpl extends UnicastRemoteObject implements AddServerIntf

{

publicAddServerImpl() throws RemoteException

{

}

publicint[] sort(int a[],int n) throws RemoteException

{

inti,j,temp;

for(i=0;i<n;i++)

{

for(j=0;j<n-1;j++)

{

if(a[j]>a[j+1])

{

temp=a[j];

a[j]=a[j+1];

a[j+1]=temp;

}

}

}

return a;

}

}



AddClient.java


importjava.rmi.*;

public class AddClient {

public static void main(String args[]) {

try {

inti,n;

String addserverurl="rmi://" +args[0]+ "/AddServer";

AddServerIntfaddserverintf = (AddServerIntf)Naming.lookup(addserverurl);

n=Integer.parseInt(args[1]);

int[] a=new int[n];

for(i=2;i<n+2;i++) {

a[i-2]=Integer.parseInt(args[i]);

}

a=addserverintf.sort(a,n);

System.out.print("Sorted nos:");

for(i=0;i<n;i++) {

System.out.print(" "+a[i]);

}

}

catch(Exception e)

{

System.out.println("Exception: "+e);

}

}

}


AddServer.java


import java.net.*;

importjava.rmi.*;

public class AddServer {

public static void main(String args[]) {

try {

AddServerImpladdserverimpl=new AddServerImpl();

Naming.rebind("AddServer",addserverimpl);

}

catch(Exception e) {

System.out.println("Exception: "+e);

}

}

}



Example 3:File transfer using RMI

FtpServerIntf.java


importjava.rmi.*;

public interface FtpServerIntf extends Remote {

public byte[] download(String filen) throws RemoteException;

}


FtpServerImpl.java


import java.io.*;

importjava.rmi.*;

importjava.rmi.server.*;

public class FtpServerImpl extends UnicastRemoteObject implements FtpServerIntf {

public String file;

publicFtpServerImpl(String s) throws RemoteException {

super();

file = s;

}

public byte[] download(String filen) throws RemoteException {

File fl=new File(filen);

bytebuf[]=new byte[(int)fl.length()];

try {

BufferedInputStreamipfl=new BufferedInputStream(new FileInputStream(filen));

ipfl.read(buf,0,buf.length);

ipfl.close();

}

catch(Exception e) {

System.out.println("FileDownload exception occured");

}

return(buf);

}

}


FtpClient.java


import java.io.*;

importjava.rmi.*;

public class FtpClient {

public static void main(String args[]) {

try {

String ftpserverurl="rmi://"+args[0]+"/FtpServer";

FtpServerIntfftpserverintf = (FtpServerIntf) Naming.lookup(ftpserverurl);

byte[] filedata=ftpserverintf.download(args[1]);

File cfile=new File(args[2]);

BufferedOutputStreamopfl = new BufferedOutputStream(new FileOutputStream(cfile.getName()));

opfl.write(filedata,0,filedata.length);

opfl.flush();

opfl.close();

}

catch(Exception e) {

System.out.println("Exception: "+e);

}

}

}



FtpServer.java


import java.io.*;

importjava.rmi.*;

public class FtpServer {

public static void main(String args[]) {

try {

FtpServerImplftpserverimpl=new FtpServerImpl("FtpServer");

Naming.rebind("FtpServer",ftpserverimpl);

}

catch(Exception e) {

System.out.println("Server Exception");

}

}

}












































Chapter 8. CORBA Architecture


CORBA, or Common Object Request Broker Architecture, is a standard architecture for distributed object systems. It allows a distributed, heterogeneous collection of objects to interoperate. CORBA is a standard defined by the OMG (Object Management Group). It describes architecture, interfaces, and protocols that distributed objects can use to interact with each other. Part of the CORBA standard is the Interface Definition Language (IDL), which is an implementation-independent language for describing the interfaces of remote objects. The OMG comprises over 700 companies and organizations, including almost all the major vendors and developers of distributed object technology, including platform, database, and application vendors as well as software tool and corporate developers. Java IDL is an implementation of the standard IDL-to-Java mapping and is provided by Sun in version 1.3 of Java 2 and is compliant with CORBA 2.x specification. Java IDL provides an Object Request Broker, or ORB. The ORB is a class library that enables low-level communication between Java-IDL applications and other CORBA-compliant applications. Like RMI, Java IDL gives you a way to access remote objects over the network. It also provides tools you need to make your objects accessible to other CORBA clients. If you export a Java class using Java IDL, you can create an object from that class and publish it through a naming/directory service. A remote object can: find this object, call methods on it, and receive data from it, just as if it were running on the client’s local machine. Unlike RMI, objects that are exported using CORBA can be accessed by clients implemented in any language with an IDL binding (C, C++, Ada etc.). The CORBA standard is extensive and provides a rich set of services. A few of the services are:

Service-Description

Object life cycle-Defines how CORBA objects are created, removed, moved, and copied

Naming Service-The CORBA naming service provides a naming structure for remote objects.

Event Service-Another COS that provides a supplier-consumer communication model that creates asynchronous communication between the objects via an Event Channel. The flow of data into the Event Channel is handled by supplier objects, while the flow of data out of the event channel is handled by consumer objects. The Event Service supports both the push and pull model. In the push model, supplier objects control the flow of data by pushing it to consumers and in the pull model, consumer objects control the flow of data by pulling data from the supplier. Instead of directly communicating with each other, the supplier and consumer can each obtain a proxy object from the Event Channel and communicate with it. Supplier objects obtain a consumer proxy and the consumer objects acquire a supplier proxy.

Persistent object service

Transactions-Coordinates atomic access to CORBA objects

Concurrency Control-Provides a locking service for CORBA objects in order to ensure concurrent access



CORBA Products

Several vendors provide CORBA products for various programming languages. The CORBA products that support the Java programming language include:

The Java 2 ORB-The Java 2 ORB comes with Sun's Java 2. It is missing several features. The main feature it has is the ability to look up an object by name.

visiBroker for Java- A popular Java ORB from Inprise Corporation. VisiBroker is also embedded in other products. For example, it is the ORB that embedded in the Netscape Communicator browser.

Orbix- A popular Java ORB from Iona Technologies.

CORBA Architecture

The major components that make up the CORBA architecture include the:

  • Interface Definition Language (IDL), which is how CORBA interfaces are defined,

  • Object Request Broker (ORB), which is responsible for all interactions between remote objects and the applications that use them,

  • The Portable Object Adaptor (POA), which is responsible for object activation/deactivation, mapping object ids to actual object implementations.

  • Naming Service, a standard service in CORBA that lets remote clients find remote objects on the networks, and

  • Inter-ORB Protocol (IIOP).

This figure shows how a one-method distributed object is shared between a CORBA client and server to implement the classic "Hello World" application.

Architectural description:

Any relationship between distributed objects has two sides: the client and the server. The server provides a remote interface, and the client calls a remote interface. These relationships are common to most distributed object standards, including RMI and CORBA. Note that in this context, the terms client and server define object-level rather than application-level interaction--any application could be a server for some objects and a client of others. In fact, a single object could be the client of an interface provided by a remote object and at the same time implement an interface to be called remotely by other objects.On the client side, the application includes a reference for the remote object. The object reference has a stub method, which is a stand-in for the method being called remotely. The stub is actually wired into the ORB, so that calling it invokes the ORB's connection capabilities, which forwards the invocation to the server. On the server side, the ORB uses skeleton code to translate the remote invocation into a method call on the local object. The skeleton translates the call and any parameters to their implementation-specific format and calls the method being invoked. When the method returns, the skeleton code transforms results or errors, and sends them back to the client via the ORBs.Between the ORBs, communication proceeds by means of a shared protocol, IIOP--the Internet Inter-ORB Protocol. IIOP, which is based on the standard TCP/IP internet protocol and works across the Internet, defines how CORBA-compliant ORBs pass information back and forth. Like CORBA and IDL, the IIOP standard is defined by OMG, the Object Management Group. IIOP allows clients using a CORBA product from one vendor to communicate with objects using a CORBA product from another vendor thus permitting interoperability, which is one of the goals of the CORBA standard. In addition to these simple distributed object capabilities, CORBA-compliant ORBs can provide a number of optional services defined by the OMG. These include services for looking up objects by name, maintaining persistent objects, supporting transaction processing, enabling messaging, and many other abilities useful in today's distributed, multi-tiered computing environments. Several ORBs from third-party vendors support some or all of these additional capabilities. The ORB provided with Java IDL supports one optional service, the ability to locate objects by name.

Interface Definition Language (IDL)

  • The services that an object provides are given by its interface. Interfaces are defined in OMG's Interface Definition Language (IDL). IDL is independent of any programming language.

  • Mappings from IDL to specific programming languages are defined as part of the CORBA specification. Mappings for C, C++, Smalltalk, Ada, COBOL, and Java have been approved by OMG.

  • The syntax of both Java and IDL were modeled to some extent on C++, so there are a lot of similarities between the two in terms of syntax. However, there are differences between IDL and Java.

In IDL, you declare only the names and types for interfaces, data members, methods, method arguments etc. You do not include the method implementations. The method implementations are created in implementation language you choose after you’ve used an IDL compiler (idlj is the IDL compiler for Java) to convert your IDL interface to your target language. When you run the idlj compiler over your interface definition file, it generates the Java version of the interface, as well as the class code files for the stubs and skeletons that enable your applications to hook into the ORB.IDL includes, like C++, non-class data structure definitions like structs, unions etc. (these are not part of Java).Method parameters in IDL include modifiers that specify whether they are input, output, or input/output variables. In Java, all primitive data types are passed by value, and all objects are passed by reference. An IDL file can include multiple public interfaces. Java allows multiple inner classes within a single public class definition and multiple nonpublic classes per file, but only a single public class can be defined in a given Java file. Modules, which are similar to Java packages, can be nested within other modules in the same IDL file. In Java, you can define a class only within a single package in a single Java file.




Continue reading this ebook at Smashwords.
Download this book for your ebook reader.
(Pages 1-88 show above.)