

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 add, remove, 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 add, remove, 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 Hashtable, HashMap, TreeMap 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.

Object Request Broker (ORB)

The core of the CORBA architecture is the ORB. Each machine involved in a CORBA application must have an ORB running in order for processes on that machine to interact with CORBA objects running in remote processes. Object clients and servers make requests through their ORBs and the remote ORB locates the appropriate object and passes back the object reference to the requestor.The ORB provides the communication infrastructure needed to identify and locate objects, handles connection management, etc. The ORBs communicate with each other via the IIOP.

Requests made on the client stub are transferred from the client's ORB to the ORB servicing the implementation of the target object. The request is passed onto the implementation through its skeleton interface.Once you run the idlj compiler, you can use the skeletons it generates to put together your server application. In addition to implementing the methods of the remote interface, your server code includes a mechanism to start the ORB and wait for invocation from a remote client.Similarly, you use the stubs generated by the idlj compiler as the basis of your client application. The client code builds on the stubs to start its ORB, look up the server using the name service provided with Java IDL, obtain a reference for the remote object, and call its method.

Naming Service

#### Defines how CORBA objects can be looked up by a name. It is a Common Object Service (COS) and allows an object to be published using a symbolic name and allows clients to obtain references to the object using a standard API.The CORBA naming service provides a naming structure for remote objects.

IIOP

The CORBA standard includes specifications for inter-ORB communication protocols that transmit object requests between various ORBs running on the network. The protocols are independent of the particular ORB implementations running at either end. An ORB implemented in Java can talk to an ORB implemented in C, as long as they are both compliant with the CORBA standard. The inter-ORB protocol delivers messages between two ORBs. These messages might be method requests, return values, error messages etc. The inter-ORB protocol (IIOP) also deals with differences between two ORB implementations, like machine-level byte ordering etc. As a CORBA developer, you don't have to be concerned with the low-level communication protocol between ORBs. If you want two ORBs to talk, just make sure they both speak the same inter-ORB protocol (IIOP).The Inter-ORB Protocol (IIOP) is an inter-ORB protocol based on TCP/IP and so is extensively used on the Internet.

POA

The POA connects the server object implementation to the ORB. It extends the functionality of the ORB and some its services include: activation and deactivation of the object implementations, generation and management of object references, mapping of object references to their implementations, and dispatching of client requests to server objects through a skeleton.

  CORBA Server Object

POA

  ORB

CORBA Example

This example illustrates the basic tasks in building a CORBA distributed application using Java IDL. You will build the classic Hello World program as a distributed application. The Hello World program has a single operation that returns a string to be printed.

1.The client invokes the sayHello method of the HelloServer.

2.The ORB transfers that invocation to the servant object registered for that IDL interface.

3.The servant's sayHello method runs, returning a Java String.

4.The ORB transfers that String back to the client.

5.The client prints the value of the String.

Getting started

You will need two things: version 1.2 of the JDK software and the idltojava compiler. The JDK provides the API and ORB needed to enable CORBA-based distributed object interaction. The idltojava compiler uses the IDL-to-Java mapping to convert IDL interface definitions to corresponding Java interfaces, classes, and methods, which you can then use to implement your client and server code.

Writing the IDL Interface

In this section, you will write a simple IDL interface for the Hello World program. The IDL interface defines the contract between the client and server parts of your application, specifying what operations and attributes are available. OMG IDL is programming-language independent. You must map it to Java before writing any of the implementation code. (Running idltojava on the IDL file does this for you automatically.) Here's the complete Hello.idl file:

module HelloApp

{

interface Hello

{

string sayHello();

};

};

OMG IDL is a purely declarative language designed for specifying programming-language-independent operational interfaces for distributed applications. OMG specifies a mapping from IDL to several different programming languages, including C, C++, Smalltalk, COBOL, Ada, and Java. When mapped, each statement in OMG IDL is translated to a corresponding statement in the programming language of choice. You can use the tool idltojava to map an IDL interface to Java and implement the client class. When you map the same IDL to C++ and implement the server in that language, the Java client and C++ server interoperate through the ORB as though they were written in the same language.

Steps needed to write the IDL for the Hello World application

Step 1: Declaring the CORBA IDL Module

A CORBA module is a namespace that acts as a container for related interfaces and declarations. It corresponds closely to a Java package. Each module statement in an IDL file is mapped to a Java package statement.

module HelloApp {

// Add subsequent lines of code here.

};

Step 2: Declaring the Interface

Like Java interfaces, CORBA interfaces declare the API contract that an object has with other objects. Each interface statement in the IDL maps to a Java interface statement when mapped.

In your Hello.idl file, enter the interface statement:

module HelloApp {

interface Hello // Add

{ // these

// four

}; // lines.

};

When you compile the IDL, this statement will generate an interface statement in the Java code. Your client and server classes will implement the Hello interface in different ways.

Step 3: Declaring the Operations

CORBA operations are the behavior that servers promise to perform on behalf of clients that invoke them. Each operation statement in the IDL generates a corresponding method statement in the generated Java interface.

In your Hello.idl file, enter the operation statement:

module HelloApp {

interface Hello

{

string sayHello(); // Add this line.

}; // notice the semicolon

}; //notice the semicolon

Because our little Hello World application has only a single operation, Hello.idl is now complete.

Mapping Hello.idl from IDL to Java

The tool idltojava reads OMG IDL files and creates the required Java files. The idltojava defaults are set up so that if you need both client and server files (as you do for our Hello World program), you simply enter the tool name and the name of your IDL file:

1.Go to a command line prompt.

2.Change directory to the location of your Hello.idl file.

3.Enter the compiler command:

idltojava Hello.idl

If you list the contents of the directory, you will see that a directory called HelloApp has been created and that it contains five files. Open Hello.java in your text editor. It looks like this:

/* Hello.java as generated by idltojava */

package HelloApp;

public interface Hello

extends org.omg.CORBA.Object {

String sayHello();

}

With an interface this simple, it is easy to see how the IDL statements map to the generated Java statements.

Mapping of IDL Statements to Java Statements

IDL Statement Java Statement

module HelloApp package HelloApp;

interface Hello public interface Hello

string sayHello(); String sayHello();

The single surprising item is the extends statement. All CORBA objects are derived from

org.omg.CORBA.Object to ensure required CORBA functionality. The required code is generated by idltojava; you do not need to do any mapping yourself.

Understanding the idltojava Compiler Output

The idltojava compiler generates a number of files, based on the options chosen on the command line. Because these provide standard functionality, you can ignore them until it is time to deploy and run your program. The five files generated by idltojava are:

_HelloImplBase.java

This abstract class is the server skeleton, providing basic CORBA functionality for the server. It implements the Hello.java interface. The server class HelloServant extends _HelloImplBase.

_HelloStub.java

This class is the client stub, providing CORBA functionality for the client. It implements the Hello.java interface.

Hello.java

This interface contains the Java version of our IDL interface. It contains the single method sayHello. The Hello.java interface extends org.omg.CORBA.Object, providing standard CORBA object functionality as well.

HelloHelper.java

This final class provides auxiliary functionality, notably the narrow method required to cast CORBA object references to their proper types.This narrow() operation highlights one of the differences between RMI and CORBA. An RMI client can automatically download the class bytecodes for a remote stub reference from the object server, if the class for the stub object cannot be found locally. CORBA is a language-independent remote object scheme, so there is no portable way to specify a remote object's type when a client obtains a stub reference. So the stub reference is initially represented a basic ObjectImpl object that knows how to forward method requests to its server methods. The client application is forced to cast this stub reference to the correct local type, using the narrow() method. In the Java mapping of the IDL, this means calling the narrow() method on the corresponding helper class.

HelloHolder.java

This final class holds a public instance member of type Hello. It provides operations for out and inout arguments, which CORBA has but which do not map easily to Java's semantics. When you write the IDL interface, you do all the programming required to generate all these files for your distributed application. The only additional work required is the actual implementation of client and server classes.

Program

Hello.idl:-

module HelloApp

{

interface Hello

{

string sayHello();

oneway void shutdown();

};

};

HelloServer.java

import HelloApp.*;

import org.omg.CosNaming.*;

import org.omg.CosNaming.NamingContextPackage.*;

import org.omg.CORBA.*;

import org.omg.PortableServer.*;

import org.omg.PortableServer.POA;

import java.util.Properties;

class HelloImpl extends HelloPOA

{

private ORB orb;

public void setORB(ORB orb_val)

{

orb = orb_val;

}

public String sayHello()

{

return "\nHello world !!\n";

}

public void shutdown()

{

orb.shutdown(false);

}

}

public class HelloServer

{

public static void main(String args[])

{

try

{

ORB orb = ORB.init(args, null);

POA rootpoa = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));

rootpoa.the_POAManager().activate();

HelloImpl helloImpl = new HelloImpl();

helloImpl.setORB(orb);

org.omg.CORBA.Object ref = rootpoa.servant_to_reference(helloImpl);

Hello href = HelloHelper.narrow(ref);

org.omg.CORBA.Object objRef =orb.resolve_initial_references("NameService");

NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);

String name = "Hello";

NameComponent path[] = ncRef.to_name( name );

ncRef.rebind(path, href);

System.out.println("HelloServer ready and waiting ...");

orb.run();

}

catch (Exception e)

{

System.err.println("ERROR: " + e);

e.printStackTrace(System.out);

}

System.out.println("HelloServer Exiting ...");

}

}

HelloClient.java

import HelloApp.*;

import org.omg.CosNaming.*;

import org.omg.CosNaming.NamingContextPackage.*;

import org.omg.CORBA.*;

public class HelloClient

{

static Hello helloImpl;

public static void main(String args[])

{

try

{

ORB orb = ORB.init(args, null);

org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");

NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);

String name = "Hello";

helloImpl = HelloHelper.narrow(ncRef.resolve_str(name)); System.out.println("Obtained a handle on server object: " + helloImpl);

System.out.println(helloImpl.sayHello());

helloImpl.shutdown();

}

catch (Exception e)

{

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

e.printStackTrace(System.out);

}

}

}

Output:-

Hello.idl:-

HelloServer.java:-

HelloClient.java:-

Program Coding:-

Reverse.idl:-

module ReverseApp

{

interface Reverse

{

string sayHello();

string rev(in string s);

oneway void shutdown();

};

};

ReverseClient.java:-

import ReverseApp.*;

import org.omg.CosNaming.*;

import org.omg.CosNaming.NamingContextPackage.*;

import org.omg.CORBA.*;

public class ReverseClient

{

static Reverse ReverseImpl;

public static void main(String args[])

{

try

{

ORB orb = ORB.init(args, null);

org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");

NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);

String name = "Reverse";

ReverseImpl = ReverseHelper.narrow(ncRef.resolve_str(name));

System.out.println("Obtained a handle on server object: " + ReverseImpl);

System.out.println(ReverseImpl.sayHello());

String str;

str=ReverseImpl.rev("hello");

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

ReverseImpl.shutdown();

}

catch (Exception e)

{

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

e.printStackTrace(System.out);

} } }

ReverseServer.java:-

import ReverseApp.*;

import org.omg.CosNaming.*;

import org.omg.CosNaming.NamingContextPackage.*;

import org.omg.CORBA.*;

import org.omg.PortableServer.*;

import org.omg.PortableServer.POA;

import java.util.Properties;

class ReverseImpl extends ReversePOA

{

private ORB orb;

public void setORB(ORB orb_val)

{

orb = orb_val;

}

public String sayHello()

{

return "\nHello world !!\n";

}

public String rev(String s)

{

int i;

String r="";

for(i=s.length()-1;i>=0;i--)

{

r=r+s.charAt(i);

}

return(r);

}

public void shutdown()

{

orb.shutdown(false);

}

}

public class ReverseServer

{

public static void main(String args[])

{

try

{

ORB orb = ORB.init(args, null);

POA rootpoa = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));

rootpoa.the_POAManager().activate();

ReverseImpl ReverseImpl = new ReverseImpl();

ReverseImpl.setORB(orb);

org.omg.CORBA.Object ref = rootpoa.servant_to_reference(ReverseImpl);

Reverse href = ReverseHelper.narrow(ref);

org.omg.CORBA.Object objRef =orb.resolve_initial_references("NameService");

NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);

String name = "Reverse";

NameComponent path[] = ncRef.to_name( name );

ncRef.rebind(path, href);

System.out.println("ReverseServer ready and waiting ...");

