You are on page 1of 209

1

ER/CORP/CRS/LA46/003
Advanced Java Programming
Module 1 - Multithreading
Education & Research
We shall now move on to the module on Multithreading.
2
2
We enable you to leverage knowledge
anytime, anywhere!
Lesson Outcomes
After completion of the module you will be able to
understand about
Creating and managing threads
Priority management
Thread synchronization
Thread groups and daemon threads
After completion of the module you will be able to understand about
Creating and managing threads
Priority management
Thread synchronization
Thread groups and daemon threads
3
3
We enable you to leverage knowledge
anytime, anywhere!
What are Threads?
A thread is a single sequential flow of control within a
program
Facility to allow multiple activities within a single process
Referred as lightweight process
Each thread has its own program counter, stack and
local variables
Threads share memory, heap area, files
What is a Thread?
A thread is a single sequential flow of control within a program. It provides facility to allow
multiple activities within a single process. Threads are also referred as lightweight
processes. Each thread has its own program counter, stack and local variables. Threads
share memory, heap area and files.
Advantages of Threads over Processes:
Threads are memory efficient. Many threads can be efficiently contained within a single
EXE, while each process will incur the overhead of an entire EXE.
Threads share a common program space, which means that messages can be passed by
queuing only the pointer to the message. Since processes do not share a common program
space, the kernel must either copy the entire message from process A's program space to
process B's program space or must provide some mechanism by which process B can
access the message.
Switching between Threads is faster, since a thread has less context to save than a process.
4
4
We enable you to leverage knowledge
anytime, anywhere!
Why use Threads?
To perform asynchronous or background processing
Increases the responsiveness of GUI applications
Better utilization of system resources
Simplify program logic when there are multiple
independent entities
A very good example of a multi-threaded application is a game software where the GUI
display, updation of scores, sound effects and timer display are happening within the same
application simultaneously
Why to use Threads?
To perform asynchronous or background processing
To Increase the responsiveness of GUI applications
For better utilization of system resources
Threads simplify program logic by having multiple independent entities
5
5
We enable you to leverage knowledge
anytime, anywhere!
Creating the Thread
Two ways:
Extending the Thread class
Implementing the Runnable interface
We can create threads in two ways.
1. By extending the Thread class and
2. By Implementing the Runnable interface.
In Java we cannot extend from more than one class. In some cases a class might be
extending from some parent class and also we need to extend from Thread class. In
such cases we can do multithreading by implementing Runnable interface.
6
6
We enable you to leverage knowledge
anytime, anywhere!
The Thread class (1 of 2)
Extend the Thread class
Override the run() method
Create an object of the sub class and call the
start method to execute the Thread
A thread can be created by creating a new class that extends Thread, and then by creating
an instance of that class. The extending class must override the run() method, which is the
entry point for the new thread. It must also call start() to begin execution of the new thread.
During its lifetime, a thread spends some time executing and some time in any of several
non-executing states. When a thread gets to executing state, it executes the code in the
method run().
7
7
We enable you to leverage knowledge
anytime, anywhere!
The Thread class (2 of 2)
class ExtThread extends Thread
{
ExtThread()
{
System.out.println("Child Thread created");
}
public void run()
{
System.out.println("Child Thread running");
}
}
class ExtThreadMain
{
public static void main(String a[])
{
System.out.println("Hi I'm main thread");
ExtThread obj=new ExtThread ();
obj.start();
System.out.println("This is the main thread printing");
}}
The above code create a new class that extends Thread, and then create an instance of that
class.
The extending class must override the run() method, which is the entry point for the new thread.
It must also call the start() to begin the execution of the new thread. Call to start() method
begins the execution of the thread by calling the run() method.
The ExtThread() is the constructor of the class which is implicitly called when the instance of
the extending class is created.
8
8
We enable you to leverage knowledge
anytime, anywhere!
The Runnable Interface (1 of 2)
Useful when the class is already extending another class
and needs to implement mutithreading
Need to implement the run() method
Create a thread object (the worker) and give it a
Runnable object (the job)
public Thread(Runnable target);
Start the thread by calling the start() method
The easiest way to create a thread is to create a class that implements the Runnable
interface. We can construct a thread on any object that implements Runnable.
To implement Runnable, a class need to implement a single method called run().
Inside run(), we define the code that constitutes the new thread. This can call other
methods, use other classes, and declare variables, just like the main thread can.
The only difference is that run() establishes the entry point for another concurrent thread of
execution within your program. This thread will end when run() returns.
9
9
We enable you to leverage knowledge
anytime, anywhere!
The Runnable Interface (2 of 2)
class RunnableThread implements Runnable
{
RunnableThread()
{
System.out.println("Child Thread: ");
}
public void run()
{
System.out.println("Hi I'm a new thread");
}
}
class RunnableThreadMain
{
public static void main(String a[])
{
System.out.println("Hi I'm main thread");
RunnableThread rt=new RunnableThread();
Thread t=new Thread(rt);
t.start();
System.out.println("Hi I'm main thread");
}
}
In order to create a thread from Runnable interface, we need to create a class that
implements Runnable. when implementing the Runnable interface the instance of the
implementing class is to be created and the object of the same has to be passed to the
object of the Thread class to specify whose run method has to be executed which then
invokes the start() method, which starts the thread by invoking run() method.
10
10
We enable you to leverage knowledge
anytime, anywhere!
Thread States
WAITING
SLEEPING
BLOCKED
ALIVE
RUNNABLE
RUNNING
NEWBORN DEAD
start()
yield() or end
of time slice
schedule
notify(), notifyAll()
wait()
sleep()
Sleep interval
expires
I/O request
I/O completion
run() returns or
thread interrupted
NON-RUNNABLE
A thread can be in one of the following states.
Newborn State:
When the new instance of the thread is created by executing the constructor Thread( ),
Thread is said to be newborn. In this state no resources are allocated to the thread.
Runnable State:
When a start() method is called on the newborn thread instance, thread makes the transition
to Runnable state. In this state the thread is waiting for the scheduler to schedule it on the
processor.
Running State:
When thread is being executed by the CPU it will be in the running state.
Non-Runnable State:
A running state can be suspended, i.e temporarily suspended from its activity. This is done
by invoking sleep() or wait () method. A suspended thread can then be resumed, allowing it
to pick up from where it left off, by calling notify() method or when the sleep interval expires.
A thread can be blocked when waiting for a resource and unblocked once things are done.
Dead State:
A thread comes to a dead state if it is over with the task. At any time, a thread can be
terminated, which halts its execution immediately. Once terminated, a thread cannot be
resumed.
11
11
We enable you to leverage knowledge
anytime, anywhere!
Thread scheduling
There are 2 techniques for thread scheduling
Pre-emptive and time-sliced
In preemptive scheduling, the thread with a higher
priority preempts threads with lower priority and grabs
the CPU
In time-sliced or round robin scheduling, each thread will
get some time of the CPU
Java runtime systems thread scheduling algorithm is
preemptive but it depends on the implementation
Solaris is preemptive, Macintosh and Windows are time
sliced
In theory, a thread with high priority should get more
CPU time, but practically it may depend on the platform
There are 2 techniques for thread scheduling
Pre-emptive and time-sliced
In preemptive scheduling, the thread with a higher priority preempts threads with lower
priority and grabs the CPU
In time-sliced or round robin scheduling, each thread will get some time of the CPU
The Java runtime system's thread scheduling algorithm is Fixed Priority preemptive. If at any
time a thread with a higher priority than all other runnable threads becomes runnable, the
runtime system chooses the new higher priority thread for execution. The new higher priority
thread is said to preempt the other threads.
In the case when two Threads with same priority are competing for CPU then is up to the
underlying platform to decide on how to handle.
Solaris is preemptive, Macintosh and Windows are time sliced. In the case of Macintosh and
Windows the threads of equal priority are time-sliced automatically in round-robin fashion. In
case of OS of preemptive types the threads of equal priority must yield control to its peers
voluntarily. If not done, then others has to wait.
12
12
We enable you to leverage knowledge
anytime, anywhere!
Thread Priorities
Thread priority can be used by the scheduler to decide
which thread is to be run
The priority of a Thread can be set using the method
setPriority()
t.setPriority(7);
The method getPriority() will return the priority of a
Thread
t.getPriority()
The priority can vary from 1 to 10 or
Thread.MIN_PRIORITY to Thread.MAX_PRIORITY
Normally a Thread will have the priority 5 or
Thread.NORM_PRIORITY
Java assigns to each thread a priority that determines how that thread should be treated with
respect to others. Thread priorities are integers that specify the relative priority of one thread
to another. Thread priority can be used by the scheduler to decide which thread is to be run.
The priority of a Thread can be set using the method setPriority(). The method
getPriority() will return the priority of a Thread. The priority can vary from 1 to 10.
Thread.MIN_PRIORITY and Thread.MAX_PRIORITY can also be used for values of 1 and
10. Normally a Thread will have the priority value of 5 also represented as
Thread.NORM_PRIORITY
Thread priority is used to decide when to switch from one running thread to the next. This
process is switching is called as context switch.
13
13
We enable you to leverage knowledge
anytime, anywhere!
Ensuring time-slicing (1 of 2)
The programmer should write code to ensure that time-
slicing occurs even when the application is running in a
preemptive environment
The static method sleep of the Thread class will make a
thread sleep for specified number of milliseconds
Thread.sleep(1000);
A sleeping thread can be interrupted by another thread
using the method interrupt()
When interrupted, sleep method will throw an
InterruptedException
The programmer should write code to ensure that time-slicing occurs even when the
application is running in a preemptive environment.
The static method sleep() of the Thread class will make a thread sleep for specified number
of milliseconds.
A sleeping thread can be interrupted by another thread using the method interrupt()
When interrupted, sleep method will throw an InterruptedException
14
14
We enable you to leverage knowledge
anytime, anywhere!
Ensuring time-slicing (2 of 2)
The yield method of the class Thread will give a chance
to other threads to run
t.yield();
The yield() method ensures that the thread behaves like
a polite thread and not a selfish thread
yield():
It is used to give the other threads of the same priority a chance to execute. If other threads
at the same priority are runnable, yield() places the calling thread in the running state into
the runnable pool and allows another thread to run. If no other threads are runnable at the
same priority, yield() does nothing.
15
15
We enable you to leverage knowledge
anytime, anywhere!
isAlive() and join() methods
The state of a thread can be queried using the isAlive()
method
Returns true if the thread has been started but not
completed its task
A thread can wait for another thread to finish by using
the join() method
isAlive() method is used to determine if a thread is still alive. The term alive does not imply
that the thread is running; it returns true for a thread that has been started but not completed
its task.
The method that you will more commonly use to wait for a thread to finish is called join().
This method waits until the thread on which it is called terminates.
16
16
We enable you to leverage knowledge
anytime, anywhere!
Thread synchronization (1 of 2)
In a multithreaded environment 2 or more threads may
access a shared resource
There should be some means to ensure that the shared
resource is accessed by only one thread at a time. This
is termed as synchronization
Every such shared object has a mutually exclusive lock
called monitor
Only one thread can get the monitor of an object at a
time
In a multithreaded environment two or more threads may access a shared resource.
There should be some means to ensure that the shared resource is accessed by only one
thread at a time. There used is synchronization
In the case of synchronization every such shared object has a mutually exclusive lock called
monitor
Only one thread can get the monitor of an object at a time.
17
17
We enable you to leverage knowledge
anytime, anywhere!
Thread synchronization (2 of 2)
Synchronization can be ensured by using the keyword
synchronized
A method or block of code can be made synchronized
Example
public class Account{
int bankBalance;
public synchronized void creditAccount (int amount) {
bankBalance+= amount;
}
}
Synchronization can be ensured by using the keyword synchronized
A method or block of code can be made synchronized.
Here is an example where a method is synchronized.
When a thread is inside the synchronized method, all other threads that try to call it or any
other synchronized method on the same instance have to wait.
18
18
We enable you to leverage knowledge
anytime, anywhere!
Inter-thread communication (1 of 3)
Thread must wait for the state of an object to change
while executing a synchronized method, it may call wait()
void wait()
void wait (long timeout)
The thread calling wait will release the lock on that
particular object
The thread will wait till it is notified by another thread
owning the lock on the same object
void notify()
void notifyAll()
Threads also provide a secondary benefit: They do away with polling. Polling is usually
implemented by a loop that is used to check some condition repeatedly. Once the condition
is true, appropriate action will be taken. So, in the case of working with sharable resources
the thread needs poll i.e it need to repeatedly check if the monitor lock is available in order
to enter a synchronized method, thereby wasting CPU cycles
To avoid polling, java includes an elegant inter-thread communication mechanism via the
wait(), notify(), and notifyAll() methods. These methods belong to the Object class and can
be called from within synchronized context only.
These methods work as follows:
A Thread is inside a synchronized method. It needs the state associated with its object to be
changed. Then it must wait for the state of the object to change. It will wait by calling wait()
method inside the synchronized method which will make the thread to give up the monitor
and goes to sleep state. The thread will wait till it is notified by another thread owning the
lock on the same object.
19
19
We enable you to leverage knowledge
anytime, anywhere!
Inter-thread communication (2 of 3)
If there are multiple threads waiting on the same object,
the notify() method will notify one among them
The thread that would be notified cannot be predicted
It is safer to call notifyAll(), since it will notify all waiting
threads
Code for synchronization should be written carefully else
may lead to a dead-lock situation
wait() tells the calling thread to give up the monitor until some other thread enters the same
monitor and calls notify().
notify() wakes up the one thread that called wait() on the same object (if there are more than
one thread in wait state, then it is not known which thread would wake up.)
notifyAll() wakes up all the threads that called wait() on the same object.
20
20
We enable you to leverage knowledge
anytime, anywhere!
Inter-thread communication (3 of 3)
Example
public class Account { public class Account { public class Account { public class Account {
int int int int bankBalance bankBalance bankBalance bankBalance; ;; ;
public synchronized void public synchronized void public synchronized void public synchronized void debitAccount debitAccount debitAccount debitAccount (int amount) { (int amount) { (int amount) { (int amount) {
while((bankBalance while((bankBalance while((bankBalance while((bankBalance - -- - amount)<0) wait(); amount)<0) wait(); amount)<0) wait(); amount)<0) wait();
bankBalance bankBalance bankBalance bankBalance - -- -= amount; = amount; = amount; = amount;

} }} }
public synchronized void public synchronized void public synchronized void public synchronized void creditAccount creditAccount creditAccount creditAccount (int amount) { (int amount) { (int amount) { (int amount) {
bankBalance bankBalance bankBalance bankBalance += amount; += amount; += amount; += amount;
notify(); notify(); notify(); notify();

} }} }
} }} }
In the above code, the bankBalance is a sharable resource between threads that are
executing debitAccount() and creditAccount() method. Both the methods have been
declared as synchronized so that only one thread can access one of these methods
completely at a time. i.e. While a thread is inside a synchronized method, all the other
threads that try to call it or any other synchronized method on the same instance have to
wait.
debitAccount() method debits amount from bankBalance. The bankBalance should not be
let with a negative value. So a check is made to see whether the sufficient amount is
available before debiting the amount. If not the debit process should not happen. i.e the
activity must be kept in the pending state till the required amount gets credited.
This can be done as follows. The threads that enter the debitAccount() method on seeing the
lowbalance has to wait till another thread can enter creditaccount method and updates the
balance. Since both the methods are synchorized only one thread can be active at a time on
any of the methods of the account object. So the first thread calls wait() and gives up the
monitor which will be used by second thread and finishes it work and notifies the first thread
by calling notify(). Now the first thread resumes and finish of the task.
21
21
We enable you to leverage knowledge
anytime, anywhere!
Inter-thread communication[Example]
class Account {
int bankBalance;
public synchronized void debitAccount (int
amount) {
try{
System.out.println("Checking for bal");
while((bankBalance - amount)<0){
System.out.println("going to
wait"); wait(); }
System.out.println("debiting..");
bankBalance -= amount;
}catch(Exception e){} }
public synchronized void creditAccount (int
amount) {
bankBalance += amount;
System.out.println("bal="+bankBalance+"
notify");
notify(); } }
class Thread1 extends Thread{
Account ac;
Thread1(Account ac){
this.ac=ac; }
public void run(){
ac.debitAccount(300); }
}
class Thread2 extends Thread{
Account ac;
Thread2(Account ac){
this.ac=ac; }
public void run(){
int i=100;
while(i<=300){
ac.creditAccount(100);
i+=100;
} } }
public class ITCCheck{
public static void main(String[] args){
Account ac=new Account();
Thread1 t1=new Thread1(ac);
t1.start();
Thread2 t2=new Thread2(ac);
t2.start();
} }
This program illustrates Inter-thread communication. Pause the presentation and analyze
the code and result.
22
22
We enable you to leverage knowledge
anytime, anywhere!
Thread Groups
Represents a set of threads
Can also contain other thread groups, creating a hierarchy
of thread groups
Provides a single-point control on the threads belonging to
the thread group
Creation time association is for the life time of the thread
ThreadGroup threadGroup = new
ThreadGroup("MyGroup");
Some of the important methods of ThreadGroup are
activeCount(), destroy(), setMaxPriority(), setDaemon()
Represents a set of threads
Can also contain other thread groups, creating a hierarchy of thread groups
Provides a single-point control on the threads belonging to the thread group
ThreadGroup threadGroup = new ThreadGroup("MyGroup"); creates a new thread group.
Some of the important methods of ThreadGroup are activeCount(), destroy(), setMaxPriority()
and setDaemon()
23
23
We enable you to leverage knowledge
anytime, anywhere!
Daemon Thread
Daemon Thread is a thread that will run in the
background, serving other threads
So, a program can stop, if all non-daemon threads have
finished execution
A thread can be made a daemon by calling the method
setDaemon(true) before calling its start() method
Can query thread status using the method isDaemon()
Daemon Thread is a thread that will run in the background, serving other threads.
So, a program can stop, if all non-daemon threads have finished execution.
A thread can be made a daemon by calling the method setDaemon(true) before calling its
start() method.
Can query thread status using the method isDaemon().
The system itself always has a few daemon threads running, one of which is the garbage
collector.
24
ER/CORP/CRS/LA46/003
Module 2- Concurrency
In Multithreading module, we have discussed the low level APIs that help us to have Multithreading at
application level. In this module we will discuss some of the high-level concurrency features which
are introduced with Java 5.
25
25
We enable you to leverage knowledge
anytime, anywhere!
Concurrency
Packages added in Java 5 for the support of concurrent programming are
java.util.concurrent
Contains classes and interfaces useful in concurrent programming
java.util.concurrent.locks
Contains interfaces and classes providing a framework for locking
and waiting for conditions that is distinct from built-in synchronization
and monitors.
java.util.concurrent.atomic
Contains classes that support lock-free thread-safe programming on
single variables.
There are also new concurrent data structures added in the Java Collections Framework.
Need for high level APIs
Reduced Programmer effort
Increased performance
Improved maintainability
Increased reliability
Some of the high-level features are
Lock Objects
Executors
Synchronizers
Callables and Futures
Concurrent Collections
Atomic variables
Etc.
26
26
We enable you to leverage knowledge
anytime, anywhere!
Task Scheduling Framework
As discussed in Module 1 there are two ways to create threads.
Extending the Thread class
Extend the Thread class
Override the run() method
Create an object of the sub class and call the start method to execute
the Thread
Implementing the Runnable interface
Useful when the class is already extending another class and needs to
implement mutithreading
Implement the run() method
Create a thread object (the worker) and give it a Runnable object (the
job)
Start the thread by calling the start() method
This works fine for smaller applications but in larger applications the thread
management and creation has to be separated from the rest of the application.
This can be done by Executor which facilitates the standardized invocation,
scheduling and execution of threads..
27
27
We enable you to leverage knowledge
anytime, anywhere!
Task Scheduling Framework(Contd..)
Executor Interface
This interface provides a way of decoupling task submission from the
mechanics of how each task will be run, including details of thread use,
scheduling, etc.
An Executor is normally used instead of explicitly creating threads.
Example:
Executor executor = anExecutor;
executor.execute(new RunnableTask1());
Many Executor implementations impose some sort of limitation on how and
when tasks are scheduled.
ExecutorService Interface
Extends Executor interface
Has features that help manage the lifecycle of both the individual tasks and
the executor itself.
Executors
It is a factory for creating various kinds of ExecutorService
implementations.
28
28
We enable you to leverage knowledge
anytime, anywhere!
Task Scheduling Framework(Contd..)
import java.util.concurrent.*;
class RunnableThread implements Runnable
{
RunnableThread()
{
System.out.println("Child Thread: ");
}
public void run()
{
System.out.println("Hi I'm a new thread");
}
}
public class Main {
public static void main(String[] args) {
ExecutorService e1=Executors.newSingleThreadExecutor();
e1.execute(new RunnableThread()); } }
This example shows how to work with Executors.
Executors.newSingleThreadExecutor() method returns the executor which executes the
command sometime in the future.
29
29
We enable you to leverage knowledge
anytime, anywhere!
Callables and Futures
In the previous versions of Java there was no provision for the
callable thread to return values to the calling thread.
With the addition of Callable<V> interface it is made possible.
The callable thread class has to implement Callable interface.
The Callable interface is similar to Runnable, in that both are
designed for classes whose instances are potentially executed
by another thread. A Runnable thread, however, does not
return a result.
Callable thread has to implement call() method in the same
way as we implement the run() method when Runnable
interface is used.
Call() methods return the required data to the calling thread.
30
30
We enable you to leverage knowledge
anytime, anywhere!
Callables and Futures
Calling thread uses the submit method on the
ExecutorService instance instead of using execute()
method.
Submit() method submits Callable object for execution and
returns a Future object. Calling thread can then call the get()
method on the Future object to retrieve the result sent by the
callable thread.
If the result is ready, it will be returned
If not the calling thread will be blocked.
31
31
We enable you to leverage knowledge
anytime, anywhere!
Callables and Futures
class PriceCalculation implements
Callable<Double> {
double price=0;
int itemCode;
PriceCalculation(int itemCode){
this.itemCode=itemCode;
}
public Double call(){
switch(itemCode){
case 101:
price=1000.0; break;
case 102:
price=2000.0; break;
}
return new Double(price);
} }
class DiscountCalculation implements
Callable<Double>{
double disPer=0;
int itemCode;
DiscountCalculation(int itemCode){
this.itemCode=itemCode;
}
public Double call(){
switch(itemCode){
case 101:
disPer=10; break;
case 102:
disPer=20; break;
}
return new Double(disPer);
} }
public class Main {
public static void main(String[] args) {
ExecutorService
pool=Executors.newFixedThreadPool(2);
Future<Double> price=pool.submit(new
PriceCalculation(101));
Future<Double> discount=pool.submit(new
DiscountCalculation(101));
try {
System.out.println("Net amount to be paid is:
"+(price.get()-(price.get()*discount.get()/100)));
} catch (Exception e){}
}
}
The given program explains the usage of Callable and Future Interfaces.
32
32
We enable you to leverage knowledge
anytime, anywhere!
Synchronizers
Java 5 introduced general purpose classes such as
Semaphore
Mutex
Etc.
Which facilitate coordination between the threads.
These classes are added as a part of java.util.concurrent
package.
33
33
We enable you to leverage knowledge
anytime, anywhere!
Semaphores
In Java a Semaphore is a lock with a counter.
It is typically used to restrict access to fixed size pool of
resources.
The Semaphore object will be created with the count which
is the same as the number of resources in the pool.
Thread which tries to access the resource will call acquire()
method on the Semaphore object.
This will return when the count>0.
If the count is zero then the thread will be blocked till the
release() method is called on the semaphore object by
another thread.
acquire() and release() are thread safe atomic operations.
34
34
We enable you to leverage knowledge
anytime, anywhere!
Semaphores (Contd...)
Semaphores are usually implemented as follows.
private Semaphore available;
private Resource[] resources;
public Resource (int poolSize){
available=new Semaphore(poolSize);
/*initialize the Resources*/
}
public Resource getResource(){
try{available.aquire();}catch(Exception e){}
/*Provide Resource from the pool*/
}
public void returnResource(Resource r){
/*Return Resource to the pool*/
available.release();}
35
35
We enable you to leverage knowledge
anytime, anywhere!
Semaphores (Contd...)
class Account{
double amt;
Account(double amt){
this.amt=amt; }
public void withdraw(double amt){
this.amt-=amt; }
public void deposit(double amt){
this.amt+=amt; }
public double display(){
return amt; }
}
class ThreadA implements Runnable{
Semaphore sa; Account acc;
ThreadA(Semaphore sa,Account acc){
this.sa=sa; this.acc=acc;
}
public void run(){
try {
sa.acquire(); acc.withdraw(200.0);
Thread.sleep(1000);
} catch (InterruptedException ex) {}
System.out.println("Amount after withdrawal:
"+acc.display());
sa.release(); } }
class ThreadB implements Runnable{
Semaphore sa;
Account acc;
ThreadB(Semaphore sa,Account acc){
this.sa=sa; this.acc=acc; }
public void run(){
try {
sa.acquire(); acc.deposit(100.0);
Thread.sleep(1000);
} catch (InterruptedException ex) {}
System.out.println("Amount after Deposit:
"+acc.display());
sa.release();
} }
public class Main {
public static void main(String[] args) {
// Semaphore working with Single Object pool;
Account acc=new Account(10000);
Semaphore s1=new Semaphore(1);
ExecutorService
e1=Executors.newFixedThreadPool(2);
e1.execute(new ThreadA(s1,acc));
e1.execute(new ThreadB(s1,acc));
} }
Here is a simple example to work with Semaphore which is associated with the account
object.
36
36
We enable you to leverage knowledge
anytime, anywhere!
Concurrent Collections
There are also new concurrent data structures added in
the Java Collections Framework.
The purpose of these classes is to provide high-
performance, highly-scalable, thread-safe versions of the
basic collection types.
They are added as a part of java.util.concurrent package.
Some of them are,
BlockingQueue
ConcurrentMap
ConcurrentNavigableMap
ConcurrentLinkedQueue
Etc.
37
37
We enable you to leverage knowledge
anytime, anywhere!
Atomic Variables
Atomic variables have features that minimize
synchronization and avoids memory consistency errors.
Atomic variables are fine-grained and light-weight than
locks, and are critical for implementing high-performance
concurrent code on multiprocessor systems.
Atomic variables limit the scope of contention to a single
variable.
With algorithms based on atomic variables instead of
locks, threads are more likely to be able to proceed
without delay.
Atomic classes AtomicInteger, AtomicLong, etc. in
java.util.concurrency.atomic package help us to work
with atomic variables.
All classes have get and set methods that work like read
and write to volatile variables.
38
38
We enable you to leverage knowledge
anytime, anywhere!
Locks
Package java.util.concurrent.locks contains interfaces
and classes providing a framework for locking and
waiting for conditions that is distinct from built-in
synchronization and monitors.
Lock Interface
Provides extensive locking operations than synchronized block.
Simple to handle locking and unlocking.
Lock l = ...; l.lock();
try {
// access the resource protected by this lock
} finally {
l.unlock();}
Has tryLock() method which helps the threads to
acquire Locks with out blocking
39
39
We enable you to leverage knowledge
anytime, anywhere!
Locks (contd..)
Reentrant Lock
This is the complete implementation of Lock interface.
Holding thread can call lock() multiple times and wont block.
Lock() acquires the lock if it is not held by another thread and
returns immediately, setting the lock hold count to one.
If the current thread already holds the lock then the hold count is
incremented by one and the method returns immediately.
If the lock is held by another thread then the current thread
becomes disabled for thread scheduling purposes and lies
dormant until the lock has been acquired, at which time the lock
hold count is set to one.
ReadWrite Lock
Has two locks that control the read and write access.
readLock() method returns a lock for reading
writeLock() method returns the lock for writing.
40
40
We enable you to leverage knowledge
anytime, anywhere!
Locks (contd..)
class Account{
double amt;
Lock lock=new ReentrantLock();
Account(double amt){
this.amt=amt; }
public void withdraw(double amt){
this.amt-=amt; }
public void deposit(double amt){
this.amt+=amt; }
public double dispay(){
return amt; } }
class ThreadA implements Runnable{
Account acc;
ThreadA(Account acc){
this.acc=acc; }
public void run(){
try {
acc.lock.lock(); acc.withdraw(200.0);
Thread.sleep(1000);
System.out.println("After withdrawal:
"+acc.dispay());
} catch (Exception ex) { }
finally{ acc.lock.unlock();
} } }
class ThreadB implements Runnable{
Account acc;
ThreadB(Account acc){
this.acc=acc;
}
public void run(){
try {
acc.lock.lock();
acc.deposit(100.0); Thread.sleep(1000);
System.out.println("After deposit:
"+acc.dispay());
} catch (Exception ex) { }
finally{
acc.lock.unlock();
} }
}
public class Main {
public static void main(String[] args) {
Account acc=new Account(10000);
ExecutorService
e1=Executors.newFixedThreadPool(2);
e1.execute(new ThreadA(acc));
e1.execute(new ThreadB(acc));
}
}
Here is a simple example that work with locks.
41
ER/CORP/CRS/LA46/003
Advanced Java Programming
Module 3 - Input Output Streams & Serialization
We shall now move on to the module on Input Output Streams & Serialization.
42
42
We enable you to leverage knowledge
anytime, anywhere!
Lesson Outcomes
After completion of the module you will be able to
understand about
What are Streams?
What are the types of streams available?
What are the classes available to work with streams?
How the buffered streams are advantageous over the
non-buffered streams?
What is Serialization?
After completion of the module you will be able to understand about
What are Streams?
What are the types of streams available?
What are the classes available to work with streams?
How the buffered streams are advantageous over the non-buffered streams? and
What is Serialization?
43
43
We enable you to leverage knowledge
anytime, anywhere!
Streams
Streams are channels of communication between
programs and source/destination of data
A stream is either a source of bytes or a destination for
bytes.
Provide a good abstraction between the source and
destination
Abstract away the details of the communication path from
I/O operation
Streams hide the details of what happens to the data
inside the actual I/O devices.
Streams can read/write data from/to blocks of memory,
files and network connections
A stream is a path of communication between the source of some information and its
destination. The source and the destination can be a file, the computer's memory, or even
the Internet. An input stream allows you to read data from a source, and an output stream
allows you to write data to a destination.
44
44
We enable you to leverage knowledge
anytime, anywhere!
Streams(Contd)
Source Program
Reads
Program Destination
Writes
Stream
Stream
This diagram shows how streams work with the source and destination.
45
45
We enable you to leverage knowledge
anytime, anywhere!
Input and Output
The Java Input/Output system is designed to make it
device independent
The classes for performing input and output operations
are available in the package java.io
Java I/O System is built on 4 abstract classes. They are,
InputStream
OutputStream
Reader and
Writer.
There are several subclasses inherited from these abstract classes each has a concrete
purpose. Though we use only those subclasses in the program, the basic functionalities are
defined in the top level classes for use by all the stream subclasses which help us to access
any device in an uniform way.
The classes for performing input and output operations are available in the package java.io
46
46
We enable you to leverage knowledge
anytime, anywhere!
Javas Input-Output System
The basic I/O system of Java can handle only two
types of data
Bytes
Characters
Java Input/Output System
Character oriented System
Byte Oriented System
The basic I/O system of Java can handle only two types of data. They are,
Bytes and
Characters.
47
47
We enable you to leverage knowledge
anytime, anywhere!
Byte I/O
Byte-Oriented System
The following are the two abstract classes provided for
reading and writing bytes
InputStream - Reading bytes
OutputStream - Writing bytes
For performing I/O operations, we depend on the sub
classes of these two classes
A stream, which receives and sends information as bytes, is called a byte-oriented stream.
At the top of the hierarchy are the two abstract classes: InputStream and OutputStream for
input and output respectively. These classes define many important methods for handling
the streams. The read() and write() methods in the InputStream and OutputStream are used
for reading and writing to and from streams respectively. Both these methods are abstract
and are implemented by all the classes derived from these InputStream and OutputStream
classes .
48
48
We enable you to leverage knowledge
anytime, anywhere!
Methods in InputStream
int available()
void close()
void mark(int numberofBytes)
boolean markSupported()
int read()
int read(byte buffer[])
int read(byte buffer[], int offset, int numberofBytes)
void reset()
long skip(long numberofBytes)
Methods defined in InputStream are,
available() - this returns the number of bytes of input currently available for reading.
close() - this closes the input source. Further read will generate IOException
mark(int numberofBytes) - This places a mark at the current point in the input stream that will remain valid
until numberofBytes are read.
markSupported() returns true if mark()/reset() is supported.
read() Returns the integer representation of the next available byte in the input.
read(byte buffer[]) It will try to read bytes into the buffer till the buffer can hold and returns the number of
bytes that are successfully read.
read(byte buffer[], int offset, int numberofBytes) - It will try to read specified numberofBytes into the buffer
starting from buffer[offset] and returns the number of bytes that are successfully read.
reset() It will reset the input pointer to the previously set mark.
skip(long numberofBytes) ignores the numberofBytes of input and returns the numberofBytes ignored
actually.
49
49
We enable you to leverage knowledge
anytime, anywhere!
Methods in OutputStream
void close()
void flush()
void write(int b)
void write(byte buffer[])
void write(byte buffer[], int offset, int numberofBytes)
Methods defined in OutputStream are,
close() This closes the output stream.
flush() It flushes the output buffers.
write(int b) this writes a byte to an output stream
write(byte buffer[]) - this writes an array of bytes to the output stream
write(byte buffer[], int offset, int numberofBytes) this writes a specified range of bytes from a
byte array to the output stream
50
50
We enable you to leverage knowledge
anytime, anywhere!
Input Stream hierarchy
InputStream
FilterInputStream
ByteArrayInputStream
FileInputStream
ObjectInputStream
BufferedInputstream
DataInputStream
PushbackInputStream
Here are the Byte Input Stream Classes derived from the abstract class InputStream.
ByteArrayInputStream
It is used to create an input stream from an array of bytes. Allows a buffer in memory to be used as an
InputStream.
FileInputStream
For reading information from a file.
ObjectInputStream
It supports retrieving the stored state of an object. It is associated with deserialization.
Filtered Streams: There are the wrappers around underlying I/O streams that transparently provide
some extended level of functionality to the other InputSteam classes.
BufferedInputStream
This is one of the most valuable of all streams. Using a buffer, it prevents a physical read every time
when more data is needed. It uses buffered array of bytes that acts as a cache for future reading.
DataInputStream
Used to read primitives from a stream in a portable fashion. All the methods that instances of this class
understand are defined in a separate interface called DataInput, and implemented by this stream.
PushbackInputStream
Has a one byte push-back buffer with which it is possible to push back the last read byte. The filter
stream class.
51
51
We enable you to leverage knowledge
anytime, anywhere!
Output Stream hierarchy
OutputStream
FilterOutputStream
ByteArrayOutputStream
FileOutputStream
ObjectOutputStream
BufferedOutputstream
DataOutputStream
PrintStream
Here are the Byte Output Stream Classes derived from the abstract class OutputStream.
ByteArrayOutputStream
It is an implementation of an output stream that uses a byte array as the destination. The inverse of
ByteArrayInputStream, which creates an input stream from an array of bytes, the ByteArrayOutputStream, directs
an output stream into an array of bytes.
FileoutputStream
It is used for writing information to a file.
ObjectOutputStream
It supports permanently saving the state of an object. It is associated with serialization.
Filtered Streams: These are wrappers around underlying I/O streams that transparently provide some extended
level of functionality to the other OutputStream classes.
BufferedOutputStream
Using a buffer, it prevents a physical write every time data is sent.
DataOutputStream
It is used to write primitives to a stream in a portable fashion.
PrintStream
It is used for producing formatted output.
52
52
We enable you to leverage knowledge
anytime, anywhere!
Character I/O
Character-Oriented System
Since byte-oriented streams are inconvenient for
Unicode-compliant character- based I/O , Java has the
following abstract classes for performing character I/O
Reader class
Writer class
Support internationalization of Java I/O
Subclasses of Reader and Writer are used for handling
Unicode characters
Streams, which receive and send information as characters are called character oriented
streams. The abstract classes Reader and Writer are the base classes for all the character-
oriented streams. Two of the most important methods are, read() and write(), which read
and write characters of data, respectively. These methods are overridden by derived stream
classes. Java supports internationalization and for that UNICODE character set is used.
53
53
We enable you to leverage knowledge
anytime, anywhere!
Methods in Reader
void close()
void mark( int )
int read()
int read(char[] c)
int read(char [] c, int off , int numberofCharacters)
long skip(long num)
Methods defined in Reader Class are:
close() - this closes the input source.
mark(int numberofCharacters) - This places a mark at the current point in the input stream
that will remain valid until numberofCharacters are read.
read() - Returns the integer representation of the next available character in the input.
read(char[] c) - It will try to read Characters into the buffer till the buffer can hold and returns
the number of Characters that are successfully read.
read(char [] c, int off , int numberofCharacters) - It will try to read specified
numberofCharacters into the buffer starting from c[off] and returns the number of Characters
that are successfully read.
skip(long num) - ignores the number of Characters of input and returns the number of
Characters ignored actually.
54
54
We enable you to leverage knowledge
anytime, anywhere!
Methods in Writer
abstract void close()
abstract void flush()
void write( int c)
void write(char[] c, int off, int len)
void write(char[] c, int len)
void write(String str)
void write(String str, int off, int len)
Methods defined in Writer class are:
close() - This closes the output stream.
flush() - It flushes the output buffers.
write( int c), write(char[] c, int off, int len), write(char[] c, int len), write(String str) and
write(String str, int off, int len) writes to the output stream.
55
55
We enable you to leverage knowledge
anytime, anywhere!
Reader
Buffered Reader
FilteredReader
PushBackReader
FileReader
InputStreamReader
CharArrayReader
Reader Hierarchy
Here are the Character Input Stream Classes derived from the abstract class Reader
BufferedReader: Read text from a character-input stream and buffer characters so as to
provide efficient reading of characters, arrays, and lines. Using a buffer, it prevents a
physical read every time when more data is needed.
InputStreamReader: Input stream that reads bytes and decodes them into characters .
FilterReader :Abstract class for reading filtered character streams.
PushbackReader : Input stream that allows characters to be returned to the input stream.
CharArrayReader : Input stream that reads from a character array.
FileReader: Input stream that reads from a file
56
56
We enable you to leverage knowledge
anytime, anywhere!
Writer
BufferedWriter
PrintWriter FileWriter
OutputStreamWriter
CharArrayWriter
Writer Hierarchy
Here are the Character Output Stream Classes derived from the abstract class Writer
BufferedWriter: Buffered Output character stream
OutputStreamWriter: Output stream that translates characters to bytes
FilterWriter :Abstract class for writing filtered character streams
CharArrayWriter : Output stream that writes to a character array
FileWriter :Output stream that writes to a file
57
57
We enable you to leverage knowledge
anytime, anywhere!
InputStream The read() method (1 of 2)
The read() method reads a byte from the input device
and returns an integer
It returns an integer value or -1 if the end of the stream is
reached
The read() method of FileInputStream returns
-1 when it reaches end of file condition
In case of a successful read, the returned integer can be
typecasted to a byte to get the data read from the device
InputStream The read() method
The read() method reads a byte from the input device and returns an integer.
It returns -1 if the end of the stream is reached .
The read() method of FileInputStream returns -1 when it reaches end of file condition
In case of a successful read, the returned integer can be typecasted to a byte to get the data
read from the device
58
58
We enable you to leverage knowledge
anytime, anywhere!
InputStream The read() method (2 of 2)
Why is the byte embedded in an int?
Storing the byte into the low end of an integer, makes it
possible for the program to distinguish between -1 integer
representing end of data condition and -1 byte, a data
stored in the device
On reading a data of -1 byte successfully from a device, the
following integer is returned
00000000 00000000 00000000 11111111
The integer value of this is 255
This can be typecast to 11111111 which is the real data,
-1 byte
When a read fails, the following integer is returned
11111111 11111111 11111111 11111111
The integer value is -1 indicating end of data
Why is the byte embedded in an int?
Storing the byte into the low end of an integer, makes it possible for the program to
distinguish between -1 integer representing end of data condition and -1 byte, a data stored
in the device
On reading a data of -1 byte successfully from a device, the integer value of 255 is returned.
When a read fails, the integer value -1 is returned as shown here.
59
59
We enable you to leverage knowledge
anytime, anywhere!
Device Independent I/O (1 of 2)
The way in which I/O is performed is not changing with the
device
The following method will write three bytes into any output
device
ByteWriter byteWriter = new ByteWriter();
byteWriter.writeBytes(System.out); //Write to the monitor
byteWriter.writeBytes(byteArrayOutputStream); //Write to an array
byteWriter.writeBytes(fileOutputStream); //Write to a file
..
public void writeBytes(OutputStream outputStream){
try{
outputStream.write(65);
outputStream.write(66);
outputStream.write(67);
}
catch(IOException exception){
System.out.println(exception); }}
The way in which I/O is performed is not changing with the device. Here is an example. The
method shown here can write three bytes to any output stream in the same way.
60
60
We enable you to leverage knowledge
anytime, anywhere!
Filter Classes
The Java I/O System uses filter classes to build
specialized I/O streams that provide particular
capabilities as needed.
Typically an instance of a lower level class is created and
then it is wrapped inside more specialized stream
instances by passing it to the wrapper via a constructor
argument.
Filter Classes
The Java I/O System uses filter classes to build specialized I/O streams that provide
particular capabilities as needed.
Typically an instance of a lower level class is created and then it is wrapped inside more
specialized stream instances by passing it to the wrapper via a constructor argument.
Typical extensions that can be achieved through this are buffering, character translation, and
raw data translation.
61
61
We enable you to leverage knowledge
anytime, anywhere!
Non-Buffered IO
Reading and writing a byte at a time can be expensive in
terms of processing time

H
a
r
d

D
i
s
k
Program
FileStream

Access H/D
Gets/writes first
byte
Access H/D
Gets/writes
second byte
Access H/D
Gets/writes third
byte
gets/writes
data
Reading and writing a byte at a time is an expensive task. It requires lot of things to be done
for a single read/write.
This diagram shows how the read and write of bytes are handled.
62
62
We enable you to leverage knowledge
anytime, anywhere!
Buffered IO
Buffering helps java to store an entire block of values
into a buffer
It never has to go back to the source and ask for
more, unless it runs out

H
a
r
d

D
i
s
k
Program FileStream

Access H/D
Gets/writes a set of
bytes as per the buffer
siz e per access
gets/writes
data
Buffer
Transfe r of group
of byte s
T
r
a
n
s
fe
r
o
f
o
n
e
b
y
t
e
a
t
a
t
im
e
With Buffering we can improve the performance of Read and Write process.
Buffering helps java to store an entire block of values into a buffer.
It never has to go back to the source and ask for more, unless it runs out.
63
63
We enable you to leverage knowledge
anytime, anywhere!
Example-Buffering
The following code snippet writes bytes to a file using buffering
mechanism
FileOutputStream fileOutputStream=new
FileOutputStream(Data);
BufferedOutputStream bufferedOutputStream=new
BufferedOutputStream(fileOutputStream);
byte data1 = 65, data2 = 66, data3 = 67;
bufferedOutputStream.write(data1);
bufferedOutputStream.write(data2);
bufferedOutputStream.write(data3);
bufferedOutputStream.close();
BufferedOutputStream
FileOutputStream
H
/
D
Filter Classes
Here is an example for buffering. This code writes data to the file using Buffering
mechanism. Here we first wrap a FileStream with a BufferedStream. Buffered classes
improve the performance of I/O by providing intermediate data storage buffers. The data
must fill the buffer to a certain level before it is sent to the next stage, thus performing fewer
time-consuming operations. Note that this can require the "flushing" of data near the end of
the transmission when the data did not reach the level required for release.
64
64
We enable you to leverage knowledge
anytime, anywhere!
DataInputStream and DataOutputStream
InputStream and OutputStream deal with bytes only
DataInputStream and DataOutputStream are filter
classes that wrap around InputStream and OutputStream
objects so that primitive types can be read and written
DataInputStream has the methods
readInt
readDouble
readBoolean
readXXX
DataOutputStream has the methods
writeInt
writeDouble
writeBoolean
writeXXX
The DataInputStream class provides the capability to read arbitrary objects and primitive
types from an input stream. The filter provided by this class can be nested with other input
filters.
The DataOutputStream class provides an output complement to DataInputStream. It allows
arbitrary objects and primitive data types to be written to an output stream. It also keeps
track of the number of bytes written to the output stream. It is an output filter and can be
combined with any output-filtering streams.
65
65
We enable you to leverage knowledge
anytime, anywhere!
PushbackInputStream
Pushback is used on an input stream for reading a byte
and then pushing it back to the stream as if it is unread
The filter class PushbackInputStream provides the
following methods for pushing back
void unread(int bytevalue)
void unread(byte buffer[])
void unread(byte buffer[], int offset, int numBytes)
When reading an input, you often need to peek at the next byte to see if it is the value that
you expect. Java provides PushbackInputStream for this purpose. You can read the byte
from the stream and push it back to the stream by unreading it.
The first form of unread() method pushes back the low order byte of bytevalue. This will be
the next byte returned by call to read().
The second form of unread() returns the bytes in the buffer.
The third form of unread() pushes back numBytes bytes beginning at offset from buffer.
66
66
We enable you to leverage knowledge
anytime, anywhere!
PrintStream
This filter class provides functionality to print all data
types.
It provides two methods, print() and println(), that are
overloaded to print any primitive data type or object.
Objects are printed by first converting them to strings
using their toString() method inherited from the Object
class.
PrintStream class has the following constructor
PrintStream(OutputStream outputStream)
System.out is a PrintStream object
PrintStream filter class provides functionality to print all data types.
It provides two methods, print() and println(), that are overloaded to print any primitive data
type or object.
Objects are printed by first converting them to strings using their toString() method inherited
from the Object class.
PrintStream class has the following constructor
PrintStream(OutputStream outputStream)
System.out is a PrintStream object
67
67
We enable you to leverage knowledge
anytime, anywhere!
Bridge Classes
Two classes act as bridge between byte streams and
characters
InputStreamReader
OutputStreamWriter
InputStreamReader wraps around an InputStream object
and helps to read characters from an InputStream
OutputStreamWriter wraps around an OutputStream
object and helps to write characters into an
OutputStream
Two classes that act as bridge between byte streams and character streams are
InputStreamReader
OutputStreamWriter
InputStreamReader wraps around an InputStream object and helps to read characters from
an InputStream.
OutputStreamWriter wraps around an OutputStream object and helps to write characters
into an OutputStream.
68
68
We enable you to leverage knowledge
anytime, anywhere!
What is Serialization?
Persistence:
The capability of an object to exist beyond the
execution of the program which created it.
In other words, saving the state of an object in some
permanent storage device, such as file
If the object exists beyond the execution of the program that created it then it is known as
persistence. Serialization is the key factor for implementing persistence. Serialization allows
to store objects in the files, communicate them across networks and use them in distributed
applications.
69
69
We enable you to leverage knowledge
anytime, anywhere!
Serialization Mechanism
Serializable objects can be converted into stream of
bytes
This stream of bytes can be written into a file
These bytes can be read back to re-create the object
Only those objects that implements java.io.Serializable
interface can be serialized
Serialization Mechanism
Where Serializable objects can be converted into stream of bytes
This stream of bytes can be written into a file
These bytes can be read back to re-create the object
Only those objects that implements java.io.Serializable or java.io. Externalizable interface
can be serialized
70
70
We enable you to leverage knowledge
anytime, anywhere!
ObjectOutputStream and ObjectInputStream
Filter classes that help to write and read Serializable
objects
ObjectOutputStream wraps around any OutputStream and
helps to write a Serializable object into the OutputStream
ObjectOutputStream(OutputStream outputStream)
The method writeObject(Object object) will write the object
to the underlying OutputStream object
ObjectInputStream wraps around any InputStream and
helps to read a stream of bytes as an Object from the
InputStream
ObjectInputStream(InputStream inputStream)
The method readObject() will read a stream of bytes,
convert them into an Object and return it
ObjectOutputStream and ObjectInputStream Filter classes help us to write and read
Serializable objects
ObjectOutputStream wraps around any OutputStream and helps to write a Serializable
object into the OutputStream
The method writeObject(Object object) will write the object to the underlying OutputStream
object
ObjectInputStream wraps around any InputStream and helps to read a stream of bytes as an
Object from the InputStream
The method readObject() will read a stream of bytes, convert them into an Object and return
it
71
71
We enable you to leverage knowledge
anytime, anywhere!
Security: an issue in serialization
Serialized objects can be sent over network
Can be accidentally or deliberately modified
Also sensitive data can be read
Solution
Encrypt the object during serialization using Security API
Ensure that sensitive objects do not implement
Serialializable or Externalizable
Serialized objects can be sent over network. While transmitting it can be accidentally or
deliberately modified and also sensitive data can be read.
So the Solution is
Encrypt the object during serialization using Security API.
But the best way is to Ensure that sensitive objects do not implement Serialializable or
Externalizable interfaces.
72
ER/CORP/CRS/LA46/003
Advanced Java Programming
Module 4 - JDBC
We shall now move on to the module on JDBC.
73
73
We enable you to leverage knowledge
anytime, anywhere!
Lesson Outcomes
After completion of the module you will be able to
understand
What is JDBC?
What are the advantages of using JDBC?
How to work with a database using JDBC? and
Transaction control in JDBC.
After completion of the module you will be able to understand
What is JDBC?
What are the advantages of using JDBC?
How to work with a database using JDBC? and
Transaction control in JDBC.
74
74
We enable you to leverage knowledge
anytime, anywhere!
JDBC
The JDBC (Java Database Connectivity) API helps a
Java program to access a database in a standard
way
JDBC is a specification that tells the database vendors
how to write a driver program to interface Java programs
with their database
The JDBC (Java Database Connectivity) API helps a Java program to access a database
in a standard way.
JDBC is a specification that tells the database vendors how to write a driver program to
interface Java programs with their database.
75
75
We enable you to leverage knowledge
anytime, anywhere!
JDBC [Contd..]
A Driver written according to this standard is called the
JDBC Driver
All related classes and interfaces are present in the
java.sql package
All JDBC Drivers implement the interfaces of java.sql
A Driver written according to JDBC standard is called the JDBC Driver
All related classes and interfaces are present in the java.sql package
All JDBC Drivers implement the interfaces of java.sql
76
76
We enable you to leverage knowledge
anytime, anywhere!
JDBC Drivers
There are 4 types of drivers --Type1, Type2,
Type3,Type4
There are 4 types of drivers --Type1, Type2, Type3,Type4 drivers.
Let us see one by one in detail.
77
77
We enable you to leverage knowledge
anytime, anywhere!
Type1 Driver (JDBC-ODBC bridge driver)
Calling Java Application
JDBC API
JDBC Driver Manager
JDBC - ODBC Bridge
(Type I Driver)
ODBC Driver
DataBase
Database Library APIs
The JDBC type 1 driver, also known as the JDBC-ODBC bridge is a database driver
implementation that uses the ODBC. The driver converts JDBC method calls into ODBC
function calls. The bridge is usually used when there is no pure-Java driver available for a
particular database.
The driver is implemented by the sun.jdbc.odbc.JdbcOdbcDriver class and comes with the
Java 2 SDK, Standard Edition.
The driver is platform-dependent as it makes use of ODBC which in turn depends on native
libraries of the operating system. Also, using this driver has got other dependencies such as
ODBC must be installed on the computer having the driver and the database which is being
connected to must support an ODBC driver. Hence the use of this driver is discouraged if
the alternative of a pure-Java driver is available.
78
78
We enable you to leverage knowledge
anytime, anywhere!
Type2 Driver (Native-API driver )
Calling Java Application
JDBC API
JDBC Driver Manager
Native - API driver
(Type II Driver)
DataBase
Database Library APIs
The JDBC type 2 driver, also known as the Native-API driver is a database driver
implementation that uses the client-side libraries of the database. The driver converts JDBC
method calls into native calls of the database API.
The type 2 driver is not written entirely in Java as it interfaces with non-Java code that
makes the final database calls. The driver is compiled for use with the particular operating
system. For platform interoperability, the Type 4 driver, being a full-Java implementation, is
preferred over this driver.
However the type 2 driver provides more functionality and performance than the type 1
driver as it does not have the overhead of the additional ODBC function calls
79
79
We enable you to leverage knowledge
anytime, anywhere!
Type3 Driver (Network-protocol driver )
Calling Java Application
JDBC API
JDBC Driver Manager
Network-Protocol driver
(Type III Driver)
Different DataBase Vendors
MiddleWare
(Application Server)
The JDBC type 3 driver, also known as the network-protocol driver is a database driver
implementation which makes use of a middle-tier between the calling program and the
database. The middle-tier (application server) converts JDBC calls directly or indirectly into
the vendor-specific database protocol.
This differs from the type 4 driver in that the protocol conversion logic resides not at the
client but in the middle-tier. However, like type 4 drivers, the type 3 driver is written entirely
in Java.
The same driver can be used for multiple databases. It depends on the number of databases
the middleware has been configured to support. The type 3 driver is platform-independent as
the platform-related differences are taken care by the middleware. Also, making use of the
middleware provides additional advantages of security and firewall access.
80
80
We enable you to leverage knowledge
anytime, anywhere!
Type4 Driver (Native-protocol driver )
Calling Java Application
JDBC API
JDBC Driver Manager
Native - Protocol driver
(Type 4 Driver)
DataBase
direct calls using specific
database protocol
The JDBC type 4 driver, also known as the native-protocol driver is a database driver
implementation that converts JDBC calls directly into the vendor-specific database protocol.
The type 4 driver is written completely in Java and is hence platform independent. It
provides better performance over the type 1 and 2 drivers as it does not have the overhead
of conversion of calls into ODBC or database API calls. Unlike the type 1 and 2 drivers, it
does not need associated software to work.
As the database protocol is vendor-specific, separate drivers, usually vendor-supplied, need
to be used to connect to the database. Performance wise this is the most efficient.
81
81
We enable you to leverage knowledge
anytime, anywhere!
Database interaction
The steps involved in a database interaction are:
Loading the specific driver
Making a connection to the database
Sending SQL statements to the database
Processing the results
The steps involved in a database interaction are:
Loading the specific driver
Making a connection to the database
Sending SQL statements to the database
Processing the results
82
82
We enable you to leverage knowledge
anytime, anywhere!
JDBC - classes and interfaces
DriverManager class :
Manages all the JDBC Drivers that are loaded in
the memory
Helps in dynamic loading of Drivers
Data Source :
Offer the user considerably more capability than
the basic Connection objects that the
DriverManager provides.
It supports connection pooling and distributed
transactions
The DriverManager class provides methods to obtain a connection to a database through a
driver, register and deregister drivers, set up logging, and set login timeouts for database
access. When you request a connection it returns an object of the Connection interface. The
Connection object is then used to create SQL statements and handle ResultSets.
The additional features of DataSource objects make it a preferred means of getting a
Connection to any source of data. The source can be anything from a relational database to
a spreadsheet or a file in tabular form.
83
83
We enable you to leverage knowledge
anytime, anywhere!
JDBC - classes and interfaces [Contd..]
Three types of standard DataSource objects :
The basic DataSource that produces standard
Connection objects just like those that the
DriverManager produces
A PooledDataSource that supports connection
pooling. Pooled connections are returned to a pool for
reuse by another transaction.
A DistributedDataSource that supports distributed
transactions accessing two or more DBMS servers.
There are three types of standard DataSource objects :
The basic DataSource that produces standard Connection objects just like those
that the DriverManager produces.
A Pooled DataSource that supports connection pooling. Pooled connections are
returned to a pool for reuse by another transaction..
A Distributed DataSource that supports distributed transactions accessing two or
more DBMS servers.
84
84
We enable you to leverage knowledge
anytime, anywhere!
JDBC - classes and interfaces [Contd..]
Methods in DriverManager class -
getConnection() : to establish a connection to a
database.
Connection getConnection(String url, Properties
info)
Connection getConnection(String url)
Connection getConnection(String url, String
userID, String password)
registerDriver(java.sql.Driver)
The methods present in java.sql.DriverManager class are:
public static synchronized Connection getConnection(String url, Properties info)
throws SQLException
This method and other getConnection() methods attempts to establish a connection to the
given database URL and attempts to select an appropriate driver from the set of registered
JDBC drivers. info is a reference to a Properties container object of tag and value pairs,
typically having username and password.
public static synchronized void registerDriver(java.sql.Driver driver) throws
SQLException
This method is invoked by Drivers to register themselves with DriverManager. This is
generally used when you have a custom driver to connect to the database.
85
85
We enable you to leverage knowledge
anytime, anywhere!
JDBC - classes and interfaces [Contd..]
Connection interface - defines methods for interacting
with the database via the established connection.
A connection object represents a connection with a
database.
A connection session includes the SQL statements
that are executed and the results that are returned
over that connection.
A single application can have one or more
connections with a single database, or it can have
many connections with many different databases.
Connection interface - defines methods for interacting with the database via the
established connection.
A connection object represents a connection with a database.
A connection session includes the SQL statements that are executed and the
results that are returned over that connection.
A single application can have one or more connections with a single database, or it
can have many connections with many different databases.
To execute a SQL statement you need to create an object of the Statement by invoking the
appropriate method of the Connection interface. You should then use the method of the
Statement interface to execute the SQL query. The method may return a ResultSet object,
integer value telling number of lines modified or updated by the statement, etc.
86
86
We enable you to leverage knowledge
anytime, anywhere!
JDBC - classes and interfaces [Contd..]
The different methods of Connection interface are:
close() - closes the database connection
createStatement() - creates an SQL Statement
object
prepareStatement() - creates an SQL
PreparedStatement object. (PreparedStatement
objects are precompiled SQL statements)
prepareCall() - creates an SQL CallableStatement
object using an SQL string. (CallableStatement
objects are SQL stored procedure call statements)
The different methods of Connection interface are:
close() - closes the database connection
createStatement() - creates an SQL Statement object
prepareStatement() - creates an SQL PreparedStatement object.
(PreparedStatement objects are precompiled SQL statements)
prepareCall() - creates an SQL CallableStatement object using an SQL string.
(CallableStatement objects are SQL stored procedure call statements)
87
87
We enable you to leverage knowledge
anytime, anywhere!
Statement
A statement object is used to send SQL statements to
a database.
Three kinds :
Statement
Execute simple SQL without parameters
PreparedStatement
Used for pre-compiled SQL statements with or
without parameters
CallableStatement
Execute a call to a database stored procedure or
function
SQL is the language used to interact with the database. To retrieve or insert, update and
delete data into a database you need to execute SQL statements. Java provides three
interfaces, i.e. the Statement interface, the PreparedStatement interface and the
CallableStatement interface to achieve this.
Statement
Execute simple SQL without parameters
PreparedStatement
Used for pre-compiled SQL statements with or without parameters
CallableStatement
Execute a call to a database stored procedure or function
88
88
We enable you to leverage knowledge
anytime, anywhere!
JDBC - classes and interfaces [Contd..]
Statement interface - defines methods that are used to interact with
database via the execution of SQL statements.
The different methods are:
executeQuery(String sql) - executes an SQL statement
(SELECT) that queries a database and returns a ResultSet
object.
executeUpdate(String sql) - executes an SQL statement
(INSERT,UPDATE,or DELETE) that updates the database and
returns an int, the row count associated with the SQL statement
execute(String sql) - executes an SQL statement that is written
as String object
getResultSet() - used to retrieve the ResultSet object
Statement interface - defines methods that are used to interact with database via the
execution of SQL statements.
The different methods are:
executeQuery(String sql) - executes an SQL statement (SELECT) that queries a
database and returns a ResultSet object.
executeUpdate(String sql) - executes an SQL statement (INSERT,UPDATE,or
DELETE) that updates the database and returns an int, the row count associated
with the SQL statement
execute(String sql) - executes an SQL statement that is written as String object
getResultSet() - used to retrieve the ResultSet object
89
89
We enable you to leverage knowledge
anytime, anywhere!
JDBC - classes and interfaces [Contd..]
Example:
Connection connection = DriverManager.getConnection(jdbc:odbc:emp, , );
/* create statement */
Statement statement = connection.createStatement();
/* get all records from the Employee table */
ResultSet resultSet = statement.executeQuery("select * from Employee");
/* update the age in empcode 1 and check no of records affected by change */
String sql = update Employee set empage = 25 where empcode = 1;
int recordsAffected = stmt.executeUpdate(sql);
if(recordsAffected == 0)
System.out.println(Update failed);
/* delete employee record with empcode = 2 */
String sql = delete from employee where empcode = 2;
int recordsAffected = statement.executeUpdate(sql);
/* we have to commit the transaction once we delete the record, otherwise the record is
just marked for deletion but not physically deleted. we achieve this by using the
commit() method of the Connection interface */
connection.commit();
An example of the usage of the Statement interface and its methods is shown here using
the Employee table and emp DSN. The Employee table consists of three fields namely
empcode, empname and empage. Pause the presentation and analyze the code.
90
90
We enable you to leverage knowledge
anytime, anywhere!
JDBC - classes and interfaces [Contd..]
ResultSet Interface - maintains a pointer to a row
within the tabular results. The next() method is used to
successively step through the rows of the tabular
results.
The different methods are:
getBoolean(int) - Get the value of a column in the
current row as a Java boolean.
getByte(int) - Get the value of a column in the
current row as a Java byte.
getDouble(int) - Get the value of a column in the
current row as a Java double.
getInt(int) - Get the value of a column in the current
row as a Java int.
Database query results are retrieved as a ResultSet object.
The ResultSet maintains the position of the current row, starting with the first row of data returned.
When a database query is executed, the results of the query are returned as a table of data organized
in rows and columns. The ResultSet interface gives access to this tabular format of data. Every
method which you use to access the database would throw an SQL Exception so, you have to include
the code in a try and catch block or declare that the method throws SQLException.
The different methods are:
next() - method is used to successively step through the rows of the tabular results
getBoolean(int) - Get the value of a column in the current row as a Java boolean.
getByte(int) - Get the value of a column in the current row as a Java byte.
getDouble(int) - Get the value of a column in the current row as a Java double.
getInt(int) - Get the value of a column in the current row as a Java int.
91
91
We enable you to leverage knowledge
anytime, anywhere!
JDBC - classes and interfaces [Contd..]
The following example illustrates the use of the ResultSet interface and its
methods.
Connection connection = DriverManager.getConnection(jdbc:odbc:emp, , );
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("select * from Employee");
/* Employee table has three columns first is a code (number), second is name
(String) and
third is age (number)*/
while(resultSet.next()){
int code = rs.getInt(1);
String name= rs.getString(2);
int age = rs.getInt(3);
System.out.println(Code : + code + Name: + name + Age : + age);
}
resultSet.close();
connection.close();
The given example illustrates the use of the ResultSet interface and its methods. Pause the
presentation and analyze the code.
92
92
We enable you to leverage knowledge
anytime, anywhere!
JDBC - classes and interfaces [Contd..]
Types of ResultSet Objects
ScrollableResultSet
It supports the ability to move a result sets cursor in
either direction and there are methods for getting the
cursor position and moving the cursor to a particular
row.
Updatable ResultSets
This allows to make the updates to the values in the
ResultSet itself, and these changes are reflected in
the database.
Types of ResultSet Objects
ScrollableResultSet
It supports the ability to move a result sets cursor in either direction and
there are methods for getting the cursor position and moving the cursor to a
particular row.
Updatable ResultSets
This allows to make the updates to the values in the ResultSet itself, and
these changes are reflected in the database.
To create a Scrollable Resultset, we need to call the createStatement method with two
arguments passed, the first specify the type of the ResultSet object.
The second argument must be one of the two ResultSet constants for specifying whether a
result set is read-only or updateable.
To create an UpdatableResultSet object,we need to call the createStatement method with
the ResultSet constant CONCUR_UPDATABLE as the second argument.The Statement
object created produces an updatable ResultSet object when it executes a query.
Once you have an UpdatableResultSet object, you can insert a new row, delete an existing
row, or modify one or more column values in the Result set and these changes will be
reflected in the database.
93
93
We enable you to leverage knowledge
anytime, anywhere!
JDBC - classes and interfaces [Contd..]
Cursor control methods
next()
previous()
first()
last()
beforeFirst()
afterLast()
absolute(int rowNumber)
relative(int rowNumber)
In addition to the ResultSet.next() method, which is used to move the cursor forward, one
row at a time, scrollable ResultSets support the method previous() which moves the cursor
back one row.
The effect of the first(), last(), beforeFirst() and afterLast() are clear from the method names
itself.
The method absolute(int number) moves the cursor to the row number indicated in the
argument.
The method relative(int rowNumber) lets you specify how many rows to move from the
current row and in which direction to move. A positive number moves the cursor forward the
given number of rows, a negative number moves the cursor backward the given number of
rows.
94
94
We enable you to leverage knowledge
anytime, anywhere!
Using Statement and ResultSet
import java.sql.*;
class JDBCTest{
public static void main(String args[]) {
try{
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection connection =
DriverManager.getConnection("jdbc:oracle:thin:@
DB IPaddress:port_no:host
string",uid",password");
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("select * from Student");
while(resultSet.next()){
System.out.println(resultSet.getInt("ClassNo"));
} }
catch(Exception exception) {
System.out.println(exception); } }}
Here is a simple program that consolidates how to work with Statement and ResultSet
interfaces. Pause the presentation and analyze the code.
95
95
We enable you to leverage knowledge
anytime, anywhere!
JDBC - classes and interfaces [Contd..]
PreparedStatement interface -- helps us to work with
precompiled SQL statements
Precompiled SQL statements are faster than normal
statements
So, if a SQL statement is to be repeated, it is better to
use PreparedStatement
Some values of the statement can be represented by a ?
character which can be replaced later using setXXX
method
PreparedStatement interface -- helps us to work with precompiled SQL statements
Precompiled SQL statements are faster than normal statements
So, if a SQL statement is to be repeated, it is better to use PreparedStatement
Some values of the statement can be represented by a ? character which can be replaced
later using setXXX method.
96
96
We enable you to leverage knowledge
anytime, anywhere!
Using PreparedStatement
import java.sql.*;
class PreparedStatementTest{
public static void main(String args[]) throws Exception{
try{
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection connection = DriverManager.getConnection(url", UID",
password");
PreparedStatement preparedStatement =
connection.prepareStatement("select * from Emp where
ename=?");
preparedStatement.setString(1,str);
ResultSet resultSet = preparedStatement.executeQuery();
while(resultSet.next()){
System.out.println(resultSet.getString("ename"));
} }
catch(Exception exception){
System.out.println(exception); }
} }
Here is a simple program that consolidates how to work with PreparedStatement and
ResultSet interfaces. Pause the presentation and analyze the code.
97
97
We enable you to leverage knowledge
anytime, anywhere!
JDBC - classes and interfaces [Contd..]
CallableStatement interface -- helps us to call stored
procedures and functions
CallableStatement callableStatement =
connection.prepareCall(execute proc ?);
callableStatement.setInt(1,50);
callableStatement.execute();
CallableStatement interface -- helps us to call stored procedures and functions.
98
98
We enable you to leverage knowledge
anytime, anywhere!
JDBC - classes and interfaces [Contd..]
The out parameters are to be registered
callableStatement.registerOutParameter(int
parameterIndex, int SQLType);
To get the value stored in the out parameter--
callableStatement.getXXX(int parameterIndex);
Before executing the procedures we have to register the out parameters of the procedure
using registerOutParameter() method. After execution the result stored in out parameters
can be retrieved using getXXX() methods.
99
99
We enable you to leverage knowledge
anytime, anywhere!
Using CallableStatement
Example - Calling a stored procedure named GetSalary.
The procedure queries on the Employee table and
returns the salary of an employee. It has one input
parameter that takes the EmpCode and an out
parameter that returns the salary
CallableStatement callableStatement =
connection.prepareCall("begin GetSalary(?,?); end;");
callableStatement.setInt(1,29418);
// OUT parameters must be registered.
callableStatement.registerOutParameter(2,Types.DOUBLE);
callableStatement.execute();
System.out.println("Salary : " +
callableStatement.getDouble(2));
Here is a piece of code that lets you know how to work with CallableStatement interface.
Pause the presentation and analyze the code.
100
100
We enable you to leverage knowledge
anytime, anywhere!
JDBC - classes and interfaces [Contd..]
ResultSetMetaData Interface - holds information on the
types and properties of the columns in a ResultSet.
The following code creates a ResultSet obect and
ResultSetMetaData object.
ResultSet rs = stmt.executeQuery("SELECT * FROM
TABLE2"); ResultSetMetaData rsmd = rs.getMetaData();
The different methods are:
getColumnName(int column)
getColumnType(int column)
ResultSetMetaData Interface - holds information on the types and properties of the
columns in a ResultSet.
The statements
ResultSet rs = stmt.executeQuery("SELECT * FROM TABLE2");
ResultSetMetaData rsmd = rs.getMetaData();
creates a ResultSet object and ResultSetMetaData object.
Then we can apply different methods on ResultSetMetaData object to get the required
information. For example,
getColumnName(int column) returns the designated column's name.
getColumnType(int column) returns the designated column's SQL type
getColumnLabel(int column) returns the designated column's suggested title for use
in printouts and displays.
101
101
We enable you to leverage knowledge
anytime, anywhere!
Transaction Management using JDBC
Transactions
The capability to group SQL statements for execution
as a single entity is provided through SQLs
transaction mechanism.
A transaction consists of one or more statements that
are executed, completed and either committed or
rolled back as a group.
The commit means that the change is made
permanently in the database, and the term rollback
means that no change is made in the database.
The capability to group SQL statements for execution as a single entity is provided through
SQLs transaction mechanism.
A transaction consists of one or more statements that are executed, completed and either
committed or rolled back as a group.
The commit means that the change is made permanently in the database, and the term
rollback means that no change is made in the database
When the method commit or rollback is called, the current transaction ends, and another one
begins.
A new JDBC connection is in auto-commit mode by default, meaning that when a statement
is completed, the method commit is called on that statement automatically.
The commit occurs when the statement completes or the next execute occurs, whichever
comes first.
102
102
We enable you to leverage knowledge
anytime, anywhere!
Transaction Management using JDBC [Contd..]
By default, auto commit mode of the connection
reference is set to true
A transaction can be done as follows using methods of
the Connection interface
... ... ... ...
connection. connection. connection. connection.setAutoCommit setAutoCommit setAutoCommit setAutoCommit(false (false (false (false); //by default it is true ); //by default it is true ); //by default it is true ); //by default it is true
try{ try{ try{ try{
//Statements //Statements //Statements //Statements
connection. connection. connection. connection.commit commit commit commit(); (); (); ();
} }} }
catch(Exception catch(Exception catch(Exception catch(Exception exception){ exception){ exception){ exception){
connection. connection. connection. connection.rollback rollback rollback rollback(); (); (); ();
} }} }
If auto-commit mode has been disabled, a transaction will not terminate until either the
commit method or the rollback method is called explicitly, so the transaction will include all
the statements that have executed since the last invocation of the commit or rollback
method.
103
103
We enable you to leverage knowledge
anytime, anywhere!
Transaction Management using JDBC [Contd..]
Transaction Isolation Levels
This allows to manage simple conflicts arising from
events such as a failure to complete a linked series of
SQL commands.
The current level of isolation can be queried using the
method :
public int getTransactionIsolation()
The control over the isolation level of a connection is
provided by this method:
setTransactionIsolation(
TRANSACTION_ISOLATION_LEVEL_XXX).
Consider the case of a multiuser application, where one transaction has initiated a transfer
between two accounts but has not yet committed it, when a second transaction attempts to
access one of the account in question.
If the first transaction is rolled back, the value the second transaction reads will be invalid.
JDBC defines levels of transaction isolation that provides different levels of conflict
management. The lowest level specifies that transaction are not supported at all, and the
highest specifies that while one transaction is operating on a database, no other
transactions may make any changes to the data that transaction reads.
setTransactionIsolation(int level) of Connection interface sets the specified isolation level.
Level can take one of the five values,
Connection.TRANSACTION_NONE,
Connection.TRANSACTION_READ_UNCOMMITTED
Connection.TRANSACTION_READ_COMMITTED
Connection.TRANSACTION_REPEATABLE_READ
Connection.TRANSACTION_SERIALIZABLE
104
104
We enable you to leverage knowledge
anytime, anywhere!
Transaction Savepoints
During a transaction, a named savepoint may be inserted
between operations to act as a marker, so that the
transaction may be rolled back to that marker, leaving all
of the operations before the marker in effect.
Transaction savepoints are JDBC enhancements that
offer finer control over transaction commit and rollback.
con.setAutocommit(false);
Statement stmt = con.createStatement();
Stmt.executeUpdate(update1);
Savepoint savepoint1 = con.setSavepoint(SavePoint1);
stmt.executeUpdate(update2);
stmt.executeUpdate(update3);
con.rollback(savePoint1);
During a transaction, a named savepoint may be inserted between operations to act as a
marker, so that the transaction may be rolled back to that marker, leaving all of the
operations before the marker in effect.
The above code shows a Savepoint being set after the first update,and the transaction being
rolled back to that Savepoint,removing two subsequent updates.
When a SQL statements make changes to a database, the commit method makes those
changes permanent, and it releases any locks the transaction holds.
The rollback method, on the other hand, simply discards those changes.
105
ER/CORP/CRS/LA46/003
Advanced Java Programming
Module 5 - Java Remote Method Invocation
We shall now move on to the module on RMI Remote Method Invocation.
106
106
We enable you to leverage knowledge
anytime, anywhere!
Lesson Outcomes
After completion of the module you can able to
understand
The need for RMI
How to Access Remote Objects and
RMI APIs
After completion of the module you can able to understand
The need for RMI
How to Access Remote Objects and
RMI APIs
107
107
We enable you to leverage knowledge
anytime, anywhere!
Remote Method Invocation
RMI feature allows us to invoke a method on an
object which resides in another JVM.
Examples of Use
Database access
Computations
Any custom protocol
Not for standard protocols (HTTP, FTP, etc.)
When the processing is distributed across the multiple networked computers then it is called
as distributed application.
In Java RMI feature allows us to invoke a method on an object which resides in another
JVM.
108
108
We enable you to leverage knowledge
anytime, anywhere!
Java Virtual Machine
Remote Objects
Java Virtual Machine
Client/local
Object
Remote
Object
TCP
The RMI (Java Remote Method Invocation) is a mechanism that enables an object on one
JVM to invoke methods on an object in another JVM.
A distributed application is an application whose processing is distributed across multiple
networked computers. Distributed architecture is based on the three-tier application
development, where the front end, namely the user interface is on one network and the
business rules and the database on a different network.
The models for developing distributed applications that exist in the industry today are
DCOM, RMI and CORBA.
All these three methods of developing distributed applications allow objects on one host to
invoke methods of objects on other computers or even computers on a different network.
DCOM and CORBA are standards of developing distributed applications and so can be
developed in any language, whereas RMI is specific to developing distributed applications in
Java.
The distributed object model used by Java allows objects in one JVM to invoke methods of
objects in a separate JVM and this is known as Remote Method Invocation (RMI). These
separate JVMs may execute as a different process in the same computer or on remote
computers.
109
109
We enable you to leverage knowledge
anytime, anywhere!
RMI Layers
Client Object
Server Object 'S'
Object 'S' Stub Object 'S' Skeleton
Remote Reference Layer
Transport Layer
Remote Reference Layer
Transport Layer
TCP
Java Virtual Machine Java Virtual Machine
RMI Layers
Remote Reference Layer
A client invoking a method on a remote server object actually uses a stub or proxy as a conduit to the remote object. A client-held
reference to a remote object is a reference to a local stub, which is an implementation of the remote interfaces of the object and which
forwards invocation requests to it via the remote reference layer. Stubs are generated using the rmic compiler.The remote reference
layer in the RMI system separates out the specific remote reference behavior from the client stub. Any call initiated by the stub is done
directly through the reference layer, enabling appropriate reference semantics to be carried out. For example, if a remote reference had
the behavior of connection retry, it would attempt to establish the retry connection on behalf of the stub. When the connection initiation
succeeded, the reference layer would forward the marshaling of arguments and send the RMI call to the underlying transport for that
reference type. The remote reference layer transmits data to the transport layer via the abstraction of a stream-oriented connection. The
transport takes care of the implementation details of connections. Although connections present a streams-based interface, a
connectionless transport can be implemented beneath the abstraction.
Transport Layer
The transport layer is responsible for connection setup, connection management, and keeping track of and dispatching to remote
objects (the targets of remote calls) residing in the transport's address space. In order to dispatch to a remote object, the transport
forwards the remote call up to the remote reference layer. The remote reference layer handles any server-side behavior that needs to
occur before handing off the request to the server-side skeleton. The skeleton for a remote object makes an up call to the remote object
implementation which carries out the actual method call.
The return value of a call is sent back through the skeleton, remote reference layer, and transport on the server side, and then up
through the transport, remote reference layer, and stub on the client side.
In general, the transport layer of the RMI system is responsible for:
Setting up connections to remote address spaces.
Managing connections.
Monitoring connection "liveness."
Listening for incoming calls.
Maintaining a table of remote objects that reside in the address space.
Setting up a connection for an incoming call.
Locating the dispatcher for the target of the remote call and passing the connection to this dispatcher.
110
110
We enable you to leverage knowledge
anytime, anywhere!
General RMI architecture
The server must first bind its name to the registry
The client lookup the server name in the registry to
establish remote references.
The Stub serializes the parameters to skeleton, the
skeleton invokes the remote method and serializes the
result back to the stub.
General RMI architecture
The server must first bind its name to the registry
The client lookup the server name in the registry to establish remote references.
The Stub serializes the parameters to skeleton, the skeleton invokes the remote method
and serializes the result back to the stub.
111
111
We enable you to leverage knowledge
anytime, anywhere!
General RMI architecture [Contd..]
RMI Server
Skeleton
RMI Registry
Stub
RMI Client
Bind
Lookup
return call
Remote Machine
Local Machine
Here is the RMI Architecture.
Let us discuss about RMI Registry.
The registry is a simple server that enables an application to look up objects that are being
exported for remote method invocation.
The registry simply keeps track of the addresses of remote objects that are being exported
by their applications
All objects are assigned unique names that are used to identify them.
A server registers one of its objects with a registry by calling a bind() or rebind() method on
a registry instance, passing it a String that uniquely identifies the object and a reference to
an instance of the object that is being exported.
Since all objects must have a unique name, a bind() call to a registry that contains a name
String that is already registered will result in an exception being thrown.
Alternatively, rebind() replaces an old object with a given name with a new object.
112
112
We enable you to leverage knowledge
anytime, anywhere!
Stub and skeleton
A client invokes a remote method, the call is first
forwarded to stub.
The stub is responsible for sending the remote call over
to the server-side skeleton
The stub opening a socket to the remote server,
marshaling the object parameters and forwarding the
data stream to the skeleton.
A skeleton contains a method that receives the remote
calls, unmarshals the parameters, and invokes the
actual remote object implementation.
S
t
u
b
RMI Client
RMI
Server
s
k
e
l
e
t
o
n
return
call
STUB
Is the client side proxy for the remote object.
It is the applications interface to the remote object
Responsible for initiating a call
Marshaling arguments to a marshal stream (marshal stream is used to transport parameters,
exceptions and errors needed for method dispatch and returning the results)
It pretends to be remote object
It informs the remote reference layer that the call should be invoked.
Upon return:
Unmarshaling the return value or exception from a marshal stream.
Informing the remote reference layer that the call is complete.
SKELETON
lives on server
receives requests from stub
talks to true remote object
delivers response to stub
113
113
We enable you to leverage knowledge
anytime, anywhere!
Steps to develop a RMI system
Define the remote interface
Develop the remote object (Server object) by
implementing the remote interface.
Develop the client program.
Compile the Java source files.
Generate the client stubs and server skeletons.
Start the RMI registry.
Start the remote server objects.
Run the client
To develop a RMI system do the following steps.
1. Define the remote interface
2. Develop the remote object (Server object) by implementing the remote interface.
3. Develop the client program.
4. Compile the Java source files.
5. Generate the client stubs and server skeletons.
6. Start the RMI registry.
7. Start the remote server objects.
8. Run the client
Let us see one by one in detail.
114
114
We enable you to leverage knowledge
anytime, anywhere!
Step1: Defining remote interface
To create a RMI application, the first step is
defining of a remote interface between the client
and server objects.
/* /* /* /* InterfaceRMI.java InterfaceRMI.java InterfaceRMI.java InterfaceRMI.java */ */ */ */
import import import import java.rmi java.rmi java.rmi java.rmi.*; .*; .*; .*;
public interface public interface public interface public interface InterfaceRMI InterfaceRMI InterfaceRMI InterfaceRMI extends Remote{ extends Remote{ extends Remote{ extends Remote{
int int int int cube(int cube(int cube(int cube(int x) throws x) throws x) throws x) throws RemoteException RemoteException RemoteException RemoteException; ;; ;
} }} }
Step1: Defining remote interface
To create a RMI application, the first step is defining of a remote interface between the
client and server objects.
The Remote interface must have the following properties:
The interface must be public.
The interface must extend the interface java.rmi.Remote.
Every methods declared in the interface must throw java.rmi.RemoteException.
Other exceptions may also be thrown.
Here in the example InterfaceRMI is the remote interface which contains the remote method
cube declared.
115
115
We enable you to leverage knowledge
anytime, anywhere!
Step2: Develop the server object
The server is a simple unicast remote server.
Create server by extending
java.rmi.server.UnicastRemoteObject
/* /* /* /*ServerRMI.java ServerRMI.java ServerRMI.java ServerRMI.java*/ */ */ */
import import import import java.rmi java.rmi java.rmi java.rmi.*; .*; .*; .*;
import import import import java.rmi.server java.rmi.server java.rmi.server java.rmi.server.*; .*; .*; .*;
public class public class public class public class ServerRMI ServerRMI ServerRMI ServerRMI extends extends extends extends UnicastRemoteObject UnicastRemoteObject UnicastRemoteObject UnicastRemoteObject implements implements implements implements InterfaceRMI InterfaceRMI InterfaceRMI InterfaceRMI { {{ {
public public public public ServerRMI ServerRMI ServerRMI ServerRMI() throws () throws () throws () throws RemoteException RemoteException RemoteException RemoteException { {{ {
super(); super(); super(); super();
} }} }
... ... ... ...
Step2: Develop the server object
The server is a simple unicast remote server.
Create server by extending java.rmi.server.UnicastRemoteObject
UnicastRemoteObject.exportObject(new ServerRMi,port);
this can be used in case the server already extends some other class and
we want that class to be the server class.
The java.rmi.server Package
This package implements several interfaces and classes that support both client and server
aspects of RMI like a class implementation of Remote interface, client stub, server skeleton
and so on.
116
116
We enable you to leverage knowledge
anytime, anywhere!
Step2 contd
The server class needs to implement the remote
methods
public int public int public int public int cube(int cube(int cube(int cube(int x) throws x) throws x) throws x) throws RemoteException RemoteException RemoteException RemoteException{ {{ {
return x*x*x; return x*x*x; return x*x*x; return x*x*x;
} }} }
The server class needs to implement the remote methods defined in the remote interface.
InterfaceRMI has the remote method cube. So ServerRMI class must provide
implementation for the remote method cube.
117
117
We enable you to leverage knowledge
anytime, anywhere!
Step2 contd
The server must bind its name to the registry, the client
will look up the server name.
Use java.rmi.Naming class to bind the server name
to registry. In this example the name by which it is
registered is MyServer.
... ... ... ...
public static void main (String a[]){ public static void main (String a[]){ public static void main (String a[]){ public static void main (String a[]){
try { try { try { try {
ServerRMI ServerRMI ServerRMI ServerRMI remoteServer remoteServer remoteServer remoteServer = new = new = new = new ServerRMI ServerRMI ServerRMI ServerRMI(); (); (); ();
Naming.rebind("MyServer Naming.rebind("MyServer Naming.rebind("MyServer Naming.rebind("MyServer", ", ", ", remoteServer remoteServer remoteServer remoteServer ); ); ); );
System.out.println("System System.out.println("System System.out.println("System System.out.println("System is ready"); is ready"); is ready"); is ready");
} }} }catch(Exception catch(Exception catch(Exception catch(Exception e){ e){ e){ e){
System.out.println(e System.out.println(e System.out.println(e System.out.println(e); ); ); );
} }} }
} }} }
} }} }
The server must bind its name to the registry.
Use java.rmi.Naming class to bind the server name to registry. In this example the name
by which it is registered is MyServer.
118
118
We enable you to leverage knowledge
anytime, anywhere!
Step2 contd
/* /* /* /*ServerRMI.java ServerRMI.java ServerRMI.java ServerRMI.java*/ */ */ */
import import import import java.rmi java.rmi java.rmi java.rmi.*; .*; .*; .*;
import import import import java.rmi.server java.rmi.server java.rmi.server java.rmi.server.*; .*; .*; .*;
public class public class public class public class ServerRMI ServerRMI ServerRMI ServerRMI extends extends extends extends UnicastRemoteObject UnicastRemoteObject UnicastRemoteObject UnicastRemoteObject implements implements implements implements InterfaceRMI InterfaceRMI InterfaceRMI InterfaceRMI { {{ {
public public public public ServerRMI ServerRMI ServerRMI ServerRMI() throws () throws () throws () throws RemoteException RemoteException RemoteException RemoteException { {{ {
super(); super(); super(); super();
} }} }
public public public public int int int int cube(int cube(int cube(int cube(int x) throws x) throws x) throws x) throws RemoteException RemoteException RemoteException RemoteException{ {{ {
return x*x*x; return x*x*x; return x*x*x; return x*x*x;
} }} }
public static void main (String a[]){ public static void main (String a[]){ public static void main (String a[]){ public static void main (String a[]){
try { try { try { try {
ServerRMI ServerRMI ServerRMI ServerRMI remoteServer remoteServer remoteServer remoteServer = new = new = new = new ServerRMI ServerRMI ServerRMI ServerRMI(); (); (); ();
Naming.rebind("MyServer Naming.rebind("MyServer Naming.rebind("MyServer Naming.rebind("MyServer", ", ", ", remoteServer remoteServer remoteServer remoteServer ); ); ); );
System.out.println("System System.out.println("System System.out.println("System System.out.println("System is ready"); is ready"); is ready"); is ready");
} }} }catch(Exception catch(Exception catch(Exception catch(Exception e){ e){ e){ e){
System.out.println(e System.out.println(e System.out.println(e System.out.println(e); ); ); );
} }} }
} }} }
} }} }
Here is the complete listing of server code.
119
119
We enable you to leverage knowledge
anytime, anywhere!
Step 3: Develop the client program
In order for the client object to invoke methods on the
server, it must first look up the name of server object in
the registry.
Use the java.rmi.Naming class to lookup the server
name.
The server name is specified as URL in the from(
rmi://host:port/name )
Default RMI port is 1099.
Step 3: Develop the client program
In order for the client object to invoke methods on the server, it must first look up the name
of server object in the registry.
Use the java.rmi.Naming class to lookup the server name.
The server name is specified as URL in the from( rmi://host:port/name )
Default RMI port is 1099.
120
120
We enable you to leverage knowledge
anytime, anywhere!
Step 3 contd
The name specified in the URL must exactly match the
name with which the server object has bound to the
registry. In this example, the name is "MyServer"
The remote method invocation is programmed using the
remote interface reference_name.function_name
The name specified in the URL must exactly match the name with which the server object
has bound to the registry. In this example, the name is "MyServer"
The remote method invocation is programmed using the remote interface
reference_name.function_name
121
121
We enable you to leverage knowledge
anytime, anywhere!
Step 3 contd
/* /* /* /*ClientRMI.java ClientRMI.java ClientRMI.java ClientRMI.java*/ */ */ */
import import import import java.rmi java.rmi java.rmi java.rmi.*; .*; .*; .*;
public class public class public class public class ClientRMI ClientRMI ClientRMI ClientRMI { {{ {
public static void public static void public static void public static void main(String main(String main(String main(String a[]) { a[]) { a[]) { a[]) {
try{ try{ try{ try{
InterfaceRMI InterfaceRMI InterfaceRMI InterfaceRMI obj obj obj obj=( =( =( =(InterfaceRMI InterfaceRMI InterfaceRMI InterfaceRMI) )) )
Naming.lookup("//localhost/MyServer Naming.lookup("//localhost/MyServer Naming.lookup("//localhost/MyServer Naming.lookup("//localhost/MyServer"); "); "); ");
int no=obj.cube(4); int no=obj.cube(4); int no=obj.cube(4); int no=obj.cube(4);
System.out.println("The System.out.println("The System.out.println("The System.out.println("The value is : " + no); value is : " + no); value is : " + no); value is : " + no);
} } } }
catch(Exception catch(Exception catch(Exception catch(Exception e){ e){ e){ e){
System.out.println(e System.out.println(e System.out.println(e System.out.println(e); ); ); );
} }} }
} }} }
} }} }
Here is the client code. Pause the presentation and analyze the code.
122
122
We enable you to leverage knowledge
anytime, anywhere!
Step 4: compiling all the source files
Compile all the 3 source codes using javac *.java.
Step 4: Compile all the source files.
123
123
We enable you to leverage knowledge
anytime, anywhere!
Step 5: generating stubs and skeleton
Now the stub and skeleton need to be generated using
rmic (rmi compiler)
>rmic ServerRMI
Step 5: generating stubs and skeleton
Generate the stub and skeleton using rmi compiler - rmic
124
124
We enable you to leverage knowledge
anytime, anywhere!
Step 6: starting the RMI registry
The rmiregistry must be started using start rmiregistry
This step needs to be done before the server program
starts as the server object has to be registered
Step 6: starting the RMI registry
The command start rmiregistry starts the RMI registry. See the output of the command.
125
125
We enable you to leverage knowledge
anytime, anywhere!
Step 7: start the server program
Once the Registry is started, the server can be started
and will be able to store itself in the Registry
Start the server program
>java ServerRMI
Step 7: start the server program
Once the Registry is started, the server can be started and will be able to store itself in the
Registry
Start the server by executing the server program.
126
126
We enable you to leverage knowledge
anytime, anywhere!
Step 8: start the client program
The client program can now access the server program.
Start the client program.
>java ClientRMI
For the client it seems as if the function call is on the
same machine
Step 8: start the client program by running the client program.
The client program can now access the server program.
You can see the result in the client window.
For the client it seems as if the function call is on the same machine
127
ER/CORP/CRS/LA46/003
Advance Java Programming
Module 6 - Java Beans
We shall now move on to the module on Java Beans.
128
128
We enable you to leverage knowledge
anytime, anywhere!
Lesson Outcomes
Reflection API
Introducing Java Beans
Simple Java Bean
Why Java Bean
Java Beans in User Interface
Naming conventions
After completion of the module you will be able to understand about
Reflection APIs
What are Java Beans
Why Java Beans are used
How to write Java Beans
Java Beans role in user interface
and the Naming Convention followed in Java Beans.
129
129
We enable you to leverage knowledge
anytime, anywhere!
The Reflection API
Reflection is the ability of software to analyze itself
The java.lang.reflect package provides reflection
capability to a Java program
The getClass() method of the class Object returns a
Class object
The getContructors(), getFields() and getMethods() are
used to analyze the
class object
Reflection is an important capability, needed when using components called Java Beans. It
allows you to analyze a software component and describe its capabilities dynamically, at run
time rather than at compile time.
For example, by using reflection, you can determine what methods, constructors, and fields
a class supports.
The java.lang.reflect package provides reflection capability to a Java program.
For each class the Java Run Time Environment (JRE) maintains an immutable Class object.
This object contains all the details such as constructors, methods, and fields in the class,
super class of the class if it is there and the interfaces if implemented by the class.
The getClass() method of the classs object; for example we are having a class named X
and its object x1. Then x1.getClass() method returns a Class object of X, which contains all
the details of X.
The methods getContructors(), getFields() and getMethods() are used to analyze the Class
object.
130
130
We enable you to leverage knowledge
anytime, anywhere!
Class Objects
A Class object can be retrieved in several ways.
If an instance of the class is available, Object.getClass is
invoked.
The following line of code gets the Class object for an
object named mystery: Class c = mystery.getClass();
If we need to retrieve the Class object for the superclass
that another Class object reflects, invoke the
getSuperclass method.
If the name of the class is known at compile time, its
Class object can be retrieved by appending .class to its
name.
If the class name is unknown at compile time, but
available at runtime, you can use the forName method
A Class Object can be retrieved in several ways.
1. As discussed recently, if the instance of a class is available then object.getClass()
returns the Class object. For Example: we are having an object named mystery then
mystery.getClass() returns the Class object. This way helps you to analyze an object with
out knowing the class name.
2. If we want to know the details of a superclass and the name of the superclass is not
known and no object is instantiated for it, then we can access the details of superclass
through the subclass object. Let X be the superclass and Y be the subclass. Let y1 be
the object of Y. Class c=y1.getClass() will return the Class object of Y. Then Class
s=c.getSuperclass() will return the Class object for the super class through which we get
the details of superclass.
3. If the name of the class is known at the compile time, then its Class object can be
retrieved by the syntax, Class c=ClassName.class; For Example Let the Class name be
X. Then the class object for X can be retrieved by Class c=X.class; here c is the Class
object for X.
4. If the name of the class is not known at compile time and known only at run time then
forName method of Class can be used to get the Class object. For example if the String
str contains the fully qualified class name then Class c = Class.forName(str) will give you
the Class object.
131
131
We enable you to leverage knowledge
anytime, anywhere!
Class Constructors(1/2)
The information about a class's constructors could be
retrieved by invoking the getConstructors method, which
returns an array of Constructor objects
The information about a class's constructors can be retrieved by invoking the
getConstructors() method on the Class object, which returns an array of Constructor objects.
Constructor Class has set of methods with which you determine the modifiers, parameter
types etc of the constructor.
132
132
We enable you to leverage knowledge
anytime, anywhere!
Class Constructors ( 2/2)
import java.lang.reflect.*;
import java.awt.*;
class SampleConstructor
{ public static void main(String[] args)
{ Rectangle r = new Rectangle(); showConstructors(r); }
static void showConstructors(Object o)
{ Class c = o.getClass();
Constructor[] theConstructors = c.getConstructors();
for (int i = 0; i < theConstructors.length; i++)
{ System.out.print("( ");
Class[] parameterTypes =
theConstructors[i].getParameterTypes();
for (int k = 0; k < parameterTypes.length; k ++)
{ String parameterString =
parameterTypes[k].getName();
System.out.print(parameterString + " "); }
System.out.println(")");
} }
}
Output:
( )
( java.awt.Rectangle )
( int int int int )
( int int )
( java.awt.Point
java.awt.Dimension )
( java.awt.Point )
( java.awt.Dimension )
Here is a sample program.
The above program prints the parameter types of each constructor in the Rectangle class.
The program performs the following steps:
1. It retrieves an array of Constructor objects from the Class object by calling getConstructors() method.
2. For every element in the Constructor array, it creates an array of Class objects by invoking
getParameterTypes() method. The Class objects in the array represent the parameters of the
constructor.
The program calls getName() method to fetch the class name of every parameter in the Class array
created in the preceding step.
When you try the program you can see the output as shown here.
133
133
We enable you to leverage knowledge
anytime, anywhere!
Identifying Class Fields (1/2)
A class's fields can be identified by invoking the getFields
method on a Class object.
The getFields method returns an array of Field objects
containing one object per accessible public field.
A public field is accessible if it is a member of either:
this class
a superclass of this class
an interface implemented by this class
an interface extended from an interface implemented
by this class
A class's fields can be identified by invoking the getFields() method on a Class object.
The getFields() method returns an array of Field objects containing one object per
accessible public field.
A public field is accessible if it is a member of either:
this class
a superclass of this class
an interface implemented by this class
an interface extended from an interface implemented by this class
134
134
We enable you to leverage knowledge
anytime, anywhere!
Identifying Class Fields (2/2)
import java.lang.reflect.*;
import java.awt.*;
class SampleField
{ public static void main(String[] args)
{ GridBagConstraints g = new
GridBagConstraints();
printFieldNames(g); }
static void printFieldNames(Object o)
{ Class c = o.getClass();
Field[] publicFields = c.getFields();
for (int i = 0; i < publicFields.length; i++)
{ String fieldName = publicFields[i].getName();
Class typeClass = publicFields[i].getType();
String fieldType = typeClass.getName();
System.out.println("Name: " + fieldName + ", Type: " +
fieldType);
} } }
Output:
Name: RELATIVE, Type: int
Name: REMAINDER, Type: int
Name: NONE, Type: int
Name: BOTH, Type: int
Name: HORIZONTAL, Type:
int
Name: VERTICAL, Type: int
Name: CENTER, Type: int
Name: NORTH, Type: int
Name: NORTHEAST, Type: int
Name: EAST, Type: int
Name: SOUTHEAST, Type: int
Name: SOUTH, Type: int
.
The above program prints the names and types of fields belonging to the
GridBagConstraints class.
Note that the program first retrieves the Field objects of the class by calling getFields()
method, and then invokes the getName and getType methods on each of these Field objects
to find its details.
When you try the program you can see the output as shown here.
135
135
We enable you to leverage knowledge
anytime, anywhere!
What is a Java Bean?
Component
An artifact that is one of the individual parts of which makes a
composite entity
Usually a component is a part that can be separated from or
attached to a system or module in a system
A Java bean is a reusable software component
Java Beans is the de-facto component model in Java world
Java Bean is NOT AN Enterprise Java Bean (EJB)
EJB is covered in Introduction to J2EE
Various Frameworks and Tools can use Java Bean
components to build something bigger
Example 1: An address component holds address of a person in
a program
Example 2: A text box is a reusable component of a screen
Java Beans:
A Java Bean is a reusable software component that can be visually manipulated in builder
tools. The JavaBeans API makes it possible to write component software in the Java
programming language.
A Java Bean bears a strong resemblance to a well-written Java application. But since it is a
component, a Bean's scope is usually smaller than that of an entire application, making it
easier to develop.
136
136
We enable you to leverage knowledge
anytime, anywhere!
What is a Java Bean? (Continued)
Java Beans API provides a framework for defining software
components that are
Reusable: Component which is capable of being used again and
again
Embeddable: Component which is expected to function without
human intervention.
Modular: A solution made of several discrete pieces, so that any
piece can be replaced without rebuilding the whole solution
Allows creation of reusable components
Library of reusable components can be built
Third Party library of components can be used to build an
application
Frameworks and Builder tools which use Java Beans components
use Java Reflection API to handle components
Java Beans API provides a framework for defining software components that are reusable,
Embeddable and modular.
The main purposes of Java Beans are closely related to the main advantages of Java
technology: The advantages includes
Platform independence
Mobility in a networked environment.
Expose accessor methods (e.g. getValue() and setValue()) to allow retrieval and changing
of attribute values by external sources;
Allow for easy mixing and matching via GUI development tools;
Generate or respond to appropriate events;
Save their state using the Java Serialization mechanism.
Compact and Easy
Leverages the Strengths of the Java Platform
Flexible Build-Time Component Editors
Frameworks and Builder tools which use Java Beans components use Java Reflection API
to handle components
137
137
We enable you to leverage knowledge
anytime, anywhere!
Simple Java Bean
Employee Class
Has all data members
private
Does not have a
constructor
A pair of public
Get/Set methods for
all or most member
variables
Names of Get/Set
methods should match
the variable names
Results in an
Employee Bean
Has properties
employeeNumber
employeeName
class Employee {
private int employeeNumber;
private String employeeName;
...
public void setEmployeeNumber
(int employeeNumber) {
this.employeeNumber=
employeeNumber;
}
public int getEmployeeNumber() {
return employeeNumber;
}
public void setEmployeeName
(String employeeName) {
this.employeeName=
employeeName;
}
public String getEmployeeName() {
return employeeName;
}
...
}
Here is an example for Java Bean. The Employee class which
Has all data members private
Does not have a constructor
Having pair of public Get/Set methods for all or most member variables
Results in an Employee Bean. This bean has two properties employeeNumber and
employeeName.
Note the convention in writing the getter and setter methods of a property. The getter
method will start with get followed by the name of the property with the initial letter in caps.
Same holds with setter method.
138
138
We enable you to leverage knowledge
anytime, anywhere!
Why Java Beans?
Many real life situations require components to work with various
frameworks and libraries
Data is in text files, XML files or other textual forms have to be
mapped programmatically in many applications
Names in text form can be mapped to variable names of a class
Reflection API in Java is used to achieve this
Example:
This is one of the reasons why Java Beans is used extensively in
both UI frameworks and Server side code
Use of Java beans is more in Server side code than the GUI code
<Employee>
<employeeNumber>29853</employeeNumber>
<employeeName>Tom</employeeName>
...
</Employee>
Many real life situations require components to work with various frameworks and libraries
Data is in text files, XML files or other textual forms have to be mapped programmatically in
many applications i.e.
Names in text form can be mapped to variable names of a class
Reflection API in Java is used to achieve this
This is one of the reasons why Java Beans is used extensively in both UI frameworks and
Server side code
Use of Java beans is more in Server side code than the GUI code
139
139
We enable you to leverage knowledge
anytime, anywhere!
Properties
Properties are Discrete attributes of a Bean that are
referenced by name
Example: EmployeeNumber is a property of
EmployeeBean
Value of a property can be read programmatically by
using a name
Properties:
Properties are attributes of a Bean that are referenced by name. These properties are
usually read and written by calling methods on the Bean specifically created for that
purpose.
140
140
We enable you to leverage knowledge
anytime, anywhere!
Where do we use Java Beans?
Data handling and data intensive applications for
mapping textual data to variables
Server side applications which use component based
design
Web technologies and related frameworks like JSP,
Struts etc
JSP Tag beans (covered in Introduction to J2EE
course)
Struts is a framework for presentation layer of Java
based web applications
GUI applications based on Java Beans components
Rarely used because of limited scope of Java in GUI
applications
Where do we use Java Beans?
Data handling and data intensive applications for mapping textual data to variables uses
Java Beans.
Server side applications which use component based design uses Java Beans.
Web technologies and related frameworks like JSP, Struts etc uses Java Beans. For
example:
JSP uses Java Beans so that the business logic can be moved to Java Beans and
the JSP page can handle only the presentation logic and use these Java Beans by
writing appropriate tags.
GUI applications based on Java Beans components uses Java Beans.
141
141
We enable you to leverage knowledge
anytime, anywhere!
Java Beans in User Interface
BDK (Bean Development Kit) was a specification
from Sun for creating and using reusable UI based
Java Beans
Difference in UI Java Beans compared to Simple
Java Beans
Methods to draw on screen are provided
Methods to persist data and settings
Persistence: storing data of an object in a non-volatile
manner and retrieving it when required
Event Handling methods to respond to user action on UI
components
Customization of components features which are visible
graphically
Application Builder or similar GUI frameworks can understand
and use these components to build GUI Screens
BDK (Bean Development Kit) was a specification from Sun for creating and using
reusable UI based Java Beans
UI Java Beans differs from Simple Java Beans in the
Methods to draw on screen
Methods to persist data and settings
Event Handling methods to respond to user action on UI components
Customization of components features which are visible graphically
Application Builder or similar GUI frameworks can understand and use these components to
build GUI Screens
142
142
We enable you to leverage knowledge
anytime, anywhere!
Java Beans in User Interface (Continued)
Application Builder tool and other GUI Frameworks
for using Java Beans
Use Reflection API and display all the properties and events
offered by a Java Bean in a toolbar in the development
environment
Developer can manipulate properties and write event handler
code in development environment
Properties can also be manipulated programmatically
Application Builder tool and other GUI Frameworks for using Java Beans use Reflection API
and display all the properties and events offered by a Java Bean in a toolbar in the
development environment. Developer can manipulate properties and write event handler
code in development environment. Properties can also be manipulated programmatically.
143
143
We enable you to leverage knowledge
anytime, anywhere!
Application Builder Tool
Java Bean components
(Classified in tabs)
Properties Window Displays
properties of selected bean
List of events
supported
Here is a sample Application Builder Tool.
144
144
We enable you to leverage knowledge
anytime, anywhere!
Sample Java Beans used in User Interface
Button Bean
Slider Bean
Here are some of Java Beans used in User Interface.
145
145
We enable you to leverage knowledge
anytime, anywhere!
Naming Conventions
Bean
Class name: Any user defined name
Should not have a constructor
Properties
What makes up a property?
Example:
A private data member called employeeNumber
A public get method by name getEmployeeNumber
A public set method by name setEmployeeNumber
Together these three form a property of a bean called
EmployeeNumber
Note: Method names and variables names are case
sensitive
The source code of a Java Bean is subject to certain naming conventions.
These naming conventions make it easier for beans to be reused, replaced and connected.
The naming conventions are:
Let us start with Bean class. The name of Bean class can be any user defined name.
To make up a property we are in need of three things.
1. Private data member.
2. Public getter and setter methods.
As discussed The getter method will start with get followed by the name of the property with
the initial letter in caps. Same holds with setter method.
Here is an example for the property.
Others Conventions are,
Every java bean class should implement java.io.Serializable interface
It should have non parametric constructor
Its properties should be accessed using get and set methods
It should contain the required event handling methods
146
146
We enable you to leverage knowledge
anytime, anywhere!
Bean Serialization (1/2)
A bean has the property of persistence when its properties,
fields, and state information are saved to and retrieved from
storage.
The beans support serialization by implementing either the
java.io.Serializable interface, or the
java.io.Externalizable interface
These interfaces offer 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
Examples of serializable classes include Component, String,
Date, Vector, and Hashtable
Bean Serialization
A bean has the property of persistence when its properties, fields, and state information are
saved to and retrieved from storage.
The beans support serialization by implementing either the
java.io.Serializable interface, or the
java.io.Externalizable interface
These interfaces offer 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
Examples of serializable classes include Component, String, Date, Vector, and Hashtable
147
147
We enable you to leverage knowledge
anytime, anywhere!
Bean Serialization (2/2)
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
To exclude fields from serialization in a Serializable
object from serialization, mark the fields with the
transient modifier.
transient int status;
Default serialization will not serialize transient and static
fields.
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
To exclude fields from serialization in a Serializable object from serialization, mark the fields
with the transient modifier.
Default serialization will not serialize transient and static fields.
148
ER/CORP/CRS/LA46/003
Advanced Java Programming
Module 7 - Java Naming & Directory Interface
We shall now move on to the module on Java Naming and Directory Interface - JNDI
149
149
We enable you to leverage knowledge
anytime, anywhere!
Lesson Outcomes
After Completion of the module you will be able to
understand about JNDI.
After Completion of the module you will be able to understand about JNDI.
150
150
We enable you to leverage knowledge
anytime, anywhere!
Introduction
Directory and Naming Services is used to organize
information hierarchically to map human understanding
of names and directory objects
JNDI is an extension of Java
JNDI provides Java application with a unified interface to
multiple naming and directory services in the enterprise
Directory and Naming Services is used to organize information hierarchically to map human
understanding of names and directory objects
In a distributed environment where the enterprise applications largely depends upon the
services provided by other applications, locating such services is a difficult issue. JNDI
provides common interface to many existing naming services like DNS, CORBA, NIS etc.
The Java Naming and Directory Interface (JNDI) is an application programming interface
(API) for accessing different kinds of naming and directory services. JNDI is not specific to a
particular naming or directory service, it can be used to access many different kinds of
systems including file systems; distributed objects systems like CORBA, Java RMI, and EJB;
and directory services like LDAP, Novell NetWare, and NIS+.
As part of the Java Enterprise API set, JNDI enables seamless connectivity to heterogeneous
enterprise naming and directory services. Developers can now build powerful and portable
directory-enabled applications using this industry standard.
151
151
We enable you to leverage knowledge
anytime, anywhere!
Naming Service
Associates names with Objects
Allows to lookup an Object by its name
Binding : association of name with the object
Context : a set of name-to-object bindings
E.g.:
Phone book associates peoples name with phone
number and addresses
DNS maps human friendly URLs with IP addresses
A naming service allows you to look up an object given its name. The process of
associating an object with its name forms binding. The set of bindings forms the Context.
COS, DNS,LDAP, NIS etc. are some of the Naming Service Providers
COS (Common Object Services) Naming: The naming service for CORBA applications;
allows applications to store and access references to CORBA objects.
DNS (Domain Name System): The Internet's naming service; maps people-friendly names
(such as www.etcee.com) into computer-friendly IP (Internet Protocol) addresses in dotted-
quad notation (207.69.175.36). Interestingly, DNS is a distributed naming service, meaning
that the service and its underlying database spread across many hosts on the Internet.
LDAP (Lightweight Directory Access Protocol): Developed by the University of Michigan;
as its name implies, it is a lightweight version of DAP (Directory Access Protocol), which in
turn is part of X.500, a standard for network directory services. Currently, over 40 companies
endorse LDAP.
NIS (Network Information System) and NIS+: Network naming services developed by Sun
Microsystems. Both allow users to access files and applications on any host with a single ID
and password.
152
152
We enable you to leverage knowledge
anytime, anywhere!
Directory Service (1 of 2)
Extended naming service
Not only allows name to be associated with objects as in
Naming service but also allows objects to have attributes
associated with them
Directory Service = Naming Service + attributes of objects
E.g. Yellow Pages Directory system :
Associates Customer name with the actual telephone
number/mobile number
Also provides extra information like address, occupation
of customer as attributes
Directory object represents an object in the computing
environment
A directory service can be viewed as a type of naming service augmented with the capability
to perform more sophisticated searches for objects.
Directory service searching can be based on attributes of that object with search filter criteria
and search controls. Directory services also allow for the modification of object attributes.
153
153
We enable you to leverage knowledge
anytime, anywhere!
Directory Services (2 of 2)
A set of connected objects forms a directory
Directory service provides operation for creating, adding,
removing, and modifying the attributes associated with
objects in a directory
Arrange the namespaces created in the Naming Services
in a hierarchy
Like the DOS file system; where the hierarchy starts from
the root directory then the subdirectories and then the
files.
It also has attributes like the date, size of the file which
gives us additional information.
Directory services typically have a hierarchical structure in which a directory object has a
context in some directory structure.
Thus each context will contain zero or more sub contexts and zero or more named directory
objects.
The directory object itself is manifested in a directory service as a collection of attributes
describing this object.
Directory services are used in many distributed enterprise applications in which a set of
distributed objects or information useful to other distributed objects may be registered,
unregistered, and queried based on a set of descriptive attributes.
A directory service search for a particular user may first involve formulating a query given
for a particular last name and geographical location such as city, state, and country.
The search result from this query may yield one or more directory objects matching this
criteria, each with a collection of attributes.
154
154
We enable you to leverage knowledge
anytime, anywhere!
JNDI Architecture (1 of 2)
Java Naming and Directory Interface (JNDI) is an API that
provides directory and naming functionality to Java
applications
The JNDI architecture consists of an API and a service
provider interface (SPI)
JNDI API allows Java applications to access a variety of
naming and directory services
The SPI enables a variety of naming and directory services
to be plugged in transparently, thereby allowing the Java
application using the JNDI API to access their services
Java Naming and Directory Interface (JNDI) is an API that provides directory and naming
functionality to Java applications
The JNDI architecture consists of an API and a service provider interface (SPI)
JNDI API allows Java applications to access a variety of naming and directory services
The SPI enables a variety of naming and directory services to be plugged in transparently,
thereby allowing the Java application using the JNDI API to access their services.
155
155
We enable you to leverage knowledge
anytime, anywhere!
JNDI Architecture (2 of 2)
Courtesy www.java.sun.com
Here is the JNDI Architecture.
156
156
We enable you to leverage knowledge
anytime, anywhere!
Service Providers
Service providers offers Naming and directory services for
various platforms
Service providers software maps the JNDI API to actual
calls to the naming or directory server
Important Service providers that comes along with JDK
Light Weight Directory Protocol (LDAP)
CORBA Common Object Services naming (COS
naming)
RMI registry
Domain Name Service (DNS)
JNDI client may invoke the JNDI API calls on these service
providers software to access the underline resources in
unified manner
Service providers offers Naming and directory services for various platforms
Service providers software maps the JNDI API to actual calls to the naming or directory
server
Important Service providers that comes along with JDK are
Light Weight Directory Protocol (LDAP)
CORBA Common Object Services naming (COS naming)
RMI registry
Domain Name Service (DNS)
JNDI client may invoke the JNDI API calls on these service providers software to access the
underline resources in unified manner
157
157
We enable you to leverage knowledge
anytime, anywhere!
JNDI Packages
javax.naming :contains classes and interfaces for
accessing naming services
javax.naming.directory: extends the core javax.naming
package to provide access to directories
javax.naming.spi : provide support for service provider
interface
javax.naming.event : contains classes and interfaces for
supporting event notification in naming and directory
services
javax.naming.ldap: contains classes and interfaces for
supporting LDAP v3 extensions and controls
JNDI Packages
javax.naming :contains classes and interfaces for accessing naming
services
javax.naming.directory : extends the core javax.naming package to provide
access to directories
javax.naming.spi : provide support for service provider interface
javax.naming.event : contains classes and interfaces for supporting event
notification in naming and directory services
javax.naming.ldap : contains classes and interfaces for supporting LDAP
v3 extensions and controls
158
158
We enable you to leverage knowledge
anytime, anywhere!
javax.naming Package
Some important APIs
Context.bind(String name, Object obj) : Binds the object obj with
name
Context.lookup(String name) : Retrieves the named object from
the list of bindings
Context.listBindings(String name): Returns NamingEnumaration
of the names bound in the named context
Context.unbind(String name) : Unbinds the named object
javax.naming package contains the classes and interfaces for accessing naming services.
One such interface is Context. This interface represents a naming context, which consists of
a set of name-to-object bindings. It contains methods for examining and updating these
bindings.
Context.bind(String name, Object obj) : Binds the object obj with name
Context.lookup(String name) : Retrieves the named object from the list of bindings
Context.listBindings(String name): Returns NamingEnumaration of the names
bound in the named context
Context.unbind(String name) : Unbinds the named object
159
159
We enable you to leverage knowledge
anytime, anywhere!
javax.naming.directory Package
Some important APIs
BasicAttribute.BasicAttribute(String id) : Constructs a new
instance of an unordered attribute
BasicAttribute.add(Object attrVal) : Adds a new value to this
attribute
BasicAttribute.get() : Retrieves one of this attributes' value
BasicAttribute.getAll() : Retrieves enumeration of this attributes'
value
DirContext.bind(String name, Object obj, Attributes attrs) : Binds
a name to an object, along with associated attributes
DirContext.search(String name, Attributes matchingAttributes ) :
Searches in a single context for objects that contain a specified
set of attributes.
javax.naming.directory Package extends the javax.naming package to provide functionality
for accessing directory services. It contains BasicAttribute class which implements Attribute
interface.
BasicAttribute(String id) : Constructs a new instance of an unordered attribute
BasicAttribute.add(Object attrVal) : Adds a new value to this attribute
BasicAttribute.get() : Retrieves one of this attributes' value
BasicAttribute.getAll() : Retrieves enumeration of this attributes' value
javax.naming.directory Package contains DirContext interface which is the directory service
interface, containing methods for examining and updating attributes associated with objects,
and for searching the directory.
DirContext.bind(String name, Object obj, Attributes attrs) : Binds a name to an
object, along with associated attributes
DirContext.search(String name, Attributes matchingAttributes ) : Searches in a
single context for objects that contain a specified set of attributes.
160
160
We enable you to leverage knowledge
anytime, anywhere!
javax.naming.directory Package
javax.naming.directory Package extends the javax.naming package to provide functionality
for accessing directory services. It contains BasicAttribute class which implements Attribute
interface.
BasicAttribute(String id) : Constructs a new instance of an unordered attribute
BasicAttribute.add(Object attrVal) : Adds a new value to this attribute
BasicAttribute.get() : Retrieves one of this attributes' value
BasicAttribute.getAll() : Retrieves enumeration of this attributes' value
javax.naming.directory Package contains DirContext interface which is the directory service
interface, containing methods for examining and updating attributes associated with objects,
and for searching the directory.
DirContext.bind(String name, Object obj, Attributes attrs) : Binds a name to an
object, along with associated attributes
DirContext.search(String name, Attributes matchingAttributes ) : Searches in a
single context for objects that contain a specified set of attributes.
161
161
We enable you to leverage knowledge
anytime, anywhere!
JNDI Naming & Lookup Example
import java.rmi.*;
import java.rmi.server.*;
public class ServerRMI extends UnicastRemoteObject implements InterfaceRMI
{
public ServerRMI() throws RemoteException {
super();
}
public int cube(int x) throws RemoteException {
return x*x*x;
}
public static void main(String a[]) {
try{
ServerRMI rs = new ServerRMI();
//binding the server object with the RMIRegistry
Naming.rebind("MyServer",rs Naming.rebind("MyServer",rs Naming.rebind("MyServer",rs Naming.rebind("MyServer",rs); ); ); );
System.out.println("System is ready");
}catch(Exception e){System.out.println(e);}
}
}
In the above example we are creating the object of ServerRMI. This object is bound to the
RMI registry (running on the local machine) by invoking Naming.rebind() method.
Here the service provider for RMI registry is Sun.
List of all binding in the registry can be obtained by invoking a call for list().
Naming.list(//localhost/) : Returns all the available bindings in the
registry
To search a particular object with its name, invoke lookup()
Naming.lookup(//localhost/MyServer) : Searches the RMI registry for
object named as MyServer
162
ER/CORP/CRS/LA46/003
Module 8: Generics
Advanced Java Programming
163
163
We enable you to leverage knowledge
anytime, anywhere!
Why Generics?
Many algorithms work in a similar way irrespective of the data
types on which they are applied on
All Stacks work in a similar way irrespective of they type of
object they hold
Generics help to write algorithms independent of a data type.
Generic programming in earlier versions of Java uses Object
as the basic element of a data structure.
For example Generic Stack has methods which works with
Objects
Class Stack
{
..
public Object push(Object item) {..}
public Object pop(){..}
..}
164
164
We enable you to leverage knowledge
anytime, anywhere!
Older Approach
Example: Generic Stack. [JDK1.4]
import java.util.*;
public class StackExample{
public static void main(String[] args){
int i1=1;
int i2=2;
int i3=3;
//Stack creation
Stack s1=new Stack();
//Adding elements to the stack
s1.push(new Integer(i1));
s1.push(new Integer(i2));
s1.push(new Integer(i3));
//Removing elements from the
stack;
Integer x;
x= (Integer)s1.pop();
x= (Integer)s1.pop();
x= (Integer)s1.pop();
}
}
165
165
We enable you to leverage knowledge
anytime, anywhere!
Older Approach (contd..)
The constraints over this approach are,
Any object whatever it [String, Integer etc.] may be
can be pushed on to the stack.
If a Stack is supposed to hold only strings, we cant
restrict the Stack to hold only the Strings.
Object that is popped out from the stack has to be
type casted back to the required type before use.
This type cast is unsafe too. Because the compiler
wont check whether the typecast is to the same type
as stored in the stack. So the cast may fail at run-time.
Solution:
Generics [Java 5]
166
166
We enable you to leverage knowledge
anytime, anywhere!
New Approach [Generics]
The new approach expects Stack to be of the form.
Where E is the Type Parameter.
The elements pushed onto and popped from the stack are
type E.
If we declare Stack<String> s=new stack<String>() then
s.push(Hello); will be allowed and s.push(new Integer(0)) will
be rejected at compile-time.
Furthermore s.pop() is known to compiler as String, So no
type cast is necessary.
Class Stack <E>
{
..
public E push(E item) {..}
public E pop(){..}
..}
Note: If you declare a Stack<E>, the Stack works with instances of E and allow you to store
one of the following types:
1. An instance of E
2. An instance of a sublcass of E, if E is a class
3. An instance of class implementing E, if E is an interface.
167
167
We enable you to leverage knowledge
anytime, anywhere!
New Approach [Generics] (contd..)
Example: Generic Stack. [Java 5]
In this approach once the compiler knows the element
type of the stack, the compiler can check whether the
correct type is used consistently and can insert the correct
casts on the values taken out from the stack.
import java.util.*;
public class StackExample{
public static void main(String[] args){
int i1=1;
int i2=2;
int i3=3;
//Stack creation
Stack<Integer> s1=new Stack<Integer>();
//Adding elements to the stack
s1.push(new Integer(i1));
s1.push(new Integer(i2));
s1.push(new Integer(i3));
//Removing elements from the
stack;
Integer x;
x= s1.pop();
x= s1.pop();
x= s1.pop();
}
}
168
168
We enable you to leverage knowledge
anytime, anywhere!
Multiple Type Parameters
There can be more than one type parameter for a class
or interface.
Example:
class Hashtable<K,V>{
..
public V put(K key, V value) { ..}
..
}
169
169
We enable you to leverage knowledge
anytime, anywhere!
Raw Type
All the collection types in J2SE 5.0 has been made Generic.
Still a Generic type can be used without type parameters.
Such a type is called Raw type.
Example: Stack Generic Type used as Raw Type
Stack s=new Stack();
s.push(new Integer(0));
Integer x=(Integer)s.pop();
In such case the compiler will give the following warning.
Note:
D:\NetBeansDemos\GenericsDemo\GenericDemo\src\g
enericdemo\Main.java uses unchecked or unsafe
operations.
Note: Recompile with -Xlint:unchecked for details.
170
170
We enable you to leverage knowledge
anytime, anywhere!
Bounded Types
A generic can restrict the type of object that can be used
as the parameter
A generic List class that performs arithmetic operations on the
elements may want to restrict the parameters to Integer, Float,
Double etc
Number is the super class of all the numeric wrapper classes
public class List<T extends Number>{
//Code goes here
}
Only Number or its sub classes can be used as a parameter
to List
171
171
We enable you to leverage knowledge
anytime, anywhere!
WildCards
import java.util.*;
public class Main {
public static void printList
(List<Object> list){
for(Object element:list){
System.out.println(element);
}
}
public static void main(String[] args) {
List<String> ls=new
ArrayList<String>();
ls.add("One");
ls.add("Two");
ls.add("Three");
List<Integer> li=new
ArrayList<Integer>();
li.add(new Integer(100));
li.add(new Integer(200));
li.add(new Integer(300));
printList(ls); //Compilation Error
printList(li); //Compilation Error
}
Problem: This code wont compile
because printList method expects
an instance of List<Object> but we
are trying to pass List<Integer>
and List<String> instances; though
String and Integer are subclasses
of Object.
Consider the following example
This code wont compile because printList method expects an instance of List<Object> but
we are trying to pass List<Integer> and List<String> instances though String and Integer are
subclasses of Object.
172
172
We enable you to leverage knowledge
anytime, anywhere!
WildCards (Contd..)
Solution: Use Wildcards.
import java.util.*;
public class Main {
public static void printList (List<?>
list){
for(Object element:list){
System.out.println(element);
}
}
public static void main(String[] args) {
List<String> ls=new
ArrayList<String>();
ls.add("One");
ls.add("Two");
ls.add("Three");
List<Integer> li=new
ArrayList<Integer>();
li.add(new Integer(100));
li.add(new Integer(200));
li.add(new Integer(300));
printList(ls);
printList(li);
}
NOTE:
Wildcards can not be used
when declaring or creating a generic
data type. If a list has to be created
that accepts any type of Object, then
the following has to be used
List<Object> lo=new
Now the PrintList() method can accept List of any type.
173
173
We enable you to leverage knowledge
anytime, anywhere!
Bounded Wildcards
import java.util.*;
public class Main {
public static void
sumOfElements(List<?> li){
double sum=0;
for(Object element:li){
Number
num=(Number)element;
sum+=num.doubleValue();
}
System.out.println("Sum of
elements of the List is: "+sum);
}
public static void main(String[]
args) {
List<Double> i1=new
ArrayList<Double>();
i1.add(new Double(100));
i1.add(new Double(200));
i1.add(new Double(300));
sumOfElements(i1);
}
}
Consider the following example
Analyze the given example. This program will find the sum of elements in the list.
Problem:
sumOfElements method accepts list of any type. But as per the requirement it can
accept only the list of type Numberic(Number and its sub types).
174
174
We enable you to leverage knowledge
anytime, anywhere!
Bounded Wildcards (contd..)
Problem:
sumOfElements method can accept list of any type:
List<String>, List<Object>, List<Integer> etc.
But as per the requirement it can accept only the list
of Numeric types (Number and its sub types).
Solution:
Use Bounded Wildcards.
Types
Upper Bounds (Keyword: extends)
Lower Bounds (Keyword: super)
175
175
We enable you to leverage knowledge
anytime, anywhere!
Bounded Wildcards (contd..)
Upper Bounds
Example:
Use of <? extends Number> sets sumOfElements method to accept Lists of type List<Number>
or a List of instances of a Number subclass, such as List<Integer>, List<Float>, List<Double> etc
and not others.
import java.util.*;
public class Main {
public static void
sumOfElements(List<? extends
Number> li){
double sum=0;
for(Number element:li){
sum+=element.doubleValue();
}
System.out.println("Sum of
elements of the List is: "+sum); }
public static void main(String[] args)
{
List<Double> i1=new
ArrayList<Double>();
i1.add(new Double(100));
i1.add(new Double(200));
i1.add(new Double(300));
sumOfElements(i1);
}
}
176
176
We enable you to leverage knowledge
anytime, anywhere!
Bounded Wildcards (contd..)
Lower Bounds
Keyword: super.
Example:
sumOfElements(List<? super Integer> li){..}
Use of <? super Integer> sets sumOfElements
method to accept List of type List< Integer> or a List
of instances of Integer superclass, such as
List<Number> and List<Object> and not others.
177
177
We enable you to leverage knowledge
anytime, anywhere!
Generic Methods
Method declarations can also be made generic.
Based on the types of the arguments passed to the
generic method, the compiler handles each method call
appropriately.
The type parameter section is delimited by angle
brackets and appears before the method's return type.
public static <T extends
Comparable<T>> T greatest(T
a,T b){
if(a.compareTo(b)>0){
return a;
}
else{
return b; } }
public static void main(String[] args) {
int max=greatest(19999,2000);
System.out.println(max);
double max1=greatest(-0.0111,
-0.111);
System.out.println(max1);
}
178
178
We enable you to leverage knowledge
anytime, anywhere!
Generic Sub Class
A Generic Class can be extended to create another
Generic class
public class LinkedList<T> extends List<T>{
//Code goes here
}
179
179
We enable you to leverage knowledge
anytime, anywhere!
Generic Interface
Generic interfaces can be created and used as follows
interface List<T>{
public void put(T element, int position);
public T get(int position);
}
class LinkedList<T> implements List<T>{
//Implementation goes here
}
180
180
We enable you to leverage knowledge
anytime, anywhere!
Erasure
Generics in Java are implemented using a technique
called erasure.
Generic type information is present only at compile time,
after which it is erased by the compiler.
Advantage:
interoperability between generic code and legacy code that uses
non-parameterized types (Raw types).
Disadvantage:
parameter type information is not available at run time, and that
automatically generated casts may fail when interoperating with
ill-behaved legacy code.
Example:
Integer ival=new Integer(10);
List<String> ls=new ArrayList<String>();
List lr=ls;
lr.add(ival);
String listData=ls.get(0); //Run Time Error
This code fails because at run-time
String listData=ls.get(0);
Becomes,
String listData=(String)ls.get(0);
181
181
We enable you to leverage knowledge
anytime, anywhere!
Some Generic Restrictions
A type parameter cannot be instantiated
T t1 = new T(); //Error, this will not work
T [] t2 = new T[5]; //Error, this will not work
A generic class cannot extend Throwable
We cannot have generic exception classes
We cant use a Generic of Primitive type.
List<int>=new .. //not allowed.
182
ER/CORP/CRS/LA46/003
Advanced Java Programming
Module 9 - Annotations
183
183
We enable you to leverage knowledge
anytime, anywhere!
Agenda
Overview
Introduction to Annotations
Annotation Basics
Built-in Annotations
@override
@deprecated
@SuppressWarnings
Meta Annotations
Accessing Annotation at Runtime
Annotation Inheritance
Advantages of Annotations
References
184
184
We enable you to leverage knowledge
anytime, anywhere!
Overview
Annotations, a new feature in J2SE 5.0 brings a much-
needed metadata facility to the core java language.
Annotations are modifiers, can be added to the code and
applied to package declarations, type declarations,
constructors, methods, fields, parameters, and variables.
Annotations do not directly affect program semantics, but
they do affect the way programs are treated by tools and
libraries, which can in turn affect the semantics of the
running program.
185
185
We enable you to leverage knowledge
anytime, anywhere!
Introduction to Annotations
The Java designers took the notion of a javadoc tag and
generalized it.
An Annotation is a special kind of modifiers(such as
public, static or final). By convention, annotations
precede other modifiers.
An annotation is an attribute of a program element.
Annotations can be read from source files, class files, or
reflectively at run time
Annotations take the form of an "at" sign (@), followed by
the annotation name.
Examples:
@Author( "Jack Doe" )
@Author( value="Jack Doe" )
@Author(@Name(first="Jack",last="Doe"))
Annotations complement javadoc tags. Ingeneral, ifthe markup is intended to affect or produce a
documentation, it should probably be a javadoc tag;otherwise, it should be an annotation.
The JavadocTM tool parses the declarations and documentation comments in a set
of Java source files and produces a corresponding set of HTML pages describing (by default) the
public and protected classes, nested classes (but not anonymous inner classes), interfaces,
constructors, methods, and fields. You can use it to generate the API (Application Programming
Interface) documentation or the implementation documentation for a set of source files.
Syntactically, the annotation is placed in front of the program element's declaration, similar to
static or final or protected.
An annotation is an attribute of a program element. An Annotation could virtually be placed ahead of
any program element, including declarations (package, class, method, and field) and
statements(Single Block).
Annotations take the form of an "at" sign (@), followed by the annotation name.
Examples:
@Author( "Jack Doe" )
@Author( value="Jack Doe" )
@Author(@Name(first="Jack",last="Doe"))
186
186
We enable you to leverage knowledge
anytime, anywhere!
Introduction to Annotations
Annotations go in their own files, just like classes.
Annotation interfaces may not extend anything. They
automatically extend java.lang.annotation.Annotation.
Their methods take no arguments.
A field with the same name is automatically declared.
An annotation instance consists of
the "@" sign
the annotation name
a parenthesized list of name-value pairs.
If only one value named value,
The name may be omited.
If no values,
No parentheses needed.
@InfosysAnnotation(
id = 77480,
Name = Rahul",
Designation =
Manager",
date = 27/3/2007"
)
public static void
employeeJoining (int id) { ... }
Annotations go in their own files, just like classes.
Annotation interfaces may not extend anything. They automatically extend
java.lang.annotation.Annotation.
Their methods take no arguments.
A field with the same name is automatically
declared.
An annotation instance consists of
the "@" sign
the annotation name
a parenthesized list of name-value pairs.
If only one value named value,
The name may be omited.
If no values,
No parentheses needed.
The InfosysAnnotation takes four values, they are Id,Name, Designation and date of join.
187
187
We enable you to leverage knowledge
anytime, anywhere!
Annotation Basics
Annotatable Program elements:
package
class, including
interface
enum
method
field
only at compile time
local variable
Formal parameter
Annotatable Program elements are
package
class, including
interface
enum
method
field
only at compile time
local variable
Formal parameter
188
188
We enable you to leverage knowledge
anytime, anywhere!
Legal Annotation Elements
primitive types
Strings
enum types
Classes (not general Objects)
arrays of the above
combinations of the above
The Legal Annotation Elements are
primitive types
Strings
enum types
Classes (not general Objects)
arrays of the above
combinations of the above
189
189
We enable you to leverage knowledge
anytime, anywhere!
Annotation Basics
Annotations
Marker
Annotations
(with no member )
Single-valued
Annotations
(With single
member)
Multi-valued
Annotations
(With more
Than one
Member)
Annotations fall into three basic categories:
Example:-
@MarkerAnnotation()
@SingleValueAnnotation("my data")
@MultiValuedAnnotation(var1="data value 1",
var2="data value 2", var3="data value 3").
Annotations fall into three basic categories:
Marker annotations have no variables. The annotation simply appears, identified by name,
with no additional data supplied. For example, @MarkerAnnotation is a marker annotation. It
includes no data, just the annotation name.
Single-value annotations are similar to markers, but provide a single piece of data.
Because only a single bit of data is supplied, you can use a shortcut syntax (assuming the
annotation type is defined to accept this syntax): @SingleValueAnnotation("my data").
This should look a lot like a normal Java method call, aside from the @ sign.
Full annotations have multiple data members. As a result, you must use a fuller syntax (and
the annotation doesn't look quite so much like a normal Java method anymore):
@FullAnnotation(var1="data value 1", var2="data value 2", var3="data value 3").
190
190
We enable you to leverage knowledge
anytime, anywhere!
Built in Annotations
The pre defined Annotation types are
@Deprecated
@override
@SupressWarnings
@Target
@Retention
@Inherited
The pre defined Annotation types are
@Deprecated
@override
@SupressWarnings
@Target
@Retention
@Inherited
The last three are called as meta annotations. Since, These annotations helps to annotate
the existing annotations.
191
191
We enable you to leverage knowledge
anytime, anywhere!
Built in Annotation -Deprecated
Deprecated is a marker annotation.
As you might expect, you use Deprecated to annotate a method that
shouldn't be used anymore.
The following Main class has a method named deprecatedMethod()
that is flagged with the @Deprecated annotation
public class Main {
@Deprecated
public static void deprecatedMethod() {
System.out.println("Don't call me");
} }
You compile a class with annotations the same way as you
do for one without annotations:
> javac Main.java produces Main.class
Read the Slides:-
The change from the @deprecated comment to the @Deprecated annotation doesn't introduce
anything really new to the system. It only slightly changes the way of doing the same thing.
192
192
We enable you to leverage knowledge
anytime, anywhere!
Built in Annotation -Deprecated
If you use the deprecated method, it produces a
compilation-time warning
public class User {
public static void main(String args[]) {
Main.deprecatedMethod(); } }
Compile the class:
javac User.java
and you'll see the following warning about using a
deprecated method:
Note: User.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Adding the -Xlint to the compilation line shows specifically what is wrong:
javac -Xlint:deprecation User.java User.java:3: warning: [deprecation] deprecatedMethod() in Main
has been deprecated Main.deprecatedMethod();
^ 1 warning
193
193
We enable you to leverage knowledge
anytime, anywhere!
Built in Annotation
Override : Override should be used only on methods
(not on classes, package declarations, or other
constructs). It indicates that the annotated method is
overriding a method in a superclass.
public class Overrode {
@Override
public int hashCode() {
return 0;
}
@Override
public boolean equals(Object o) {
return true; } }
The above code should be pretty easy to follow. The @Override annotation annotates two methods -
- equals() and hashCode() -- to indicate that they override versions of the methods from the parent
Object class(java.lang.Object). This might seem trivial at first, but it's actually a nice feature. You
literally cannot compile this class without overriding these methods. The annotation also ensures that
when you mess with equals(), you also have at least some indication that you should make sure that
hashCode() still matches up.
This annotation type really shines when you're up too late coding and mistype something, as in next
code.
194
194
We enable you to leverage knowledge
anytime, anywhere!
SuppressWarnings Annotation
The final of the three new annotations in J2SE 5.0,
@SuppressWarnings .
It tells the compiler not to warn you about something that
it would normally warn you about.
The javac compiler defines seven options to suppress:
all, deprecation, unchecked, fallthrough, path, serial, and
finally.
let's look at the suppression of the fallthrough option
Let's start with the following class. Notice that the class is
missing a break statement for each case of the switch
statement:
The final of the three new annotations in J2SE 5.0, @SuppressWarnings .
It tells the compiler not to warn you about something that it would normally warn you about.
Warnings belong to a category, so you have to tell the annotation what types of warnings to suppress
The javac compiler defines seven options to suppress: all, deprecation, unchecked, fallthrough, path,
serial, and finally. (The language specification defines only two such types: deprecation and
unchecked.)
let's look at the suppression of the fallthrough option
Let's start with the following class. Notice that the class is missing a break statement for each case of
the switch statement:
195
195
We enable you to leverage knowledge
anytime, anywhere!
SuppressWarnings Annotation
public class Fall {
public static void main(String args[]) {
int i = args.length;
switch (i) {
case 0: System.out.println("0");
case 1: System.out.println("1");
case 2: System.out.println("2");
case 3: System.out.println("3");
default: System.out.println("Default");
}
} }
Compile the class with javac. You'll see that it simply creates the .class file, and displays no warnings:
javac Fall.java
If you want the compiler to warn you about switch statements that fall through (that is, one or more break
statements are missing), you compile with the -Xlint:fallthrough option:
javac -Xlint:fallthrough Fall.java
This produces the following warnings:
Fall.java:6: warning: [fallthrough] possible fall-through into case case 1: System.out.println("1");
Fall.java:7: warning: [fallthrough] possible fall-through into case case 2: System.out.println("2");
Fall.java:8: warning: [fallthrough] possible fall-through into case case 3: System.out.println("3");
Fall.java:9: warning: [fallthrough] possible fall-through into case default : System.out.println("Default");
4 warnings
But what if you want to ignore the fact that the switch statement is missing a break statement for each
case? That's where the @SuppressWarnings annotation comes into play.
If you add the following line before the main() method declaration:
196
196
We enable you to leverage knowledge
anytime, anywhere!
SuppressWarnings Annotations
public class Fall {
@SuppressWarnings("fallthrough")
public static void main(String args[]) {
int i = args.length;
switch (i) {
case 0: System.out.println("0");
case 1: System.out.println("1");
case 2: System.out.println("2");
case 3: System.out.println("3");
default: System.out.println("Default");
}
}
}
@SuppressWarnings("fallthrough")
Compiling the class with the -Xlint:fallthrough option:
javac -Xlint:fallthrough Fall.java
will just generate the .class file and display no warnings.
@SuppressWarnings annotations can also be used to suppress other warnings such as those
that would be displayed if you used a collection without specifying the data type of the
collection elements.
Don't use the @SuppressWarnings annotation simply to avoid the compilation-time warning.
Use it where an unchecked warning is unavoidable, such as when using a library that isn't
built with generics in mind
197
197
We enable you to leverage knowledge
anytime, anywhere!
Meta Annotations
@Documented
@Inherited
@Target
@Retention
The set of predefined annotation types you learned about in Part 1 have a predetermined purpose.
However, as you move into writing your own annotation types, the purpose of your annotation types
isn't always self-evident. In addition to basic documentation, you'll probably write types that are
specific to a certain member type, or perhaps a certain set of member types. This requires you to
supply some sort of metadata on your annotation type, so that the compiler can enforce the
annotation's intended functionality.
You can use four predefined annotation types -- referred to as meta-annotations -- to annotate your
annotations
Read the slides
198
198
We enable you to leverage knowledge
anytime, anywhere!
Meta-Annotations
@Documented
javadoc should be generated when this annotation is
applied to an element
Is the use of the annotation part of the public API
@Inherited
Does the annotated get applied to subclasses or to
the base type?
only works on classes
not overriden methods
not interfaces
@Documented
Indicates that annotations with a type are to be documented by javadoc and similar tools by default.
This type should be used to annotate the declarations of types whose annotations affect the use of
annotated elements by their clients. If a type declaration is annotated with Documented, its
annotations become part of the public API of the annotated elements.
@Inherited
Indicates that an annotation type is automatically inherited. If an Inherited meta-annotation is present
on an annotation type declaration, and the user queries the annotation type on a class declaration,
and the class declaration has no annotation for this type, then the class's superclass will
automatically be queried for the annotation type. This process will be repeated until an annotation for
this type is found, or the top of the class hierarchy (Object) is reached. If no superclass has an
annotation for this type, then the query will indicate that the class in question has no such annotation.
199
199
We enable you to leverage knowledge
anytime, anywhere!
Meta-Annotations
@Target
Where the annotation can be used
What kind of source elements
Defaults in all
public @interface Target {
ElementType[] value();
}
Indicates the kinds of program element to which an annotation type is applicable. If a Target meta-
annotation is not present on an annotation type declaration, the declared type may be used on any
program element. If such a meta-annotation is present, the compiler will enforce the specified usage
restriction. For example, this meta-annotation indicates that the declared type is itself a meta-
annotation type. It can only be used on annotation type declarations:
@Target(ElementType.ANNOTATION_TYPE)
public @interface MetaAnnotationType { ... }
This meta-annotation indicates that the declared type is intended solely for use as a member type in
complex annotation type declarations. It cannot be used to annotate anything directly:
@Target({})
public @interface MemberType { ... }
It is a compile-time error for a single ElementType constant to appear more than once in a Target
annotation. For example, the following meta-annotation is illegal:
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.FIELD})
public @interface Bogus { ... }
200
200
We enable you to leverage knowledge
anytime, anywhere!
Annotation-@Retention
Indicates how long annotations with the annotated type
are to be retained. If no Retention annotation is present
on an annotation type declaration,
The retention policy defaults to RetentionPolicy.CLASS.
Annotations meta-annotated with Retention(RUNTIME)
can be accessed via reflection mechanisms
Read the slides
201
201
We enable you to leverage knowledge
anytime, anywhere!
Meta Annotations -Retention Policies
Annotations can have one of three retention policies:
Source-file retention
Annotations with source-file retention are read by the compiler
during the compilation process, but are not rendered in the
generated .class files.
Class-file retention
This is the default retention policy. Annotations with class-file
retention are read by the compiler and also retained in the
generated .class files.
Runtime retention
Annotations with runtime retention are read by the compiler,
retained in the generated .class files, and also made available at
runtime.
Local variable annotations are not retained in class files (or at
runtime) regardless of the retention policy set on the annotation type
Read the slides:-
202
202
We enable you to leverage knowledge
anytime, anywhere!
Class Annotation Example
import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(value=RetentionPolicy.RUNTIME)
@Illustrate( {
Illustrate.Feature.annotation,
Illustrate.Feature.enumeration } )
public @interface Illustrate {
enum Feature {
annotation, enumeration, forLoop,
generics, autoboxing, varargs;
@Override public String toString() {
return "the " + name() + " feature";
}
};
Feature[] value() default {Feature.annotation};
}
Things to Note in Example
Annotations may be annotated.
These are known as meta annotations.
An annotation may be annotated with itself.
203
203
We enable you to leverage knowledge
anytime, anywhere!
import java.lang.annotation.Target;
import java.lang.annotation.Annotation;
import java.lang.annotation.Inherited;
@Illustrate(
{Illustrate.Feature.enumeration,Illustrate.Feature.forLoop})
public class Suggester {
// @SuppressWarnings({"unchecked"}) // not yet supported
public static void main( String[] args ) {
try {
java.util.Scanner userInput =
new java.util.Scanner( System.in );
System.out.print( "In what class are you interested? " );
Class theClass = Class.forName( userInput.next() );
Illustrate ill =
(Illustrate)theClass.getAnnotation( Illustrate.class);
If suppressWarningAnnotation is uncommented, then the compiler will suppressthe warning. Our
intention is to check the warning, so comment the line supresswarnings.
Annotation Access Example
Annotations meta-annotated with Retention(RUNTIME) can be accessed via
reflection mechanisms.
The following example shows a program that pokes at classes to see "if they illustrate anything."
204
204
We enable you to leverage knowledge
anytime, anywhere!
if ( ill != null ) {
System.out.println( "Look at this class if you'd " +
" like to see examples of" );
for ( Illustrate.Feature f : ill.value() ) {
System.out.println( "\t" + f );
}
}
else {
System.out.println(
"That class will teach you nothing." );
}
}
catch( ClassNotFoundException cnfe ) {
System.err.println( "I could not find a class named \"" +
cnfe.getMessage() + "\"." );
System.err.println( "Are you sure about that name?" );
}
} }
205
205
We enable you to leverage knowledge
anytime, anywhere!
Compilation and Execution
javac *.java
Note: Suggester.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
java Suggester
In what class are you interested? Suggester
Look at this class if you'd like to see examples of
the enumeration feature
the forLoop feature
java Suggester
In what class are you interested? Illustrate
Look at this class if you'd like to see examples of
the annotation feature
the enumeration feature
Read the slides
206
206
We enable you to leverage knowledge
anytime, anywhere!
Annotation Inheritance
By default annotations are not inherited.
For Example
@MyAnnotation class Super {
@Oneway public void foo() {}
}
class Sub extends Super {
public void foo() {}
}
Then Sub does not have the MyAnnotation annotation, and
Sub.foo() is not an @Oneway method, despite the fact that it
overrides Super.foo() which is.
It is important to understand the rules relating to inheritance of annotations, as these have a bearing
on join point matching based on the presence or absence of annotations
If an annotation type has the meta-annotation @Inherited then an annotation of that type on a class
will cause the annotation to be inherited by sub-classes. So, in the example above, if the
MyAnnotation type had the @Inherited attribute, then Sub would have the MyAnnotation annotation.
@Inherited annotations are not inherited when used to annotate anything other than a type. A type
that implements one or more interfaces never inherits any annotations from the interfaces it
implements.
207
207
We enable you to leverage knowledge
anytime, anywhere!
Advantages
EJB, Web Services etc
Replace or supplement descriptors with annotation
Code generate boring classes/interface
Annotated EJB implementation to generate Home, Remote
etc
Annotated web Services implementation to generate servlets
binding and JAX-RPC interfaces etc.
Your use case for generating code form annotated
classes/interfaces
JavaBeans, logger utilities, debugging classes , etc
Recognizing special methods, classes, etc at runtime
Test methods, plug-in points, UI elements, etc
Read the slides.
208
208
We enable you to leverage knowledge
anytime, anywhere!
References
http://java.sun.com/javase/6/docs/technotes/guides/language/
annotations.html
http://www.eclipse.org/aspectj/doc/released/adk15notebook/an
notations.html
http://www-128.ibm.com/developerworks/library/j-annotate1/
http://www-128.ibm.com/developerworks/library/j-
annotate2.html
http://www.softwaresummit.com/2004/speakers/LandersAnnot
ations.pdf
http://java.sun.com/mailers/techtips/corejava/2006/tt0620.html
http://java.sun.com/javase/6/docs/technotes/guides/language/annotations.html
http://www.eclipse.org/aspectj/doc/released/adk15notebook/annotations.html
http://www-128.ibm.com/developerworks/library/j-annotate1
http://www-128.ibm.com/developerworks/library/j-annotate2.html
http://www.softwaresummit.com/2004/speakers/LandersAnnotations.pdf
209
209
We enable you to leverage knowledge
anytime, anywhere!
Thank You!

You might also like