orb.run();

}

catch (Exception e)

{

System.err.println("ERROR: " + e);

e.printStackTrace(System.out);

}

System.out.println("ReverseServer Exiting ...");

}

}

Output:

Hello.idl:-

ReverseServer.java:-

ReverseClient.java:-

Chapter 9. Overview of JINI

Jini is the name for a distributed computing environment, that can offer ``network plug and play''. A device or a software service can be connected to a network and announce its presence. Clients that wish to use such a service can then locate it and call it to perform tasks. This can be used for mobile computing tasks where a service is only connected to a network for a short time, but more generally can be used in any network where there is some degree of change. There are a large number of scenarios where this can be used,

  1. A new printer connected to the network can announce its presence and capabilities. A client can then use this printer without having to be specially configured to do so.

  2. A digital camera can be connected to the network. It can present a user interface that will not only allow pictures to be taken, but is also aware of any printers so that the pictures can be printed if possible.

  3. A configuration file that is copied and modified on individual machines can be made into a network service from a single machine, reducing maintenance costs.

  4. New capabilities extending existing ones can be added to a running system without disruption of existing services, or any need to reconfigure possible clients

  5. Services can announce changes of state, such as a printer running out of paper. Listeners, typically of an administrative nature, can watch for these and flag them for attention

Jini is not an acronym for anything, and does not have a particular meaning. A Jini system or federation is a collection of clients and services all communicating by the Jini protocols. Normally this will consist of applications written in Java, communicating using the Java Remote Method Invocation mechanism. While Jini is written in pure Java, neither clients nor services are constrained to be in pure Java. They may include native code methods, act as wrappers around non-Java objects, or even be written in some other language altogether. They just need to talk the Jini protocols. This gives a Jini federation a flexibility beyond Java, in which the framework is supplied using simple Java mechanisms, but can link services and clients from a variety of sources.

Components

Jini is just one of a large number of distributed systems architectures, including industry-pervasive systems such as CORBA and DCOM. It is distinguished by being based on Java, and deriving many features purely from this Java basis. There are other Java frameworks from Sun which would appear to overlap Jini, such as Enterprise Java Beans. This book does not delve much into the relationships between all these various systems, but the reader should be aware that Jini is only one competitor in a non-empty market. What will condition the success or failure of Jini is partly the politics of the market, but also (hopefully!) the technical capabilities of Jini, and this book will deal with some of the technical issues involved in using Jini.In a running Jini system, there are three main players. There is a service, such as a printer, a toaster, a marriage agency, etc. There is a client which would like to make use of this service. Thirdly, there is a lookup service(service locator) which acts as a broker/trader/locator between services and clients. There is an additional component, and that is a network connecting all three of these, and this network will generally be running TCP/IP. (The Jini specification is fairly independent of network protocol, but the only current implementation is on TCP/IP.)Code will be moved around between these three pieces, and this is done by serializing the objects (and marshalling them to allow storage without reconstitution), and using Java's socket support to send and receive objects. In addition, objects in one JVM (Java Virtual Machine) may need to invoke methods on an object in another JVM and this will typically be done using RMI (Remote Method Invocation), although the Jini specification does not require this (it may require RMI semantics, but not necessarily implementation).

Components of a Jini system

Service Registration

A service will actually be an object (or set of objects) which is living within a server. The server performs various tasks on behalf of the service. The first stage is for the server to register the service with the lookup service/service locator. In order to perform this registration, the server must first find a lookup service. This can be done in two ways: if the location of the lookup service is known, then the server can use unicast TCP to connect directly to it. If the location is not known, the server will make UDP multicast requests, and lookup services will respond to these requests. Lookup services will be listening on port 4160 for both the unicast and multicast requests. When the lookup service gets a request on this port, it sends an object back to the server. This object, known as a registrar, acts as a proxy to the lookup service, and runs in the service's JVM (Java Virtual Machine). Any requests that the server needs to make of the lookup service are made through this proxy registrar. Any suitable protocol may be used to do this, but in practice the implementations that you get of the lookup service (e.g from Sun) will probably use RMI.What the server does with the registrar is to register the service with the lookup service. This involves taking a copy of the service, and storing it on the lookup:

Querying for a service locator

Registrar returned

Service uploaded

Client Lookup

The client on the other hand, is trying to get a copy of the service into its own JVM. It goes through the same mechanism to get a registrar from the lookup service. But this time it does something different with this, which is to request the service to be copied across to it.

Querying for a service locator

Registrar returned

Asking for a service

Service returned

At this stage there is the original service running back on its host. There is a copy of the service stored in the lookup service, and there is a copy of the service running in the client's JVM. The client can make requests of the service object running in its own JVM.

## Chapter 10. Java Beans

JavaBeans are reusable software components for Java. They are classes that encapsulate many objects into a single object (the bean). They are serializable, have a 0-argument constructor, and allow access to properties using getter and setter methods. The following list enumerates some of the benefits that Java Bean technology provides for a component developer:

• ABean obtains all the benefits of Java's "write-once, run-anywhere" paradigm.

• The properties, events, and methods of a Bean that are exposed to another application

can be controlled.

• Auxiliary software can be provided to help configure a Bean. This software is only

needed when the design-time parameters for that component are being set. It does

not need to be included in the run-time environment.

• The configuration settings of a Bean can be saved in persistent storage and restored

at a later time.

• ABean may register to receive events from other objects and can generate events

that are sent to other objects.

Beans have the following characteristics:

Introspection

Introspection is the process by which a builder tool determines and analyzes how a bean works at design and run time. Because the beans are coded with predefined patterns for their method signatures and class definitions, tools that recognize these patterns can "look inside" a bean and determine its properties and behavior. Each bean has a related bean information class, which provides property, method, and event information about the bean itself. Each bean information class implements a BeanInfo interface, which explicitly lists the bean features that will be exposed to application builder tools.

Properties

Properties control a bean's appearance and behavior. Builder tools introspect on a bean to discover its properties and to expose those properties for manipulation. This allows you to change a bean's property at design time.

Customization

The exposed properties of a bean can be customized at design time. Customization allows you to alter the appearance and behavior of a bean. Beans support customization by using property editors or by using special, sophisticated bean customizers.

Events

Beans use the Java event model to communicate with other beans. Beans can fire events. When a bean fires an event it is considered a source bean. A bean can also receive an event, in which case it is considered a listener bean. A listener bean registers its interest in the event with the source bean. Builder tools use introspection to determine those events that a bean sends and those events that it receives.

Persistence

Beans use Java object serialization, by implementing the java.io.Serializable interface, to save and restore states that might have changed as a result of customization. For example, the state is saved when an application customizes a bean in an application builder, so that the changed properties can be restored at a later time.

Methods

All bean methods are identical to methods of other Java classes. Bean methods can be called by other beans or through scripting languages.

### Simple example of java bean class

package mypack;

public class Employee implements java.io.Serializable{

private int id;

private String name;

public Employee(){}

public void setId(int id){

this.id=id;

}

public int getId(){

return id;

}

public void setName(String name){

this.name=name;

}

public String getName(){return name;}

}

### Access the java bean class

package mypack;

public class Test{

public static void main(String args[]){

Employee e=new Employee();//object is created

e.setName("ABC");//setting value to the object

System.out.println(e.getName());

}}

Bean Properties

Properties control a bean's appearance and behavior. Builder tools introspect on a bean to discover its properties and to expose those properties for manipulation. This allows you to change a bean's property at design time. To define a property in a bean class, supply public getter and setter methods. For example, the following methods define an int property called mouthWidth:

public class FaceBean {

private int mMouthWidth = 90;

public int getMouthWidth() {

return mMouthWidth;

}

public void setMouthWidth(int mw) {

mMouthWidth = mw;

}

}

A builder tool like NetBeans recognizes the method names and shows the mouthWidth property in its list of properties. It also recognizes the type, int, and provides an appropriate editor so the property can be manipulated at design time.This example shows a property than can be read and written. Other combinations are also possible. A read-only property, for example, has a getter method but no setter. A write-only property has a setter method only.A special case for boolean properties allows the accessor method to be defined using is instead of get. For example, the accessor for a boolean property running could be as follows:

public boolean isRunning() {

// ...

}

Various specializations of basic properties are available and described in the following sections.

## Indexed Properties

An indexed property is an array instead of a single value. In this case, the bean class provides a method for getting and setting the entire array. Here is an example for an int[] property called testGrades:

public int[] getTestGrades() {

return mTestGrades;

}

public void setTestGrades(int[] tg) {

mTestGrades = tg;

}

For indexed properties, the bean class also provides methods for getting and setting a specific element of the array.

public int getTestGrades(int index) {

return mTestGrades[index];

}

public void setTestGrades(int index, int grade) {

mTestGrades[index] = grade;

}

## Bound Properties

A bound property notifies listeners when its value changes. This has two implications:

  1. The bean class includes addPropertyChangeListener() and removePropertyChangeListener() methods for managing the bean's listeners.

  2. When a bound property is changed, the bean sends a PropertyChangeEvent to its registered listeners.

PropertyChangeEvent and PropertyChangeListener live in the java.beans package. The java.beans package also includes a class, PropertyChangeSupport, that takes care of most of the work of bound properties. This handy class keeps track of property listeners and includes a convenience method that fires property change events to all registered listeners. The following example shows how you could make the mouthWidth property a bound property using PropertyChangeSupport. The necessary additions for the bound property are shown in bold.

import java.beans.*;

public class FaceBean {

private int mMouthWidth = 90;

private PropertyChangeSupport mPcs =

new PropertyChangeSupport(this);

public int getMouthWidth() {

return mMouthWidth;

}

public void setMouthWidth(int mw) {

int oldMouthWidth = mMouthWidth;

mMouthWidth = mw;

mPcs.firePropertyChange("mouthWidth",

oldMouthWidth, mw);

}

public void

addPropertyChangeListener(PropertyChangeListener listener) {

mPcs.addPropertyChangeListener(listener);

}

public void

removePropertyChangeListener(PropertyChangeListener listener) {

mPcs.removePropertyChangeListener(listener);

}

}

Bound properties can be tied directly to other bean properties using a builder tool like NetBeans. You could, for example, take the value property of a slider component and bind it to the mouthWidth property shown in the example. NetBeans allows you to do this without writing any code.

## Constrained Properties

A constrained property is a special kind of bound property. For a constrained property, the bean keeps track of a set of veto listeners. When a constrained property is about to change, the listeners are consulted about the change. Any one of the listeners has a chance to veto the change, in which case the property remains unchanged.

The veto listeners are separate from the property change listeners. Fortunately, the java. beans package includes a VetoableChangeSupport class that greatly simplifies constrained properties.Changes to the mouthWidth example are shown in bold:

import java.beans.*;

public class FaceBean {

private int mMouthWidth = 90;

private PropertyChangeSupport mPcs =

new PropertyChangeSupport(this);

private VetoableChangeSupport mVcs =

new VetoableChangeSupport(this);

public int getMouthWidth() {

return mMouthWidth;

}

public void

setMouthWidth(int mw) throws PropertyVetoException {

int oldMouthWidth = mMouthWidth;

mVcs.fireVetoableChange("mouthWidth",

oldMouthWidth, mw);

mMouthWidth = mw;

mPcs.firePropertyChange("mouthWidth",

oldMouthWidth, mw);

}

public void

addPropertyChangeListener(PropertyChangeListener listener) {

mPcs.addPropertyChangeListener(listener);

}

public void

removePropertyChangeListener(PropertyChangeListener listener) {

mPcs.removePropertyChangeListener(listener);

}

public void

addVetoableChangeListener(VetoableChangeListener listener) {

mVcs.addVetoableChangeListener(listener);

}

public void

removeVetoableChangeListener(VetoableChangeListener listener) {

mVcs.removeVetoableChangeListener(listener);

}

}

Events in Bean Box

BeanBox is a test container in BDK. We can use BeanBox to create Application, Applet, and New Beans. We can lay out, edit and interconnect beans visually. That is one of the benefits of Javabeans is the capability for the beans to be used in visual application builder tools. Before installing BDK, we have to install JDK version 1.1 or later first and then install BDK. There is a "beanbox" directory insidne of BDK (assume "BDK" is a directory for JavaBeans"). BeanBox comes with the batch file, called run.bat in the "beanbox" directory. If we type in "run", it would displays 3 windows: The first window is Toolbox, it lists all the beans registered for use with BeaBox. We also can write our own beans and add them to this window. The second window is BeanBox, it is the main container window. Last window is Propertysheet, it lists the properties associated with the current selected bean. It is responsible for providing the visual editing capabilities of the BeanBox.

The following is the picture of the windows from Starting and Using the BeanBox

The BeanBox allows you to:

  * Drop beans onto a composition window

  * Resize and move beans around

  * Edit the exported properties of a bean

  * Run a customizer to configure a bean

  * Connect a bean event source to an event handler method

  * Connect together bound properties on different beans

  * Save and restore sets of beans

  * Making applets from beans

  * Get an introspection report on a bean

  * Add new beans from JAR files

Using the BeanBox

Let's create a simple application using BeanBox. We are going to select "OurButton" from the ToolBox window and place it somewhere in the BeanBox window. We are going to edit this bean in the Propertysheet window, change the label to "Start". We are going to select another button, and call it "Stop". Now let's get something exciting, select the "Juggler" bean. A useful function of BeanBox is that we can wire beans together using events, we can do that visully, this makes it very easy. Click the "Start" button, go to Edit and Event, select Action Event Menu item, and then select Actionperformed. Now we can see a line originating from the "Start" button that moves as the mouse moved around. We are going to move the mouse over the "Juggle" bean. Click to connect the button bean's action event to the "Juggle" bean. Select "start Juggle" method from Dialog box. We are going to do the same thing for "Stop" button. Now, we can click "stop" and "start" to control the animation. We also can save the bean by using the save command. If we clear this out, we can reload the application by opening it. This is a easy and fun to play with.

## Using Example Beans

The easiest way to understand how BeanBox works is to use it. You can construct simple beans applications without writing any Java code using BeanBox. As a first example, you can build a simple "Juggling Duke" application in which Duke will start or stop juggling depending on which of two buttons you push.

The first thing to do is add the Juggler Bean. Starting with an empty BeanBox select the Juggler Bean from the list of Beans in the Toolbox window.

Now, placing the cursor anywhere in the BeanBox will cause a Juggler Bean to be inserted in the design form. The highlighted box surrounding the Juggler indicates the Juggler is the currently selected bean.

Next, you'll need to add a start button and a stop button to control the juggler. Each of these Beans is an instance of the OurButton Bean class.

Place an instance of the button in the form.

To change the label on the button, edit the label field in the property sheet to read "start."

The text for the button changes at the same time you type it into the property sheet editor.

The next step is to specify an event to be fired by the button. A corresponding event-handler method is then selected for the Juggler Bean.

Use the edit menu to select an action event to be fired by the start button. Note that in order for this to work, the start button must be selected.

Once the actionPerformed menu selection is made, BeanBox enters a state where a line emanates from the start button and follows the mouse as you move it around the window. This indicates that the button is the selected source for the action event, and that your next mouse press should be over the target which defines appropriate event-handler methods, in this case the Juggler.

When you drag the line from the start button and release it over the Juggler Bean, a dialog appears listing applicable event handlers defined by the Juggler Bean.

Select the start method as the target for the event, then press OK. You can now press the start button; Duke should start tossing beans around in a circle over his head like a professional juggler. You can control Duke's juggling speed by manually setting the propery value labeled animationRate in the Juggler's property sheet editor. For the appropriate property sheet editor to appear, the Juggler must be the currently selected Bean within the BeanBox frame.

To complete the example program, you need to add a stop button. Again, from the list of available beans in the Toolbox menu select OurButton.

Drag the button just below the start button, and drop it in place. Make sure the new button is the currently selected Bean. If it is, the appropriate property editor appears to the right.

Edit the label field of the property sheet to read "start." The button's label reflects your changes as you type.

Hook up the action event from the stop button to the Juggler's stop event-handler method. Make sure the stop button is the currently selected bean. Select the actionPerformed event from the Edit/Events menu.

Now drag the event line from the button source to the Juggler Bean target. Press and release the mouse button with the connection line over the Juggler. You'll now see the dialog of applicable event-handler methods defined for the Juggler Bean.

Select the stop event. Now you're finished. You should be able to start and stop the juggler by pressing the appropriate button.

Bean Customization

A Bean's appearance and behavior can be customized at design time within Beans-compliant builder tools. Typically there are two ways to customize a Bean:

  * By using a property editor. Each Bean property has its own property editor. A builder tool usually displays a Bean's property editors in a property sheet. A property editor is associated with, and edits a particular property type.

  * By using customizers. Customizers give you complete GUI control over Bean customization. Customizers are used where property editors are not practical or applicable. Unlike a property editor, which is associated with a property, a customizer is associated with a Bean.

### i)Property Editors

A property editor is a tool for customizing a particular property type. Property editors are displayed in, or activated from property sheets. A property sheet will determine a property's type, search for a relevant property editor, and display the property's current value in a relevant way.

Property editors must implement the PropertyEditor interface. PropertyEditor provides methods that specify how a property should be displayed in a property sheet.

Here is the BeanBox's Properties sheet containing OurButton properties:

ii)Bean customizers

A customizer is an additional dialog that users can launch to change Java bean properties. You can create customizer classes for editing properties of Java beans that you add to the visual editor.

A customizer class should implement the interface java.beans.Customizer, and should also be a subclass of java.awt.Component. Usually, a customizer is a container such as a java.awt.Panel or javax.swing.JPanel that contains the controls to let you view and manipulate your Java bean's properties. When the customizer is launched from the toolbar button, it is hosted inside a dialog that has OK and Cancel buttons.

When a user opens a customizer, the customizer is given the Java bean it is customizing as part of the method public void setObject(Object bean);. The customizer is then able to make changes directly to the argument.

The java.beans.Customizer interface also has the methods public void addPropertyChangeListener(PropertyChangeListener listener); and public void removePropertyChangeListener(PropertyChangeListener listener). The visual editor will add itself as a listener on the customizer, and if the customizer is to refresh the appearance of the Java bean on the Design view, it should signal a property change by calling its listeners with any of the methods firePropertyChange(... with any set of arguments.

When your user clicks OK, the visual editor will try to determine what changes the customizer has made to the Java bean so it can update the Java source code. To do this, the visual editor takes a copy of all the Java bean's properties before the customizer is launched, and then compares them with the properties when the customizer is closed. If any property is different ( returns false to the equals method), it is determined to have been changed. To determine the argument to the set method for the property, the property editor on the java.beans.PropertyDescriptor is created. Then, it is called with public void setValue(Object) and public String getJavaInitializationString();. Likewise, when you click Cancel, because the customizer has already changed the Java bean, the visual editor queries the set of properties and resets any that are different to their initial state.

If the customizer is a top level shell that does not require a dialog to run within, such as a java.awt.Frame or javax.swing.JFrame, the visual editor will run the customizer as is. Because this type of customizer is responsible for its own set of buttons and the visual editor has no way of knowing whether it was canceled or confirmed, whenever the customizer is closed, the top level properties are queried to see whether they have changed. Thus, if the customizer performs a cancel it must do so, thereby ensuring the Java bean's properties are restored to their initial state.

After you write a customizer, it needs to be set on the bean descriptor for the BeanInfo class for the Java bean:

public class MyClassBeanInfo extends SimpleBeanInfo {

public BeanDescriptor getBeanDescriptor() {

return new BeanDescriptor(MyClass.class,

MyCustomizer.class);

}

}

All customizers must:

  * Extend java.awt.Component or one of its subclasses.

  * Implement the java.beans.Customizer interface This means implementing methods to register PropertyChangeListener objects, and firing property change events at those listeners when a change to the target bean has occurred.

  * Implement a default constructor.

  * Associate the customizer with its target class via BeanInfo.getBeanDescriptor.

# Bean Persistence

A bean has the property of persistence when its properties, fields, and state information are saved to and retrieved from storage. Component models provide a mechanism for persistence that enables the state of components to be stored in a non-volatile place for later retrieval.The mechanism that makes persistence possible is called _serialization_. Object serialization means converting an object into a data stream and writing it to storage. Any applet, application, or tool that uses that bean can then "reconstitute" it by deserialization. The object is then restored to its original state.For example, a Java application can serialize a Frame window on a Microsoft Windows machine, the serialized file can be sent with e-mail to a Solaris machine, and then a Java application can restore the Frame window to the exact state which existed on the Microsoft Windows machine.All beans must persist. To persist, your beans must support serialization by implementing either the java.io.Serializable (in the API reference documentation) interface, or the java.io.Externalizable (in the API reference documentation) interface. These interfaces offer you the choices of automatic serialization and customized serialization. If any class in a class's inheritance hierarchy implements Serializable or Externalizable, then that class is serializable.

## The Serializable Interface

The Serializable interface provides automatic serialization by using the Java Object Serialization tools. Serializable declares no methods; it acts as a marker, telling the Object Serialization tools that your bean class is serializable. Marking your class Serializable means you are telling the Java Virtual Machine (JVM) that you have made sure your class will work with default serialization. Here are some important points about working with the Serializable interface:

## The Externalizable Interface

Use the Externalizable interface when you need complete control over your bean's serialization (for example, when writing and reading a specific file format). To use the Externalizable interface you need to implement two methods: readExternal and writeExternal. Classes that implement Externalizable must have a no-argument constructor.

Example:

import javax.swing.JButton;

import java.awt.*;

import java.io.Serializable;

public class test extends JButton implements Serializable {

private Image img;

public test() {

img=null;

}

public void setImage(Image i) {

img=i;

}

public void paint(Graphics g) {

if (img != null)

g.drawImage(img, 0, 0,null);

else {

g.setColor(Color.red);

Dimension size = getSize();

g.fillOval(0, 0, size.width, size.height);

}

}

}

  * All beans must contain a constructor with no parameters. My constructor initializes my only property/member variable (img).

  * All beans must contain 'implements Serializable'. You don't need to override any of these functions but you have to have that in your class definition. Serializable lets the IDE save your property values during design time.

  * Any properties of your bean must have get and set functions if you want to have them show up in property lists. I only have one property and it is write only so I created a function called 'setImage()'.

  * Beans apparently need to meet security considerations and so probably won't let you do certain things like access local files.

In menu system do: tools -> palette -> Swing/AWT Components  
there should be 3 buttons. Eventually you might want to choose Add from JAR but we will do:  
Add From Project... There may be a delay at this point. Then Click next. Your component should show up. Click it and click 'next' again.Select a folder to put your bean into - choose "Beans". Click 'finish'. Now you should see your been in the pallette near the bottom in the Beans section. Open up the beans section if it isn't already. Click your bean and then click in your window to place it. That's it.

Output

JAR File

A JAR (Java ARchive) file is a file that contains the class, image, and sound files for a Java application or applet gathered into a single file and possibly compressed. When a programmer gets a Java program development kit, a small program or utility called "jar" is included. The jar utility lets the programmer create, list, or extract the individual files from a JAR file.JAR file is the compressed file format. You can store many files in a JAR file. JAR stands for the Java Archive. This file format is used to distribute a set of java classes. This file helps you to reduce the file size and collect many file in one by compressing files. Downloading the files are become completed in very short duration of time because of reducing the file size. You can make the jar file executable by collecting many class file of your java application in it. The jar file can execute from the javaw (Java Web Start).The JAR file format is based on the popular ZIP file format. Usually these file format is not only used for archiving and distribution the files, these are also used for implementing various libraries, components and plug-ins in java applications. Compiler and JVMs (Java Virtual Machine) can understand and implement these formats for java application.

For mentioning the product information like vendor name, product version, date of creation of the product and many other things related to the product are mentioned in the manifest file. Such type of files are special which are mentioned in the jar file for making it executable for the application. This file format is to be used for collecting auxiliary files associated with the components.To perform basic operations for the jar file there has to be used the Java Archive Tool (jar tool). It is provided by the jdk (Java Development Kit). Following are some jar command which are invoked by the jar tool:

Functions&Command

1)creation a jar file

jar cf jar-file-name file-name(s)_or_directory-name

2)viewing contents of a jar file

jar tf jar-file-name

3)viewing contents with detail of a jar file

jar tvf jar-file-name

4)extract all the files of a jar file

jar xf jar-file-name

5)extract specific files from the jar file

jar xf jar-file-name file-name(s)_from_jar-file

6)update jar files

jar uf jar-file-name file-name(s)_from_jar-file

7)running a executable packaged jar file

java -jar jar-file-name

Chapter 11. Overview of Swing

Swing is a set of program component s for Java programmers that provide the ability to create graphical user interface ( GUI ) components, such as buttons and scroll bars, that are independent of the windowing system for specific operating system . Swing components are used with the Java Foundation Classes

## Swing features

  * Light Weight \- Swing component are independent of native Operating System's API as Swing API controls are rendered mostly using pure JAVA code instead of underlying operating system calls.

  * Rich controls \- Swing provides a rich set of advanced controls like Tree, TabbedPane, slider, colorpicker, table controls

  * Highly Customizable \- Swing controls can be customized in very easy way as visual apperance is independent of internal representation.

  * Pluggable look-and-feel\- SWING based GUI Application look and feel can be changed at run time based on available values.

Swing VS AWT

AWT-Swing

AWT stands for Abstract windows toolkit.-Swing is also called as JFC's (Java Foundation classes).

AWT components are called Heavyweight component.-Swings are called light weight component because swing components sits on the top of AWT components and do the work.

AWT components require java.awt package.-Swing components require javax.swing package.

AWT components are platform dependent.-Swing components are made in purely java and they are platform independent.

Why Swing Components Are Lightweight

With very few exceptions, Swing components are lightweight. This means that they are written entirely in Java and do not map directly to platform-specific peers. Because lightweight components are rendered using graphics primitives, they can be transparent, which enables nonrectangular shapes. Thus, lightweight components are more efficient and more flexible.Furthermore, because lightweight components do not translate into native peers, the look and feel of each component is determined by Swing, not by the underlying operating system. This means that each component will work in a consistent manner across all platforms.

Swing Supports a Pluggable Look and Feel

Swing supports a pluggable look and feel (PLAF). Because each Swing component is renderedby Java code rather than by native peers, the look and feel of a component is under the control of Swing. This fact means that it is possible to separate the look and feel of a component from the logic of the component, and this is what Swing does. Separating out the look and feel provides a significant advantage: it becomes possible to change the way that a component is rendered without affecting any of its other aspects. In other words, it is possible to "plug in" a new look and feel for any given component without creating any side effects in the code that uses that component. Moreover, it becomes possible to define entire sets of look-and-feels that represent different GUI styles. To use a specific style, its look and feel is simply "plugged in." Once this is done, all components are automatically rendered using that style.

Components and Containers

A Swing GUI consists of two key items: components and containers. However, this distinction is mostly conceptual because all containers are also components. The difference between the two is found in their intended purpose: As the term is commonly used, a component is an independent visual control, such as a push button or slider. A container holds a group of components. Thus, a container is a special type of component that is designed to hold other components. Furthermore, in order for a component to be displayed, it must be held within a container. Thus, all Swing GUIs will have at least one container. Because containers are components, a container can also hold other containers. This enables Swing to define what is called a containment hierarchy, at the top of which must be a top-level container. Let's look a bit more closely at components and containers.

Components

In general, Swing components are derived from the JComponent class. (The only exceptions to this are the four top-level containers, described in the next section.) JComponent provides the functionality that is common to all components. For example, JComponent supports the pluggable look and feel. JComponent inherits the AWT classes Container and component. Thus, a Swing component is built on and compatible with an AWT component. All of Swing's components are represented by classes defined within the package javax.swing. The following table shows the class names for Swing components (including those used as containers).

Containers

Swing defines two types of containers. The first are top-level containers: JFrame, JApplet,JWindow, and JDialog. These containers do not inherit JComponent. They do, however, inherit the AWT classes Component and Container. Unlike Swing's other components,which are lightweight, the top-level containers are heavyweight. This makes the top-levelcontainers a special case in the Swing component library.As the name implies, a top-level container must be at the top of a containment hierarchy.Atop-level container is not contained within any other container. Furthermore, every containment hierarchy must begin with a top-level container. The one most commonly used for applications is JFrame. The one used for applets is JApplet.The second type of containers supported by Swing are lightweight containers. Lightweight containers do inherit JComponent. An example of a lightweight container is JPanel, whichis a general-purpose container. Lightweight containers are often used to organize and manage groups of related components because a lightweight container can be contained within another container. Thus, you can use lightweight containers such as JPanel to create subgroups of related controls that are contained within an outer container.

The main package is javax.swing. This package must be imported into any program that uses Swing. It contains the classes that implement the basic Swing components, such as push buttons, labels, and check boxes.

A Simple Swing Application

Swing programs differ from both the console-based programs and the AWT-based programs shown earlier in this book. For example, they use a different set of components and a different container hierarchy than does the AWT. Swing programs also have special requirements that relate to threading. The best way to understand the structure of a Swing program is to work through an example. There are two types of Java programs in which Swing is typically used. The first is a desktop application. The second is the applet. This section shows how to create a Swing application Although quite short, the following program shows one way to write a Swing application.In the process, it demonstrates several key features of Swing. It uses two Swing components: JFrame and JLabel. JFrame is the top-level container that is commonly used for Swing applications. JLabel is the Swing component that creates a label, which is a component that displays information. The label is Swing's simplest component because it is passive. That is, a label does not respond to user input. It just displays output. The program uses a JFrame container to hold an instance of a JLabel. The label displays a short text message.

// A simple Swing application.

import javax.swing.*;

class SwingDemo {

SwingDemo() {

// Create a new JFrame container.

JFrame jfrm = new JFrame("A Simple Swing Application");

// Give the frame an initial size.

jfrm.setSize(275, 100);

// Terminate the program when the user closes the application.

jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

// Create a text-based label.

JLabel jlab = new JLabel(" Swing means powerful GUIs.");

// Add the label to the content pane.

jfrm.add(jlab);

// Display the frame.

jfrm.setVisible(true);

}

public static void main(String args[]) {

// Create the frame on the event dispatching thread.

SwingUtilities.invokeLater(new Runnable() {

public void run() {

new SwingDemo();

}

});

}

}

Swing programs are compiled and run in the same way as other Java applications. Thus,

to compile this program, you can use this command line:

javac SwingDemo.java

To run the program, use this command line:

java SwingDemo

When the program is run, it will produce the window shown

Because the SwingDemo program illustrates several core Swing concepts, we will examine it carefully, line by line. The program begins by importing javax.swing. As mentioned, this package contains the components and models defined by Swing. For example, javax.swing defines classes that implement labels, buttons, text controls, and menus. It will be included in all programs that use Swing.Next, the program declares the SwingDemo class and a constructor for that class. The constructor is where most of the action of the program occurs. It begins by creating a JFrame, using this line of code:

JFrame jfrm = new JFrame("A Simple Swing Application");

This creates a container called jfrm that defines a rectangular window complete with a titlebar; close, minimize, maximize, and restore buttons; and a system menu. Thus, it creates a standard, top-level window. The title of the window is passed to the constructor.Next, the window is sized using this statement:

jfrm.setSize(275, 100);The setSize( ) method (which is inherited by JFrame from the AWT class Component) sets the dimensions of the window, which are specified in pixels. Its general form is shown here:void setSize(int width, int height).In this example, the width of the window is set to 275 and the height is set to 100. By default, when a top-level window is closed (such as when the user clicks the closebox), the window is removed from the screen, but the application is not terminated. While this default behavior is useful in some situations, it is not what is needed for most applications.Instead, you will usually want the entire application to terminate when its top-level window is closed. There are a couple of ways to achieve this. The easiest way is to call setDefaultCloseOperation( ), as the program does:

jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

After this call executes, closing the window causes the entire application to terminate. The general form of setDefaultCloseOperation( ) is shown here:

void setDefaultCloseOperation(int what)

The value passed in what determines what happens when the window is closed. There are

several other options in addition to JFrame.EXIT_ON_CLOSE. They are shown here:

JFrame.DISPOSE_ON_CLOSE

JFrame.HIDE_ON_CLOSE

JFrame.DO_NOTHING_ON_CLOSE

Their names reflect their actions. These constants are declared inWindowConstants, which is an interface declared in javax.swing that is implemented by JFrame.

The next line of code creates a Swing JLabel component:

JLabel jlab = new JLabel(" Swing means powerful GUIs.");

JLabel is the simplest and easiest-to-use component because it does not accept user input. It simply displays information, which can consist of text, an icon, or a combination of the two. The label created by the program contains only text, which is passed to its constructor.

The next line of code adds the label to the content pane of the frame:

jfrm.add(jlab);

Event Handling in SWING

The event handling mechanism used by Swing is the same as that used by the AWT.This approach is called the delegation event model.In many cases, Swing uses the same events as does the AWT, and these events are packaged in java.awt.event. Events specific to Swing are stored in javax.swing.event

Example

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import java.util.*;

public class Sample10 extends JFrame {

private JButton jbtNum1;

private JButton jbtNum2;

private JButton jbtNum3;

private JButton jbtNum4;

private JButton jbtNum5;

private JButton jbtNum6;

private JButton jbtNum7;

private JButton jbtNum8;

private JButton jbtNum9;

private JButton jbtNum0;

private JButton jbtEqual;

private JButton jbtAdd;

private JButton jbtSubtract;

private JButton jbtMultiply;

private JButton jbtDivide;

private JButton jbtSolve;

private JButton jbtClear;

private double TEMP;

private double SolveTEMP;

private JTextField jtfResult;

Boolean addBool = false ;

Boolean subBool = false ;

Boolean divBool = false ;

Boolean mulBool = false ;

String display = "";

public Sample10() {

JPanel p1 = new JPanel();

p1.setLayout(new GridLayout(4, 3));

p1.add(jbtNum1 = new JButton("1"));

p1.add(jbtNum2 = new JButton("2"));

p1.add(jbtNum3 = new JButton("3"));

p1.add(jbtNum4 = new JButton("4"));

p1.add(jbtNum5 = new JButton("5"));

p1.add(jbtNum6 = new JButton("6"));

p1.add(jbtNum7 = new JButton("7"));

p1.add(jbtNum8 = new JButton("8"));

p1.add(jbtNum9 = new JButton("9"));

p1.add(jbtNum0 = new JButton("0"));

p1.add(jbtClear = new JButton("C"));

JPanel p2 = new JPanel();

p2.setLayout(new FlowLayout());

p2.add(jtfResult = new JTextField(20));

jtfResult.setHorizontalAlignment(JTextField.RIGHT);

jtfResult.setEditable(false);

JPanel p3 = new JPanel();

p3.setLayout(new GridLayout(5, 1));

p3.add(jbtAdd = new JButton("+"));

p3.add(jbtSubtract = new JButton("-"));

p3.add(jbtMultiply = new JButton("*"));

p3.add(jbtDivide = new JButton("/"));

p3.add(jbtSolve = new JButton("="));

JPanel p = new JPanel();

p.setLayout(new GridLayout());

p.add(p2, BorderLayout.NORTH);

p.add(p1, BorderLayout.SOUTH);

p.add(p3, BorderLayout.EAST);

add(p);

jbtNum1.addActionListener(new ListenToOne());

jbtNum2.addActionListener(new ListenToTwo());

jbtNum3.addActionListener(new ListenToThree());

jbtNum4.addActionListener(new ListenToFour());

jbtNum5.addActionListener(new ListenToFive());

jbtNum6.addActionListener(new ListenToSix());

jbtNum7.addActionListener(new ListenToSeven());

jbtNum8.addActionListener(new ListenToEight());

jbtNum9.addActionListener(new ListenToNine());

jbtNum0.addActionListener(new ListenToZero());

jbtAdd.addActionListener(new ListenToAdd());

jbtSubtract.addActionListener(new ListenToSubtract());

jbtMultiply.addActionListener(new ListenToMultiply());

jbtDivide.addActionListener(new ListenToDivide());

jbtSolve.addActionListener(new ListenToSolve());

jbtClear.addActionListener(new ListenToClear());

} //JavaCaluclator()

class ListenToClear implements ActionListener {

public void actionPerformed(ActionEvent e) {

//display = jtfResult.getText();

jtfResult.setText("");

addBool = false ;

subBool = false ;

mulBool = false ;

divBool = false ;

TEMP = 0;

SolveTEMP =0 ;

}

}

class ListenToOne implements ActionListener {

public void actionPerformed(ActionEvent e) {

display = jtfResult.getText();

jtfResult.setText(display + "1");

}

}

class ListenToTwo implements ActionListener {

public void actionPerformed(ActionEvent e) {

display = jtfResult.getText();

jtfResult.setText(display + "2");

}

}

class ListenToThree implements ActionListener {

public void actionPerformed(ActionEvent e) {

display = jtfResult.getText();

jtfResult.setText(display + "3");

}

}

class ListenToFour implements ActionListener {

public void actionPerformed(ActionEvent e) {

display = jtfResult.getText();

jtfResult.setText(display + "4");

}

}

class ListenToFive implements ActionListener {

public void actionPerformed(ActionEvent e) {

display = jtfResult.getText();

jtfResult.setText(display + "5");

}

}

class ListenToSix implements ActionListener {

public void actionPerformed(ActionEvent e) {

display = jtfResult.getText();

jtfResult.setText(display + "6");

}

}

class ListenToSeven implements ActionListener {

public void actionPerformed(ActionEvent e) {

display = jtfResult.getText();

jtfResult.setText(display + "7");

}

}

class ListenToEight implements ActionListener {

public void actionPerformed(ActionEvent e) {

display = jtfResult.getText();

jtfResult.setText(display + "8");

}

}

class ListenToNine implements ActionListener {

public void actionPerformed(ActionEvent e) {

display = jtfResult.getText();

jtfResult.setText(display + "9");

}

}

class ListenToZero implements ActionListener {

public void actionPerformed(ActionEvent e) {

display = jtfResult.getText();

jtfResult.setText(display + "0");

}

}

class ListenToAdd implements ActionListener {

public void actionPerformed(ActionEvent e) {

TEMP = Double.parseDouble(jtfResult.getText());

jtfResult.setText("");

addBool = true ;

}

}

class ListenToSubtract implements ActionListener {

public void actionPerformed(ActionEvent e) {

TEMP = Double.parseDouble(jtfResult.getText());

jtfResult.setText("");

subBool =true;

}

}

class ListenToMultiply implements ActionListener {

public void actionPerformed(ActionEvent e) {

TEMP = Double.parseDouble(jtfResult.getText());

jtfResult.setText("");

mulBool =true;

}

}

class ListenToDivide implements ActionListener {

public void actionPerformed(ActionEvent e) {

TEMP = Double.parseDouble(jtfResult.getText());

jtfResult.setText("");

divBool =true;

}

}

class ListenToSolve implements ActionListener {

public void actionPerformed(ActionEvent e) {

SolveTEMP = Double.parseDouble( jtfResult.getText() );

if ( addBool == true )

SolveTEMP = SolveTEMP + TEMP;

else if ( subBool == true )

SolveTEMP = SolveTEMP - TEMP;

else if ( mulBool == true )

SolveTEMP = SolveTEMP * TEMP;

else if ( divBool == true )

SolveTEMP = SolveTEMP / TEMP;

jtfResult.setText( Double.toString( SolveTEMP ) );

addBool = false ;

subBool = false ;

mulBool = false ;

divBool = false ;

}

}

public static void main(String[] args) {

// TODO Auto-generated method stub

Sample10 calc = new Sample10();

calc.pack();

calc.setLocationRelativeTo(null);

calc.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

calc.setVisible(true);

}

}

Chapter 12. Java Native Interface

Java Native Interface (JNI) is a standard programming interface for writing Java native methods and embedding the JVM into native applications. Simply, it is a Java technology with which a Java application can call a method written with such as C, C++ and assembly. Adopting JNI is very simple. You need two components -- a Java program, and a native library. The native library is written in other languages and compiled on corresponding platforms.

Introduction, Purpose and features

1. JNI stands for Java Native Interface

2. JNI specifies a communication protocol between Java code and external, native code.

3. It enables your Java code to interface with native code written in other languages (such as C, C++)

4. Native code typically accesses the CPU and registers directly and is thus faster than interpreted code (like Java)

5. Java native methods are methods declared in your Java code (much like you declare an abstract method), but which are actually implemented in another programming language.

JNI allows Java programmers to

1. Leverage platform specific features outside a JVM. For example, you typically can't write a device driver in Java because you can't directly access the hardware

2. Leverage the improved speed possible with natively compiled code (such as C or assembler). For example, you might need an extremely fast math routine for a scientific application or game program.

3. Utilize existing code libraries in your Java programs. For example, there might be a really good file compression library written in C. Why try to rewrite it in Java when you can access it using JNI?

JNI Drawbacks

1. Your program is no longer platform independent

2. Your program is not as robust. If there is a null pointer exception in your native code, the JVM can't display a helpful message. It might even lock up.

JNI supports

1. Native methods can create and manipulate Java objects such as strings and arrays.

2. Native methods can manipulate and update Java objects passed into them (as parameters)

3. You can catch and throw exceptions from native methods and handle these exceptions in either the native method or your Java application

4. This almost seamless sharing of objects makes it very easy to incorporate native methods in your Java code

The Role of JNI

1. As a part of the Java virtual machine implementation, the JNI is a two-way interface that allows Java applications to invoke native code and vice versa.

2. The JNI is designed to handle situations where you need to combine Java applications with native code.

3. As a two-way interface, the JNI can support two types of native code: native libraries and native applications.

JNI "Hello World!" Application

Let's create the JNI "Hello World" application – a Java application that calls a C function via JNI to print "Hello World!".The process consists of the following steps:

  * Create a class (HelloWorld.java) that declares the native method.

  * Use javac to compile the HelloWorld source file, resulting in the class file HelloWorld.class.

  * Use javah -jni to generate a C header file (HelloWorld.h) containing the function prototype for the native method implementation. The javah tool is provided with JDK or Java 2 SDK releases.

  * Write the C implementation (CLibHelloWorld.c) of the native method.

  * Compile the C implementation into a native library, creating HelloWorld.dll.

  * Run the HelloWorld program using the java runtime interpreter. Both the class file (HelloWorld.class) and the native library (HelloWorld.dll) are loaded at runtime.

  *

  *

##### Step 1: Write a Java Class that uses C Codes - HelloJNI.java

public class HelloJNI {

static {

System.loadLibrary("hello"); // Load native library at runtime

// hello.dll (Windows) or libhello.so (Unixes)

}

// Declare a native method sayHello() that receives nothing and returns void

private native void sayHello();

// Test Driver

public static void main(String[] args) {

new HelloJNI().sayHello(); // invoke the native method

}

}

The static initializer invokes System.loadLibrary() to load the native library "Hello" (which contains the native method sayHello()) during the class loading. It will be mapped to "hello.dll" in Windows; or "libhello.so" in Unixes. This library shall be included in Java's library path (kept in Java system variable java.library.path); otherwise, the program will throw a UnsatisfiedLinkError. You could include the library into Java Library's path via VM argument -Djava.library.path= _path_to_lib_.

Next, we declare the method sayHello() as a native instance method, via keyword native, which denotes that this method is implemented in another language. A native method does not contain a body. The sayHello() is contained in the native library loaded.

The main() method allocate an instance of HelloJNI and invoke the native method sayHello().

Compile the "HelloJNI.java" into "HelloJNI.class".

> **javac HelloJNI.java**

#####

##### Step 2: Create the C/C++ Header file - HelloJNI.h

Run javah utility on the class file to create a header file for C/C++ programs:

> **javahHelloJNI**

The output is HelloJNI.h as follows:

/* DO NOT EDIT THIS FILE - it is machine generated */

#include <jni.h>

/* Header for class HelloJNI */

#ifndef _Included_HelloJNI

#define _Included_HelloJNI

#ifdef __cplusplus

extern "C" {

#endif

/*

* Class: HelloJNI

* Method: sayHello

* Signature: ()V

*/

JNIEXPORT void JNICALL Java_HelloJNI_sayHello(JNIEnv *, jobject);

#ifdef __cplusplus

}

#endif

The header declares a C function Java_HelloJNI_sayHello as follows:

JNIEXPORT void JNICALL **Java_HelloJNI_sayHello** (JNIEnv *, jobject);

The naming convention for C function is Java_{package_and_classname}_{function_name}(JNI arguments). The dot in package name shall be replaced by underscore.

The arguments:

  * JNIEnv*: reference to JNI environment, which lets you access all the JNI fucntions.

  * jobject: reference to "this" Java object.

We are not using these arguments in the hello-world example, but will be using them later. Ignore the macros JNIEXPORT and JNICALL for the time being.

The extern "C" is recognized by C++ compiler only. It notifies the C++ compiler that these functions are to be compiled using C's function naming protocol (instead of C++ naming protocol). C and C++ have different function naming protocols as C++ support function overloading and uses a name mangling scheme to differentiate the overloaded functions.

##### Step 3: C Implementation - HelloJNI.c

#include <jni.h>

#include <stdio.h>

#include "HelloJNI.h"

// Implementation of native method sayHello() of HelloJNI class

JNIEXPORT void JNICALL Java_HelloJNI_sayHello(JNIEnv *env, jobjectthisObj) {

printf("Hello World!\n");

return;

}

Save the C program as "HelloJNI.c"

Here

  * We use the printf function to display the string "Hello World!".

  * Both arguments, the JNIEnv pointer and the reference to the object, are ignored.

  * The C program includes three header files:

  * jni.h – provides information the native code needs to call JNI functions.

  * stdio.h – implements the printf() function.

  * HelloJNI.h – generated by using javah, it includes the C/C++ prototype for the Java_Hello_print function.

  * Be sure to name your project CLibHelloWorld so the DLL it creates will be named c_library.dll.

  * Run the Java class (main method). Be sure all the files and dll are in one folder.

  * java HelloWorld

  * You should see "Hello world" appear on the screen!

  * If you see a "java.lang.UnsatisfiedLinkError" error message, then Java couldn't find your shared library OR mismatch in native functions.

Chapter 13. Servlets

Servlets are Java applications running on the server side, just like CGI and server side scripting languages such as ASP or PHP. Servlets can therefore manage HTTP requests and to provide the client with a dynamic HTTP response (thus creating dynamic web pages).

Servlets have several advantages over other server-side technologies. Since they are build in Java, servlets provide a means of improving web servers on any platform, especially servlets that are independent of the web server (unlike Apache modules or Netscape Server API). Indeed, servlets run in a servlet engine, establishing the link between the servlet and the web server. The programmer does not have to worry about technical details such as the network connection, the formatting of the HTTP response ...etc. A servlet container is a class for manipulating the servlet. On the other hand servlets are much better than the scripts, as they are pseudo-codes, automatically loaded when the server starts or when the connection from client is initiated. Servlets are active (memory-resident) and ready to handle requests from clients, whereas with scripts, a new process is created for each HTTP request.   
One of the major advantages of servlets is their reusability. You can create components encapsulating similar services, in order to reuse them in future applications.

Servlet Life Cycle

## The init() method :

The init method is designed to be called only once. It is called when the servlet is first created, and not called again for each user request. So, it is used for one-time initializations, just as with the init method of applets.

The servlet is normally created when a user first invokes a URL corresponding to the servlet, but you can also specify that the servlet be loaded when the server is first started.

When a user invokes a servlet, a single instance of each servlet gets created, with each user request resulting in a new thread that is handed off to doGet or doPost as appropriate. The init() method simply creates or loads some data that will be used throughout the life of the servlet.

The init method definition looks like this:

publicvoidinit()throwsServletException{

// Initialization code...

}

##

## The service() method :

The service() method is the main method to perform the actual task. The servlet container (i.e. web server) calls the service() method to handle requests coming from the client( browsers) and to write the formatted response back to the client.

Each time the server receives a request for a servlet, the server spawns a new thread and calls service. The service() method checks the HTTP request type (GET, POST, PUT, DELETE, etc.) and calls doGet, doPost, doPut, doDelete, etc. methods as appropriate.

Here is the signature of this method:

publicvoid service(ServletRequest request,

ServletResponse response)

throwsServletException,IOException{

}

The service () method is called by the container and service method invokes doGe, doPost, doPut, doDelete, etc. methods as appropriate. So you have nothing to do with service() method but you override either doGet() or doPost() depending on what type of request you receive from the client.

The doGet() and doPost() are most frequently used methods with in each service request. Here is the signature of these two methods.

## The doGet() Method

A GET request results from a normal request for a URL or from an HTML form that has no METHOD specified and it should be handled by doGet() method.

publicvoiddoGet(HttpServletRequest request,

HttpServletResponse response)

throwsServletException,IOException{

// Servlet code

}

## The doPost() Method

A POST request results from an HTML form that specifically lists POST as the METHOD and it should be handled by doPost() method.

publicvoiddoPost(HttpServletRequest request,

HttpServletResponse response)

throwsServletException,IOException{

// Servlet code

}

## The destroy() method :

The destroy() method is called only once at the end of the life cycle of a servlet. This method gives your servlet a chance to close database connections, halt background threads, write cookie lists or hit counts to disk, and perform other such cleanup activities.

After the destroy() method is called, the servlet object is marked for garbage collection. The destroy method definition looks like this:

publicvoid destroy(){

// Finalization code...

}

There are two types of servlet

i)Generic Servlet

ii)HTTP Servlet

Generic Servlet:

  * GenericServlet class is direct subclass of Servlet interface.

  * Generic Servlet is protocol independent.It handles all types of protocol like http, smtp, ftp etc.

  * Generic Servlet only supports service() method.It handles only simple request

public void service(ServletRequestreq,ServletResponse res ).

HttpServlet:

  * HttpServlet class is the direct subclass of Generic Servlet.

  * HttpServlet is protocol dependent. It handles only http protocol.

  * HttpServlet supports public void service(ServletRequestreq,ServletResponse res ) and protected void service(HttpServletRequestreq,HttpServletResponse res).

  * HttpServlet supports also doGet(),doPost(),doPut(),doDelete(),doHead(),doTrace(),doOptions()etc.

Generic Servlet Example

import java.io.*;  
import javax.servlet.*;

public class HelloWorld extends GenericServlet{   
public void service(ServletRequest request,   
ServletResponse response)  
throws ServletException,IOException{  
response.setContentType("text/html");  
PrintWriter pw = response.getWriter();  
pw.println("<html>");  
pw.println("<head><title>Hello World</title></title>");  
pw.println("<body>");  
pw.println("<h1>Hello World</h1>");  
pw.println("</body></html>");  
}  
}

Chapter 14. Introduction to JSP

JSP technology is used to create web application just like Servlet technology. It can be thought of as an extension to servlet because it provides more functionality than servlet such as expression language, jstl etc.A JSP page consists of HTML tags and JSP tags. The jsp pages are easier to maintain than servlet because we can separate designing and development. It provides some additional features such as Expression Language, Custom Tag etc.

Advantage of JSP over Servlet

There are many advantages of JSP over servlet. They are as follows:

1) Extension to Servlet

JSP technology is the extension to servlet technology. We can use all the features of servlet in JSP. In addition to, we can use implicit objects, predefined tags, expression language and Custom tags in JSP, that makes JSP development easy.

2) Easy to maintain

JSP can be easily managed because we can easily separate our business logic with presentation logic. In servlet technology, we mix our business logic with the presentation logic.

3) Fast Development: No need to recompile and redeploy

If JSP page is modified, we don't need to recompile and redeploy the project. The servlet code needs to be updated and recompiled if we have to change the look and feel of the application.

4) Less code than Servlet

In JSP, we can use a lot of tags such as action tags, jstl, custom tags etc. that reduces the code. Moreover, we can use EL, implicit objects etc.

Life cycle of a JSP Page

The JSP pages follows these phases:

  * Translation of JSP Page

  * Compilation of JSP Page

  * Classloading (class file is loaded by the classloader)

  * Instantiation (Object of the Generated Servlet is created).

  * Initialization ( jspInit() method is invoked by the container).

  * Reqeust processing ( _jspService() method is invoked by the container).

  * Destroy ( jspDestroy() method is invoked by the container).

Note: jspInit(), _jspService() and jspDestroy() are the life cycle methods of JSP.

As depicted in the above diagram, JSP page is translated into servlet by the help of JSP translator. The JSP translator is a part of webserver that is responsible to translate the JSP page into servlet. Afterthat Servlet page is compiled by the compiler and gets converted into the class file. Moreover, all the processes that happens in servlet is performed on JSP later like initialization, committing response to the browser and destroy.

Creating a simple JSP Page

To create the first jsp page, write some html code as given below, and save it by .jsp extension. We have save this file as index.jsp. Put it in a folder and paste the folder in the web-apps directory in apache tomcat to run the jsp page.

index.jsp

Let's see the simple example of JSP, here we are using the scriptlet tag to put java code in the JSP page. We will learn scriptlet tag later.

<html>

<body>

<% out.print(2*5); %>

</body>

</html>

It will print 10 on the browser.

Example

Index.jsp:-

<%@ page import="java.sql.*" %>

<%@ page import="java.io.*" %>

<html>

<body>

<TABLE style="background-color: #ffffcc;">

<TR>

<TD align="center">

<h2>

To display all the data from the table click here...

</h2>

</TD>

</TR>

<TR>

<TD align="center"><A HREF="newjsp.jsp">

<font size="4" color="blue">show data from table</font></A></TD>

</TR>

</TABLE>

</body>

</html>

Jsp program:-

<%@ page import="java.sql.*" %>

<%@ page import="java.io.*" %>

<html>

<body>

<h2>Data from the table student</h2>

<%

try

{

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

Connection con = DriverManager.getConnection("jdbc:odbc:stu");

Statement st=con.createStatement();

ResultSet rs=null;

String Q = "SELECT * from student";

rs = st.executeQuery(Q);

%>

<TABLE cellpadding="15" border="1" style="background-color: #ffffcc;">

<%

while (rs.next())

{

%>

<TR>

<TD><%=rs.getString(1)%></TD>

<TD><%=rs.getString(2)%></TD>

<TD><%=rs.getString(3)%></TD>

</TR>

<% } %>

<%

rs.close();

st.close();

con.close();

}

catch (Exception ex)

{

%>

<font size="+3" color="red"> <br>

<%

out.println("Unable to connect to database.");

}

%>

</TABLE>

<TABLE>

<TR>

<TD><FORM ACTION="index.jsp" method="get" >

<button type="submit"><\-- back</button></TD>

</TR>

</TABLE>

</font>

</body>

</html>

Output:-

Chapter 15. JDBC

This JDBC tutorial covers all the topics of JDBC with the simple examples. JDBC is a Java API that is used to connect and execute query to the database. JDBC API uses jdbc drivers to connects to the database.

Why use JDBC?

Before JDBC, ODBC API was used to connect and execute query to the database. But ODBC API uses ODBC driver that is written in C language which is plateform dependent and unsecured. That is why Sun Microsystem has defined its own API (JDBC API) that uses JDBC driver written in Java language.

JDBC Driver

JDBC Driver is a software component that enables java application to interact with the database.There are 4 types of JDBC drivers:

  1. JDBC-ODBC bridge driver

  2. Native-API driver (partially java driver)

  3. Network Protocol driver (fully java driver)

  4. Thin driver (fully java driver)

1) JDBC-ODBC bridge driver

The JDBC-ODBC bridge driver uses ODBC driver to connect to the database. The JDBC-ODBC bridge driver converts JDBC method calls into the ODBC function calls. This is now discouraged because of thin driver.

Advantages:

  * easy to use.

  * can be easily connected to any database.

Disadvantages:

  * Performance degraded because JDBC method call is converted into the ODBC function calls.

  * The ODBC driver needs to be installed on the client machine.

2) Native-API driver

The Native API driver uses the client-side libraries of the database. The driver converts JDBC method calls into native calls of the database API. It is not written entirely in java.

Advantage:

  * performance upgraded than JDBC-ODBC bridge driver.

Disadvantage:

  * The Native driver needs to be installed on the each client machine.

  * The Vendor client library needs to be installed on client machine.

3) Network Protocol driver

The Network Protocol driver uses middleware (application server) that converts JDBC calls directly or indirectly into the vendor-specific database protocol. It is fully written in java.

Advantage:

  * No client side library is required because of application server that can perform many tasks like auditing, load balancing, logging etc.

Disadvantages:

  * Network support is required on client machine.

  * Requires database-specific coding to be done in the middle tier.

  * Maintenance of Network Protocol driver becomes costly because it requires database-specific coding to be done in the middle tier.

4) Thin driver

The thin driver converts JDBC calls directly into the vendor-specific database protocol. That is why it is known as thin driver. It is fully written in Java language.

Advantage:

  * Better performance than all other drivers.

  * No software is required at client side or server side.

Disadvantage:

  * Drivers depends on the Database.

Example

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.ResultSet;

import java.sql.Statement;

public class Type_One

{

public static void main(String[] args)

{

try

{

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); //Load Driver

Connection con = DriverManager.getConnection("jdbc:odbc:stu"); //Create Connection with Data Source Name : stu

Statement s = con.createStatement(); // Create Statement

String query = "select * from Data"; // Create Query

s.execute(query); // Execute Query

ResultSet rs = s.getResultSet(); //return the data from Statement into ResultSet

while(rs.next()) // Retrieve data from ResultSet

{

System.out.print("Serial number : "+rs.getString(1)); //1st column of Table from database

System.out.print(" , Name : "+rs.getString(2)); //2nd column of Table

System.out.print(" , City : "+rs.getString(3)); //3rd column of Table

System.out.println(" and Age : "+rs.getString(4)); //4th column of Table

}

s.close();

con.close();

}

catch (Exception e)

{

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

}

}

}

Chapter 16. EJB

The J2EE Architecture allows the programmers to divide their work into two major categories:

  * Business Logic

  * Presentation Logic

Presentation Logic:

Presentation Logic consists of all the program (JSP and Servlets), images and html files that are used to interact with the client. These files are archived into .war file. These files are installed on the web server and these interacts with the users.

Business Logic:

These are EJB applications which implements the business logic of the system and are archived into .jar file. Business logic runs on the application server.These two types of archives are bundled into complete J2EE applications, and delivered as Enterprise Archive (EAR) file.Let's took an example of form processing. In this example J2EE application could have and HTML form, which prompts the user to input the data, a servlet to receive the data from the form and process it, and also an Enterprise Bean to store the data in a database. In this example the HTML form and servlet are archived in a WAR file, and the Enterprise Java Bean is archived into JAR file. These two archive files (WAR and JAR) both are added to the EAR file, which is finally deployed on the serverOne of Java's most important features is platform independence. Since its arrival, Java has been depicted as "write once, run anywhere". But Enterprise JavaBeans (EJBs) go one step further. They are not only platform independent but also implementation independent. That is, EJBs can run in any application server that implements the EJB specifications

EJP Architecture

Client tier— Students and administrators use the client tier to interact with the system. The client tier is provided by a Web browser, such as Internet Explorer or Netscape Navigator. The client tier communicates with the Web tier by using the HTTP protocol.

Web tier— This tier accepts user requests and generates responses using the presentation logic. The sample application uses both servlets and JSPs in a Web container. The Web tier communicates with the business logic tier using RMI/IIOP protocol.

Business logic tier— This tier handles the core business logic of the application. The business components are implemented as EJB components with support from an EJB container.

EIS tier— The EIS tier consists of the database in which the sample application's permanent data is stored. The business-logic tier communicates with the EIS tier using JDBC.

Types of EJP

Enterprise beans : An enterprise bean is a non-visual component of a distributed, transaction-oriented enterprise application. Enterprise beans are typically deployed in EJB containers and run on EJB servers. There are three types of enterprise beans: session beans, entity beans, and message-driven beans.

Session beans: Session beans are non-persistent enterprise beans. They can be stateful or stateless. A stateful session bean acts on behalf of a single client and maintains client-specific session information (called conversational state) across multiple method calls and transactions. It exists for the duration of a single client/server session. A stateless session bean, by comparison, does not maintain any conversational state. Stateless session beans are pooled by their container to handle multiple requests from multiple clients.

Entity beans: Entity beans are enterprise beans that contain persistent data and that can be saved in various persistent data stores. Each entity bean carries its own identity. Entity beans that manage their own persistence are called bean-managed persistence (BMP) entity beans. Entity beans that delegate their persistence to their EJB container are called container-managed persistence (CMP) entity beans.

Message-driven beans: Message-driven beans are enterprise beans that receive and process JMS messages. Unlike session or entity beans, message-driven beans have no interfaces. They can be accessed only through messaging and they do not maintain any conversational state. Message-driven beans allow asynchronous communication between the queue and the listener, and provide separation between message processing and business logic.

Remote client view  
The remote client view specification is only available in EJB 2.0. The remote client view of an enterprise bean is location independent. A client running in the same JVM as a bean instance uses the same API to access the bean as a client running in a different JVM on the same or different machine.  
Remote interface: The remote interface specifies the remote business methods that a client can call on an enterprise bean.  
Remote home interface: The remote home interface specifies the methods used by remote clients for locating, creating, and removing instances of enterprise bean classes.

Local client view  
The local client view specification is only available in EJB 2.0. Unlike the remote client view, the local client view of a bean is location dependent. Local client view access to an enterprise bean requires both the local cleint and the enterprise bean that provides the local client view to be in the same JVM. The local client view therefore does not provide the location transparency provided by the remote client view. Local interfaces and local home interfaces provide support for lightweight access from enterprise bean that are local clients. Session and entity beans can be tightly couple with their clients, allowing access without the overhead typically associated with remote method calls.

Local interface: The local interface is a lightweight version of the remote interface, but for local clients. It includes business logic methods that can be called by a local client.  
Local home interface: The local home interface specifies the methods used by local clients for locating, creating, and removing instances of enterprise bean classes.

EJB client JAR file  
An EJB client JAR file is an optional JAR file that can contain all the class files that a client program needs to use the client view of the enterprise beans that are contained in the EJB JAR file. If you decide not to create a client JAR file for an EJB module, all of the client interface classes will be in the EJB JAR file.

EJB container  
An EJB container is a run-time environment that manages one or more enterprise beans. The EJB container manages the life cycles of enterprise bean objects, coordinates distributed transactions, and implements object security. Generally, each EJB container is provided by an EJB server and contains a set of enterprise beans that run on the server.

Deployment descriptor  
A deployment descriptor is an XML file packaged with the enterprise beans in an EJB JAR file or an EAR file. It contains metadata describing the contents and structure of the enterprise beans, and runtime transaction and security information for the EJB container.

EJB server  
An EJB server is a high-level process or application that provides a run-time environment to support the execution of server applications that use enterprise beans. An EJB server provides a JNDI-accessible naming service, manages and coordinates the allocation of resources to client applications, provides access to system resources, and provides a transaction service. An EJB server could be provided by, for example, a database or application server.

EJB architecture allows enterprise applications to be portable by running on a J2EE-compliant application server. An EJB application can be partitioned in a more usable, flexible, and expandable fashion. For example, new clients to access legacy systems can be easily built to meet user requirements. Moreover, the EJB architecture helps create a service-based model in which services are location-transparent components that can be delivered to their target clients. EJBs are highly reusable components, and represent the next step in the progression of Java technology for the development of application platforms capable of supporting mission-critical, component-based, enterprise applications. EJB components allow the development of business logic to be used across enterprise applications and to be portable across different platforms.The EJB model is based on Java Remote Method Invocation (RMI) technology, which supports the separation of executable components across multiple tiers. This separation permits maximum implementation flexibility and high scalability. RMI allows access to remote components to appear as if it were local to the invoking client. Moreover, the introduction of infrastructure services provided by the container help to manage and offer such services to the deployed EJBs. These runtime services make it possible for the EJB developer to focus on writing robust and reliable applications.The following summarizes the benefits gained by the enterprise and developers from using EJB technology:

  * Simplicity: The EJB architecture simplifies the development of complex enterprise applications by providing built-in common services. This allows an EJB application developer to access and utilize these services, and results in a reduction of the overall development effort.

  * Application portability: Portability can be accomplished by deploying an EJB application on any J2EE-compliant application server. Many Java application servers today implement all the services provided by J2EE-standard specifications.

  * Component reusability: An EJB is a highly reusable building block. J2EE applications can be composed of custom-based EJBs, off-the-shelf EJBs, or both. In addition, the application business logic of a certain EJB can be reused through Java subclassing of the EJB class.

  * Application partitioning: The separation of an application's business logic from its presentation allows ease of development and helps business programmers to work independently from Web page designers. Again, the separation of the application's business logic from its data helps manage each team independently. Any change of a component hosted in one tier does not affect the other tiers.

  * Distributed applications: The EJB architecture helps create distributed applications, which can span multiple environments. Each subsystem can work independently of the others, but still can interact with one another to deliver enterprise services to the target users. A user transaction, for example, can be executed across multiple servers within a single context, and will be perceived by the user as a single unit of work.

  * Application interoperability: The EJB architecture helps EJB components to access other components written in other component-based models, such as CORBA and .NET.

  * Application integration: One of the main objectives of the EJB architecture is to allow the integration of new applications with existing applications, such as legacy systems. Today, Enterprise Application Integration (EAI) is a hot topic for the corporate world. The related J2EE APIs, such as the J2EE Connector Architecture (JCA) and the Java Message Service (JMS) specification, make it possible to integrate enterprise bean applications with various non-Java applications, such as ERP systems or mainframe applications, in a standard way.

  * Availability of Java application servers: An enterprise has many J2EE-compliant application servers to choose from. Each application server provides J2EE services at a minimum, with the addition of other value-added services. A J2EE-compliant server can be selected to meet the customer's needs, which prevents vendor lock-in.

Session Bean

package program;

import javax.ejb.Stateless;

@Stateless

public class NewSessionBean implements NewSessionBeanRemote

{

public Integer Addtion(int a, int b)

{

return a+b;

}

public Integer Subtract(int a, int b)

{

return a-b;

}

public Integer Multiply(int a, int b)

{

return a*b;

}

}

Session Bean Interface:-

package program;

import javax.ejb.Remote;

@Remote

public interface NewSessionBeanRemote

{

Integer Addtion(int a, int b);

Integer Subtract(int a, int b);

Integer Multiply(int a, int b);

}

Index.jsp:-

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title> Bean </title>

</head>

<body>

<h1 align="center"> SESSION BEAN </h1>

<form name="my" action="NewServlet">

Enter x value: <input type="text" name="xval"><br>

Enter y value: <input type="text" name="yval"><br>

<input type="submit" value="submit">

</form>

</body>

</html>

Servlet.jsp:-

import java.io.IOException;

import java.io.PrintWriter;

import javax.ejb.EJB;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import program.NewSessionBeanRemote;

@WebServlet(name="NewServlet", urlPatterns={"/NewServlet"})

public class NewServlet extends HttpServlet

{

@EJB

private NewSessionBeanRemote newSessionBean;

protected void processRequest(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException

{

response.setContentType("text/html;charset=UTF-8");

PrintWriter out = response.getWriter();

try

{

String x=request.getParameter("xval");

String y=request.getParameter("yval");

int a=Integer.parseInt(x);

int b=Integer.parseInt(y);

out.println("The values are");

out.println("<br>");

out.println("Addition value :" +newSessionBean.Addtion(a, b));

out.println("</br>");

out.println("Subtraction value :" +newSessionBean.Subtract(a, b));

out.println("</br>");

out.println("Multiplication value :" +newSessionBean.Multiply(a, b));

out.println("</br>");

}

finally

{

out.close();

}

}

}
Chapter 17. Java Media Frame work

JMF is a framework for handling streaming media in Java programs. JMF is an

optional package of Java 2 standard platform. JMF provides a unified architecture

and messaging protocol for managing the acquisition, processing and delivery of

time-based media. JMF enables Java programs to

(i) Present ( playback) multimedia contents,

(ii) capture audio through mi

crophone and video through Camera,

(iii) do real-time streaming of

media over the Internet,

(iv) process media ( such as changing media format, adding special effects),

(v) store media into a file.

Features of JMF

JMF supports many popular media formats such as JPEG, MPEG-1, MPEG-2, QuickTime, AVI, WAV, MP3, GSM, G723,H263, and MIDI. JMF supports popular media access protocols such as file, HTTP, HTTPS, FTP, RTP, and RTSP. JMF uses a well-defined event reporting mechanism that follows the "Observer" .design pattern. JMF uses the "Factory" design pattern that simplifies the creation of JMF objects. The JMF support the reception and transmission of media streams using Real-time Transport Protocol (RTP) and JMF supports management of RTP sessions. JMF scales across different media data types, protocols and delivery mechanisms. JMF provides a plug-in architecture that allows JMF to be customized and extended. Technology providers can extend JMF to support additional media formats. High performance custom implementation of media players, or codecs possibly using hardware accelerators can be defined and integrated with the JMF.

The first few lines of the SimpleAudioPlayer class include the following calls, which import all necessary classes:

import javax.media.*;

import java.io.File;

import java.io.IOException;

import java.net.URL;

import java.net.MalformedURLException;

The javax.media package is one of the many packages defined by JMF.javax.media is the core package, containing the definitions of the Manager class and the Player interface,among others. In addition to the import javax.media statement, the above code fragment includes several import statements that create the input to our media player

In the next code fragment, the public class SimpleAudioPlayer and the Player instance variable are defined:

public class SimpleAudioPlayer {

private Player audioPlayer = null;

The term Player may sound quite familiar, because it is based on our common use of audio- and video-based media players. In fact, instances of this interface act much like their real-life counterparts. Players expose methods that relate to the functions of a physical

media player such as a stereo system or VCR. For example, a JMF media Player has the ability to start and stop a stream of media.

Creating a Player over a file

JMF makes it quite simple to obtain a Player instance for a given media file. The Manager class acts as a factory for creating many of the specific interface types exposed in JMF,

including the Player interface. Therefore, the Manager class is responsible for creating our Player instance, as shown below:

public SimpleAudioPlayer(URL url) throws IOException,

NoPlayerException,

CannotRealizeException {

audioPlayer = Manager.createRealizedPlayer(url);

}

public SimpleAudioPlayer(File file) throws IOException,

NoPlayerException,

CannotRealizeException {

this(file.toURL());

}

Player states

JMF defines a number of different states that a Player instance may be in. These states are as follows:

•Prefetched

•Prefetching

•Realized

•Realizing

•Started

•Unrealized

Starting and stopping the Player

Setting up a Player instance to be started or stopped is as simple as calling the easily recognized methods on the Player, as shown here:

public void play() {

audioPlayer.start();

}

public void stop() {

audioPlayer.stop();

audioPlayer.close();

}

Calling the play() method on the SimpleAudioPlayer class simply delegates the call to the start() method on the Player instance. After calling this method, you should hear the audio file played through the local speakers. Likewise, the stop()method delegates to the player to both stop and close the Player instance.Closing the Player instance frees any resources that were used for reading or playing the media file. Because this is a simple example, closing the Player is an acceptable way of ending a session. In a real application, however, you should carefully consider whether you want to get rid of the Player before you close it. Once you've closed the player, you will have to create a new Player instance before you can play your media again

Creating a SimpleAudioPlayer

Finally, this media player application contains a main() method, which lets it be invoked from the command line by passing in the file name. In the main() method, we make the following call, which creates the

SimpleAudioPlayer:

File audioFile = new File(args[0]);

SimpleAudioPlayer player = new SimpleAudioPlayer(audioFile);

The only other thing we have to do before we can play our audio file is to call the play() method on the created audio player, as shown here:

player.play();

To stop and clean up the audio player, we make the following call, also found in the main() method:

player.stop();

JMF Architecture

Example

import java.awt.BorderLayout;

import java.awt.Component;

import java.io.IOException;

import java.net.URL;

import javax.media.CannotRealizeException;

import javax.media.Manager;

import javax.media.NoPlayerException;

import javax.media.Player;

import javax.swing.JPanel;

public class MediaPanel extends JPanel

{

public MediaPanel( URL mediaURL )

{

setLayout( new BorderLayout() ); // use a BorderLayout

// Use lightweight components for Swing compatibility

Manager.setHint( Manager.LIGHTWEIGHT_RENDERER, true );

try

{

// create a player to play the media specified in the URL

Player mediaPlayer = Manager.createRealizedPlayer( mediaURL );

// get the components for the video and the playback controls

Component video = mediaPlayer.getVisualComponent();

Component controls = mediaPlayer.getControlPanelComponent();

if ( video != null )

add( video, BorderLayout.CENTER ); // add video component

if ( controls != null )

add( controls, BorderLayout.SOUTH ); // add controls

mediaPlayer.start(); // start playing the media clip

} // end try

catch ( NoPlayerException noPlayerException )

{

System.err.println( "No media player found" );

} // end catch

catch ( CannotRealizeException cannotRealizeException )

{

System.err.println( "Could not realize media player" );

} // end catch

catch ( IOException iOException )

{

System.err.println( "Error reading from the source" );

} // end catch

} // end MediaPanel constructor

} // end class MediaPanel

Chapter 18. Java 3D API

The Java 3D API is a hierarchy of Java classes which serve as the interface to a sophisticated three-dimensional graphics rendering and sound rendering system. The programmer works with high-level constructs for creating and manipulating 3D geometric objects. These geometric objects reside in a virtual universe, which is then rendered. The API is designed with the flexibility to create precise virtual universes of a wide variety of sizes, from astronomical to subatomic. Despite all this functionality, the API is still straightforward to use. The details of rendering are handled automatically. By taking advantage of Java threads, the Java 3D renderer is capable of rendering in parallel. The renderer can also automatically optimize for improved rendering performance.Every Java 3D program is at least partially assembled from objects from the Java 3D class hierarchy. This collection of objects describes a virtual universe , which is to be rendered. The API defines over 100 classes presented in the javax.media.j3d package. These classes are commonly referred to asthe Java 3D core classes.

Typical Screen Graph

Example

import com.sun.j3d.utils.universe.SimpleUniverse;

import com.sun.j3d.utils.geometry.ColorCube;

import javax.media.j3d.BranchGroup;

public class Hello3d {

public Hello3d()

{

SimpleUniverse universe = new SimpleUniverse();

BranchGroup group = new BranchGroup();

group.addChild(new ColorCube(0.3));

universe.getViewingPlatform().setNominalViewingTransform();

universe.addBranchGraph(group);

}

public static void main( String[] args ) {

new Hello3d();

}

}

Internationalization

Some applications need to use more than one language in the user interface. Changing a program to allow for this is called "internationalization", while the actual translation is called "localization". Translation is usually applied only to user interface elements (menus, labels, and so on), and _not_ to business data stored in the database.An internationalized program has the following characteristics:

  * With the addition of localized data, the same executable can run worldwide.

  * Textual elements, such as status messages and the GUI component labels, are not hardcoded in the program. Instead they are stored outside the source code and retrieved dynamically.

  * Support for new languages does not require recompilation.

  * Culturally-dependent data, such as dates and currencies, appear in formats that conform to the end user's region and language.

  * It can be localized quickly.

_Localization_ is the process of adapting software for a specific region or language by adding locale-specific components and translating text. The term localization is often abbreviated as l10n, because there are 10 letters between the "l" and the "n."

## Commonly used methods of Locale class

There are given commonly used methods of Locale class.

  1. **public static Locale getDefault()** it returns the instance of current Locale

  2. **public static Locale[] getAvailableLocales()** it returns an array of available locales.

  3. **public String getDisplayCountry()** it returns the country name of this locale object.

  4. **public String getDisplayLanguage()** it returns the language name of this locale object.

  5. **public String getDisplayVariant()** it returns the variant code for this locale object.

  6. **public String getISO3Country()** it returns the three letter abbreviation for the current locale's country.

  7. **public String getISO3Language()** it returns the three letter abbreviation for the current locale's language.

# Before Internationalization

Suppose that you've written a program that displays three messages, as follows:

public class NotI18N {

static public void main(String[] args) {

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

System.out.println("How are you?");

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

}

}

You've decided that this program needs to display these same messages for people living in France and Germany. Unfortunately your programming staff is not multilingual, so you'll need help translating the messages into French and German. Since the translators aren't programmers, you'll have to move the messages out of the source code and into text files that the translators can edit. Also, the program must be flexible enough so that it can display the messages in other languages, but right now no one knows what those languages will be.It looks like the program needs to be internationalized.

# After Internationalization

The source code for the internationalized program follows. Notice that the text of the messages is not hardcoded.

import java.util.*;

public class I18NSample {

static public void main(String[] args) {

String language;

String country;

if (args.length != 2) {

language = new String("en");

country = new String("US");

} else {

language = new String(args[0]);

country = new String(args[1]);

}

Locale currentLocale;

ResourceBundle messages;

currentLocale = new Locale(language, country);

messages = ResourceBundle.getBundle("MessagesBundle", currentLocale);

System.out.println(messages.getString("greetings"));

System.out.println(messages.getString("inquiry"));

System.out.println(messages.getString("farewell"));

}

}

Chapter 19. Deploying N-Tier Application

####  Layer and Process

A layer may run in an individual process; several layer may also run in an individual process; a layer may run in several processes too. If you read above section "Tier and Layer Relationship", you can understand here easily.

### 3-Tier Architecture

We introduce the 3-Tier concept first so that we can understand other tier concepts later easily. The simplest of N-Tier architecture is 3-Tier which typically contain following software component layers listed from the top level to the low level: presentation layer, application layer and data layer, which are depicted in Diagram 1.

A layer can access directly only the public components of its directly-below layer. For example, presentation layer can only access the public components in application layer, but not in data layer. Application layer can only access the public components in data layer, but not in presentation layer. Doing so can minimize the dependencies of one layer on other layers. This dependency minimization will bring benefits for layer development/maintenance, upgrading, scaling and etc. Doing so also makes the tier security enforcement possible. For example, the client layer cannot access the data layer directly but through the application layer, so data layer has a higher security guarding. Finally, doing so can also avoid cyclic dependencies among software components.

In order to claim a complete 3-Tier architecture, all three layers should be able to run in separate computers.

These three layers are briefly described as below:

**Presentation layer** : a layer that users can access directly, such as desktop UI, web page and etc. Also called client.

**Application layer** : this layer encapsulates the business logic (such as business rules and data validation), domain concept, data access logic and etc. Also called middle layer.

**Data layer** : the external data source to store the application data, such as database server, CRM system, ERP system, mainframe or other legacy systems and etc. The one we meet often today is database server. For N-Tier architecture, we need to use the non-embedded database server, such as SQL server, Oracle, DB2, MySQL or PostgreSQL. The non-embedded database server can be run in an individual computer. Whereas, the embedded type databases, such as Microsoft access, dbase and etc, cannot run in an individual computer, and then cannot be used as the data layer of the 3-Tier architecture.

###  1, 2, 3 or More Tier Architecture

**1-Tier** : all above layers can only run in one computer. In order to achieve 1-Tier, we need to use the embedded database system, which cannot run in an individual process. Otherwise, there will be at least 2-Tier because non-embedded databases usually can run in an individual computer (tier).

**2-Tier** : either presentation layer and application layer can only run in one computer, or application layer and data layer can only run in one computer. The whole application cannot run in more than 2 computers.

**3-Tier** : the simplest case of N-Tier architecture; all above three layers are able to run in three separate computers. Practically, these three layers can also be deployed in one computer (3-Tier architecture, but deployed as 1-Tier).

**N-Tier** : 3 or more tiers architecture. Diagram 2 below depicts a typical N-Tier architecture. Some layers in 3-Tier can be broken further into more layers. These broken layers may be able to run in more tiers. For example, application layer can be broken into business layer, persistence layer or more. Presentation layer can be broken into client layer and client presenter layer. In diagram 2, in order to claim a complete N-Tier architecture, client presenter layer, business layer and data layer should be able to run in three separate computers (tiers). Practically, all these layers can also be deployed in one compute (tier).

**Client layer** : this layer is involved with users directly. There may be several different types of clients coexisting, such as WPF, Window form, HTML web page and etc.

**Client presenter layer** : contains the presentation logic needed by clients, such as ASP .NET MVC in IIS web server. Also it adapts different clients to the business layer.

_Business layer_ : handles and encapsulates all of business domains and logics; also called domain layer.

_Persistence layer_ : handles the read/write of the business data to the data layer, also called data access layer (DAL).

_Data layer_ : the external data source, such as a database.

Sometimes, the number of tiers is able to be equal or more than 3, but client presenter layer, business layer and data layer cannot run in three separate computers (tiers). Is this a N-Tier architecture? we categorize this N-Tier as an incomplete N-Tier architecture because its client presenter layer, business layer and data layer cannot run in three separate computers (tiers). If we use the modem non-embedded database such as Sql Server, Oracle and etc, these databases will always be able to run in an individual computer. Therefore, for this case in Diagram 1, the criteria of a 2-Tier architecture is that presentation layer and application layer can run in only one computer; the criteria of a complete 3-Tier architecture is that presentation layer and application layer can run in different computers. A complete N-Tier architecture has the same criteria as 3-Tier.

##  Advantages and Disadvantages of Different Tier Architectures

### 1 or 2-Tier Architecture

**Advantages** : simple and fast for a lower number of users due to fewer processes and fewer tiers; low cost for hardware, network, maintenance and deployment due to less hardware and network bandwidth needed.

**Disadvantages** : will have issues when the number of users gets big; has limitation to solve issues like security, scalability, fault tolerance and etc because it can be deployed in only 1 or 2 computes.

###  N-Tier Architecture

**Advantages** : there are following general advantages:

  1. Scalable: this is due to its capability of multiple tier deployment and the tier decoupling it brought. For example, the data tier can be scaled up by database clustering without other tiers involving. The web client side can be scaled up by load-balancer easily without affecting other tiers. Windows server can be clustered easily for load balancing and failover. In addition, business tier server can also be clustered to scale up the application, such as Weblogic cluster in J2EE.

  2. Better and finer security control to the whole system: we can enforce the security differently for each tier if the security requirement is different for each tier. For example, business tier and data tier usually need higher security level than presentation tier does, then we can put these two high security tiers behind firewall for protection. 1 or 2 tiers architecture cannot fully achieve this purpose because of a limited number of tiers. Also, for N-Tier architecture, users cannot access business layer and data layer directly, all requests from users are routed by client presenter layer to business layer, then to data layer. Therefore, client presenter layer also serves as a proxy-like layer for business layer, and business layer serves as a proxy-like layer for data layer. These proxy-like layers provides further protection for their layers below.

  3. Better fault tolerance ability: for example, the databases in data layer can be clustered for failover or load balance purpose without affecting other layers.

  4. Independent tier upgrading and changing without affecting other tiers: in object-oriented world, Interface-dependency implementation can decouples all layers very well so that each layer can change individually without affecting other layers too much. Interface-dependency means a layer depends on another layer by interfaces only, not concrete classes. Also, the dependency of a layer only on its directly-below layer also minimizes the side effect of a layer's change on the whole system. For example, if keep the interfaces unchanged, we can update or replace the implementation of any layer independently without affecting the whole system. Due to the changing of business requirement and technology, changing the implementation of a layer to another totally different one does happen often. For example, originally we use Windows Form mainly, now we use WPF mainly. If our original system is implemented as the decoupled layer structure, then we will only need to update the client side from Windows Form to WPF without the need to change the server side layers.

  5. Friendly and efficient for development: the decoupled layers are logic software component groups mainly by functionality, they are very software development friendly and efficient. Each layer can be assigned individually to a team who specializes in the specific functional area; a specialized team can handle the relevant task better and more efficiently.

  6. Friendly for maintenance: N-Tier architecture groups different things together mainly by functionality and then makes things clear, easily understandable and manageable.

  7. Friendly for new feature addition: due to the logical grouped components and the decoupling brought by N-Tier architecture, new features can be added easily without affecting too much on the whole system.

  8. Better reusability: this is due to the logically grouped components and the loose couplings among layers. Loosely-coupled component groups are usually implemented in more general ways, so they can be reused by more other applications.

####  The Disadvantages of the N-Tier Deployment

  1. The performance of the whole application may be slow if the hardware and network bandwidth aren't good enough because more networks, computers and processes are involved.

  2. More cost for hardware, network, maintenance and deployment because more hardware and better network bandwidth are needed.

The effects of N-Tier deployment on the application performance are a double edge issue. In one side, if the number of uses isn't big enough, the performance may be slow due to more computers, process and network involved. Namely, if put everything in one tier or one process, performance will be better for a small number of users. However, if the number of user gets big, then the scalability brought by N-Tier will improve the overall performance, such as load balancing and database clustering which all improve the performance of N-Tier architecture. Why the performance result of the small number of users and the big number of users are different? this is because the bottleneck of the whole application are different for these two situations. For the case with the small number users, the bottleneck is the time for data to communicate among different processes. If more computer, more processes and longer network, then costs longer, then performance is bad. However, when the number of user gets big, the bottleneck shift to other things because of server's capacity, such as cpu and memory resource contentions in one computer, database threshold in server, horsepower limitation of a web server and etc. Only the scalability of N-Tier architecture can solve these bottlenecks existing with a big number of users; usually load balancing by server clustering is used for N-Tier architecture's scalability. With more computers are scaled up to share the task for big number of users, then performance is improved. Besides gaining performance by scalability of N-Tier architecture, we can also improve the performance with better hardware and better network bandwidth to meet our business requirement.

160

