Add to Google Reader or Homepage

Javax.naming.NameAlreadyBoundException

                                If you glance at the title you could have an idea about this exception. It says that Name is Already bounded. 

What does it mean? 


When we are dealing with RMI, we know that the server needs to register the remote object in the RMI registry with a name. The client will use this name to get the remote object.I  have already explained this in my post Java RMI tutorial.Here we have to know one thing that each remote object should be registered with a unique name.

So it is obvious that when two different remote objects are registered with same name then this exception will be thrown for example, if we do like this, then this exception will be thrown.

.....................
.............................
.............................
 Context namingContext = new InitialContext();
namingContext.bind("rmi:central",store);//binding the remote object store with name central
namingContext.bind("rmi:central",shop);
//binding the remote object shop with name central

What are the other reasons?

 In the above shown exmaple, i have registered two different remote objects with same name and so i got this exception thrown, "but the other common reason is trying to  re-bind the object with the same name". 

 When this kind of situation occurs?


I have already told in my post  Executing java RMI that to execute an RMI we need to start the rmi registry first and then execute the server and then client. If you set the codebase property correctly it will work fine, but when you try to re-execute the  server you may have encountered this exception even though codebase is set correctly. why? because "you have actually tried to re-bind the object that is already bounded with the same name".

Here you should understand that "as long as RMI registry is running the entries of the registry persists until the RMI registry is stopped". so when re-executing the server ensure that  the  RMI registry is re-started again.




java.util.ConcurrentModificationException

                           

                In this post we will see about the Concurrent Modification Exception which is usually thrown when a collection is structurally modified by more than one  iterators .Let us see in detail about this exception.

In java API it is given that,"If a method detects that an object is concurrently modified and when such a modification is not permissible, then this exception will be thrown".

 What does it mean?

 

This could be clearly explained in the context of collections, we all know that the collections are used to store the objects and there are iterators available,which contains methods that  enables us to traverse through the collections and  to add and remove elements at the desired locations.

This feature brings us a problem that "when two iterators are simultaneously used to modify the collection then this exception will be thrown" and there are two other situations at which this exception will be thrown, let's see what are they?

-->

Situation 1

 "Do not instantiate an iterator until the collection is filled with the objects", Let's see what happens if we instanitate an iterator before the collection is filled.


Program

import java.util.*;
import java.lang.*;
class Concurrenttest
{
public static void main(String args[])
{
LinkedList a=new LinkedList();
ListIterator li=a.listIterator();//line no 8
a.add("wow");
a.add("world");
a.add("ganesh");//line no 11
System.out.println(a);
System.out.println(li.next());// line no 13
}
}
 


Output

[wow, world, ganesh]
Exception in thread "main" java.util.ConcurrentModificationException
        at java.util.LinkedList$ListItr.checkForComodification(Unknown Source)
        at java.util.LinkedList$ListItr.next(Unknown Source)
        at Concurrenttest.main(Concurrenttest.java:13)

 Here in the above program you can see that i have just created a collection and stored in it  some string objects and i tried to traverse through the list but it throws Concurrent Modification Exception. But if you instantiate the iterator (line no 8)after the collection is filled(line no 11) then this exception would not be thrown.

Situation 2

 

 ''Do not  use the iterator and the collection object itself to modify the collection  simultaneously", Otherwise this exception would be thrown,

program

import java.util.*;
import java.lang.*;
class Concurrenttest
{
public static void main(String args[])
{
LinkedList a=new LinkedList();
a.add("wow");
ListIterator li=a.listIterator();
System.out.println(li.next());
a.add("world");//adding the object(modifying)
li.remove();// removing the object(modifying)
System.out.println(a);
}
}
 

Output

wow
Exception in thread "main" java.util.ConcurrentModificationException
        at java.util.LinkedList$ListItr.checkForComodification(Unknown Source)
        at java.util.LinkedList$ListItr.remove(Unknown Source)
        at Concurrenttest.main(Concurrenttest.java:12)
 
 In the above program you can see that i have used both the collection object and iterator to simultaneously modify the collection. In order to avoid this kind of problem, use any one,either iterator or collection object to modify the collection.

Use of Two Iterators simultaneously


This is the first reason which i have mentioned before,i.e, "using two iterators simultaneously to modify the collection".


Program

import java.util.*;
import java.lang.*;
class Concurrenttest
{
public static void main(String args[])
{
LinkedList a=new LinkedList();
a.add("wow");
a.add("world");
a.add("ganesh");
System.out.println(a);
ListIterator li=a.listIterator();
ListIterator li1=a.listIterator();
System.out.println(li.next());
li.remove();//one iterator removing the first object
li1.next();//Another iterator trying to read the first object that was removed
}
}

Output

[wow, world, ganesh]
wow
Exception in thread "main" java.util.ConcurrentModificationException
        at java.util.LinkedList$ListItr.checkForComodification(Unknown Source)
        at java.util.LinkedList$ListItr.next(Unknown Source)
        at Concurrenttest.main(Concurrenttest.java:16)

If you read the comment line of the above program you can understand what i have done.Thus in this case use only one iterator to modify and traverse the object  or use two iterators only to traverse the objects.


 

JTextArea - An Example

JTextArea


Before discussing TextArea let us know the difference between TextField and TextArea,
The difference between these two components,are as follows.

 "A TextField is an input box where we can only enter single line of text whereas a TextArea allows you to enter multiple line of texts".

 " If the text is more than the display area of the Field a TextField will never grow but the TextArea will grow".

Creating a TextArea


A TextArea can be created by using the  JTextArea class of the Swing package as follows,

JTextArea area=new JTextArea(height,width);

Here 'height' and 'width' specifies the number of rows and columns  of text that should be  supported respectively.

Following program explains you how to create and add TextArea into a container,

TextAreaDemo.java

import javax.swing.*;
import java.awt.*;
class TextAreaDemo extends JFrame
{
public TextAreaDemo()
{
setTitle("TextAreaDemo");
setSize(400,400);
setLocationByPlatform(true);
JPanel p=new JPanel();
JLabel lb=new JLabel("TextArea");
p.add(lb);
JPanel p1=new JPanel();
JTextArea area=new JTextArea(10,25);//Text Area of height 10 rows and width 25 Columns 
area.setLineWrap(true);
p1.add(area);
add(p,BorderLayout.NORTH);
add(p1,BorderLayout.CENTER);
}
} 
 
 

TextAreaMain.java


import javax.swing.*;
import java.util.*;
class TextAreaMain
{
public static void main(String args[])
{
TextAreaDemo Areademo=new TextAreaDemo();
Areademo.setVisible(true);
Areademo.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}


OUTPUT:



 



 As you see the above program it is very simple to create and add a textarea into a panel,but there are some important things that should be noted here, they are,

1. If you see this line  area.setLineWrap(true);  you can identify that Line Wrap is not supported in TextArea by default. So you have to invoke this method explicitly to include this feature into TextArea.

2. As i have said before, if the text to be displayed is more than the display size then the TextArea will grow until it reaches the window size and after that text would be clipped.

3. Like TextField, it also supports setText() and getText() methods to set and retrieve the text to/from the TextArea...



 

 

Java Object Serialization

What is meant by Object Serialization?


In General, Object Serialization refers to writing an object into a stream,you can consider a stream as a data structure used to store values. Mostly the stream used for object serialization is a FILE. The reverse process is called object deserialization i.e, reading the object from the stream.

Object serialization is useful when you want to store objects into a file like primitive data types are stored.



What do they actually meant by writing(storing) objects?

 Are we really writing the objects in to  a stream? The answer is certainly "no". Then what we are writing into a stream?.Actually we are writing the state of the objects,to put it simply 
"we are storing the non-static and non-transient fields of the class in to an external file".


Non-static field:


You could have known that a Non-Static field is a field(or variable) which is not preceded by the static modifier.

For example,  int a=10; 

You could have asked why a static field is not serialized by default?

The  reason is " If there is a non-static field in your class,then each object that you would create will have their won copy of that field but on the other hand if there is a static field then it will be shared by each object". So rather than serializing a static field for each object they(Sun Microsystems) could have left that.


Non-transient field:


Similar to Non-Static field, here the field is not preceded by the  transient keyword. What is its use? There are certain fields which cannot be serialized in java,and if you try to do so then Not Serializable Exception will be thrown.  So, in order to avoid this exception you have to use this keyword.

 Now  let's see how to serialize  and deserialize the object. If you want to serialize an object you need to use the ObjectOutputStream class of the java.io package as follows,

ObjectOutputStream os=new ObjectOutputStream(new FileOutputStream("primit.dat"));
os.writeObject(this);// Here "this" specifies the object to be serialized.
 
 Similarly for deserializing the object you need to use the ObjetInputStream class of the java.io package as follows,

ObjectInputStream is=new ObjectInputStream(new FileInputStream("primit.dat"));
SerializeDemo s=(SerializeDemo)is.readObject();
 
 
  what happens when you read object from the stream?

When reading(or Deserializing) the object,"we are not actually reading the object, a new object is re-constructed from the stream with the field values stored in it". Here i would like to highlight one thing, you all know that to construct an object we need the class definition and this applies even if you reconstruct the object i.e, when reading the object from the stream we need the actual class definition in the class path.

 

Program:

  
SerializeMain.java

class Serializemain
{
public static void main(String args[])
{
SerializeDemo p=new SerializeDemo();
p.execute();
}
}


SerializeDemo.java
 

import java.io.*;
import java.util.*;
import java.lang.*;
class SerializeDemo implements Serializable
{
String name;
int Mark;
int rollno;
public void execute()
{
try
{
Scanner in=new Scanner(System.in);
System.out.println("Enter the name:");
name=in.next();
System.out.println("Enter the marks");
Mark=in.nextInt();
System.out.println("Enter the rollno");
rollno=in.nextInt();
ObjectOutputStream os=new ObjectOutputStream(new FileOutputStream("primit.dat"));
os.writeObject(this);// Serializing the object
ObjectInputStream is=new ObjectInputStream(new FileInputStream("primit.dat"));
SerializeDemo s=(SerializeDemo)is.readObject();// Deserializing the object
System.out.println("Name:"+s.name);
System.out.println("Mark:"+s.Mark);
System.out.println("RollNo:"+s.rollno);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}


 Output:

Enter the name:
ganesh
Enter the marks
80
Enter the rollno
34
Name:ganesh
Mark:80
RollNo:34

 
 

Executing an RMI

How to execute a RMI program?


There are three steps involved in executing a RMI program,

1. Executing the RMI registry

2.Executing the server

3 Executing the Client


1)Executing the RMI registry



 In windows type in,

c:\>rmiregistry  and press enter key, then the RMI registry will  get started

 

2)Executing the server


Executing a RMI server is quite difficult for newbies. In my previous post RMI tutorial i told you that if a client requires a remote object then it will request the object from the RMI registry with a name.


 who is registering the remote object in the RMI registry?

The answer is server,  but when the server is registering the object it needs to provide the details about the location of the classes and interfaces that may be required  by the remote object. Otherwise javax.naming.communicationexception will be thrown. So in order to avoid this error you need to provide the location of the required classes using the codebase property.


There are two ways to do that,

Way 1:

 Here if you see the line,

java -Djava.rmi.server.codebase=http://localhost:80/ NameServer.




I am saying to the registry that all the required files will be available in the port 80 of this system  using the url http://localhost:80/ . Since i have implemented this in a single system i have done like this, but this will be more useful when the required files are available in another remote machine. At that time you have to specify the hostname of the remote machine in the url like as follows,

http://metallica:80/  if the host name is metallica.


Way 2: 

When all the required files are available in the server itself then you don't need to provide the url but you have to provide the location of the class files in the server like as follows


Since my class files are available in the location file:c:\blog\rmi1\downloads/  i have given like this, so during execution of the server all the required files will be downloaded from the given location.


Executing a client:


It is simple as executing the normal java program,say for an example java NameClient


 

Java RMI Tutorial

How to perform Remote Method Invocation in java


What is meant  by RMI?

Remote Method Invocation refers to invoking a method on an object which resides in a remote machine.For example, let's take the client/server model. In which the server is  usually a remote machine and the client invokes a method of an object which resides in the server to accomplish the required task.

Let us see what are the components needed  by us to perform  the RMI,

Server - A remote machine which serves us the requested operation.

Client - A machine that requests the server to perform some tasks on its behalf.

RMI Registry

In general, if you want to invoke a method of a class what do you actually need? an object of that class. If the class is available in your machine, then there is no problem for you to create an object of that class and invoke the method.

But in RMI the class for which you would like to create an object is not in your machine it is available in the remote machine i.e, the server. So you would need some means to get the object of that class(in the server). What to do? RMI registry has been created for this purpose.

Consider RMI registry as a book where in the objects needed by the clients are registered by the server with a name (in our case it is a RMI url) ,So if any clients needs  an object, it will request the RMI registry(book) with a name, then the RMI registry provides the object corresponding to that name to the client. Now client can access the methods.

 Stub - I would consider a stub as a cached copy of the remote object in the client machine. What is a remote object? An object of a class that implements the Remote Interface is called remote object.  

what do you meant by Remote Interface? An interface that extends the Remote Interface of the java.rmi package

Why should i need to extend the remote interface?

If you want to make a method to be remotely accessible then you should include this method in the interface that extends the Remote Interface.

For example,

import java.rmi.*;
public interface NameCollections extends Remote //Remote interface
{
public String getName(int index)throws RemoteException;//Remotely 
                                                                                                                                   accessible method
}


 A class that implements the Remote interface is like as follows:

import java.rmi.*;
import java.util.*;
import java.rmi.server.*;


class NameStorage extends UnicastRemoteObject implements NameCollections //A
                                                                                                    class that implements the remote interface
{
private Map name;
public NameStorage()throws RemoteException
{

name=new HashMap();
name.put(1,"Ganesh");
name.put(2,"jazz");
}
public String getName(int index)throws RemoteException
{
String str=name.get(new Integer(index));
return str;
}
}

 NameStorage name=new NameStorage(); //Here name is the remote object

Skeleton - It is exactly similar to the stub but it resides in the server machine, After java 1.2 the skeleton has been omitted. So let's leave this component.


Server


import java.rmi.*;
import javax.naming.*;
class NameServer 
{
public static void main(String args[])throws RemoteException,NamingException
{
Context ictxt=new InitialContext();
NameStorage store=new NameStorage();
ictxt.bind("rmi:Storage",store);//Binding the remote object(store) with a 
                                                                                           name(storage)
System.out.println("Clients can invoke the methods....");
}
}

Client


import java.rmi.*;
import java.util.*;
import javax.naming.*;
class NameClient
{
public static void main(String args[])throws NamingException,RemoteException
{
Context itxt=new InitialContext();
 
//Searching for the remote object in the RMI registry  
 
NameCollections coll=(NameCollections)itxt.lookup("rmi://localhost/Storage");
 
String n1=coll.getName(2);// Invoking the remote method
System.out.println("Name Obtained from the server:"+n1);
}
} 

Though it appears as invoking the remote method, it doesn't actually invoke the remote method, then what? It actually invokes the method on the stub object(which is available in the client machine).

This stub object would in turn  call the remote method which is available in the server and forwards the return value from the server to  the  client.


Since it is a lengthy post, i have dealt with the execution of the RMI program in another
 post How to execute a RMI program .  



JLabel - An Example

How to create and use JLabel

  
In java, labels are components used to hold the texts. A Label will look like "Text engraved   in the container(may be  a frame or panel)".

In general what is meant by a Label?


 A Label is a piece of a paper that provides information about the object to which it is affixed with. Similarly, here also the sole purpose of a label  is to provide information about the object  that cannot able to identify itself to the user.

Say, for  an example, In java,On seeing a button we can able to tell what it is intended to do, like NEXT, CANCEL, but a text field , text area cannot be able to describe themselves. So, in these kind of situations labels helps us to identify them.

Creating a Label 


In order to create a label,we need to create an object for the JLabel class by giving the text to be displayed as a label, like

JLabel l1=new JLabel("NAME");

JLabel l2=new JLabel(ADDRESS);


Program:

 

LabelDemo.java


import java.util.*;
import javax.swing.*;
import java.awt.*;
class LabelDemo extends JFrame
{
public LabelDemo()
{
setSize(300,300);
setTitle("LabelDemo");
setLayout(new FlowLayout(FlowLayout.CENTER,0,100));
setLocationByPlatform(true);
JPanel p=new JPanel();
JLabel l1=new JLabel("NAME :");
p.add(l1);
JTextField tf=new JTextField(20);
tf.setColumns(10);
p.add(tf);
add(p);
}
}


LabelMain.java


import java.util.*;
import javax.swing.*;

class LabelMain
{
public static void main(String args[])
{
LabelDemo ld=new LabelDemo();
ld.setVisible(true);
ld.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}


output:

 



In java, there is a facility available for us to either add an image , or an image along with the text into a label.Let's see how to add an image into a label.

JLabel l1=new JLabel(new ImageIcon("Nature.jpg"));

JLabel l2=JLabel("Nature",new ImageIcon("Nature.jpg"),SwingConstants.LEFT);


In tha above example, if you modify the Label creation statement like  as follows it will enable you to add  an image to a label.







JTextField - An Example

How to create and use JTextField 


In an user interface design,a text field provides a way to interact with the user either by prompting the user to enter an input  or by displaying some information in the textfield.

In this post we are going to see how to create a textfield and use it in our application.

To create a text field you need to create an object of the JTextField class in the javax.swing package as follows.

JTextField tf=new JTextField(20);

The argument value "20" in the above statement specifies the width of the TextField.

JTextField class has four constructors which are of great concern to us. They are...

1. JTextField tf=new JTextField() - creates a text field with width "0"

2. JTextField tf=new JTextField(int columns)-creates a text field with the given   
width.

3. JTextField tf=new JTextField(String str,int columns) ;

creates a text field with the given width and displays the string given in the first argument.

4. JTextField tf=new JTextField(String str)

creates a text field displaying the string with the length of the string as the size of the text field.


Programs

 

JTextFieldDemo

import java.util.*;
import javax.swing.*;
import java.awt.*;
class TextFieldDemo extends JFrame
{
public TextFieldDemo()
{
setSize(300,300);
setTitle("JTextFieldDemo");
setLayout(new FlowLayout(FlowLayout.CENTER,0,100));// used to center the panel in the 
                                                                                                                                                 frame   
setLocationByPlatform(true);
JPanel p=new JPanel();

JLabel lb=new JLabel("INPUT1");
p.add(lb);
JTextField tf=new JTextField();
tf.setText("Hi!Enter the input here.. ");
p.add(tf);
add(p);
}
} 
 
 

TextFieldMain

 
import java.util.*;
import javax.swing.*;

class TextFieldMain
{
public static void main(String args[])
{
TextFieldDemo tfd=new TextFieldDemo();
tfd.setVisible(true);
tfd.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
 


Output:





JTextField class has two important methods namely,

void  setText(String str) - to display a particular text in the text field say for an example,

JTextField tf=new JTextField(20);
tf.setText("Hai");
  
String getText ()-  to retrieve text from the particular text field like as follows,

String s=tf.getText();

You can also dynamically change the "size" of the text field using setColumns(int width).

for example tf.setColumns(10); will  provide a output like this,












javax.naming.communicationexception in RMI

When javax.naming.communicationexception will be thrown in RMI?


In java API, it is given that this exception will be thrown when the client is unable to communicate with the naming services.The reason for this exception may be due to server or client side failures.

In this post we will see how server-side failure causes this exception in RMI .

I guess you know about RMI(Remote Method Invocation) through which we can able to access the methods of a remote object. To execute an RMI application we need these components like,

1.Server

2.Client

3.Stub

4.Skeleton

5.RMI registry

Here we are going to focus on the stub, 

what is meant by a stub? 

It is a client-side object used to communicate with the server-side object(skeleton). The client needs to get a stub object.

 From where the client gets its stub object?

The client will get the stub object from the RMI registry, where the server would have already registered  a remote object with a name(RMI url).The client will use the name(RMI url) to get the stub object.


This problem arises when the server is unable to register( or bind) an object to a name (RMI url).

" The reason for this problem is that,when registering a remote object in the RMI registry we need to specify the "path" of the remote interface(in our example - NameCollections) implemented by the object and other components needed by that object, if any of the components needed is not available in the given path then this exception will be thrown."

 
 See the following example to understand about this exception.


Program:


Prog1:


import java.rmi.*;
public interface NameCollections extends Remote
{
public String getName(int index)throws RemoteException;
}


Prog2:

import java.rmi.*;
import java.util.*;
import java.rmi.server.*;

class NameStorage extends UnicastRemoteObject implements NameCollections 
{
private Map name;
public NameStorage()throws RemoteException
{
name=new HashMap();
name.put(1,"Ganesh");
name.put(2,"jazz");
}
public String getName(int index)throws RemoteException
{
String str=name.get(new Integer(index));
return str;
}
}
 
 
Prog 3: 


import java.rmi.*;
import javax.naming.*;
class NameServer 
{
public static void main(String args[])throws RemoteException,NamingException
{
Context ictxt=new InitialContext();
NameStorage store=new NameStorage();
ictxt.bind("rmi:Storage",store);
System.out.println("Clients can invoke the methods....");
}
} 
 
 

Output:


Screen1:

 



Screen2:



Here the NameServer program tries to register a remote object with the RMI url and when registering the object as i have said before we need to specify the path for required files. Here i  have tried to look for files in port:8080,but see what happens.

Have a look at the screen1, there i had executed a command like the following

java -cp . NanoHTTPD 8080 , implies that the server NanoHTTPD has to  serve the files in the port 8080, but if you see the screen 1 it says that the server is serving files from port 80.

I didn't noticed that and i have given the path as codebase= http://localhost:8080/  to look for files that's why i got this error?. 

So i have to change the command as follows codebase= http://localhost:80/ to resolve the above problem. I don't  know is there any problem in NanoHTTPD server or in my laptop.

"But an important thing to be noted here is the path that you provide should exactly point to the location where the necessary files are residing in the server."


In some cases, if you left the trailing slash in the command as given in the below line
 codebase =  http://localhost:8080   then you would get this error.





 

JButton - An Example

Creating a Button in JFrame


Buttons are one of the most commonly used components in any UI based application.In this post we are going to see how to create a button and how to assign a event handler to that button.


Creating a button in java is very simple and it involves four steps,

1.Creating the button

2.adding the button to the container(frame or panel)

3.creating the Listeners for buttons

4.associating those Listeners to the buttons

First Step,creating the button is as easy as follows

Jpanel p=new JPanel();
JButton button=new JButton("NEXT");
p.add(button);

Here you have to note one thing,simply creating a button will not register itself with the Event Listener and its your job to register a button with the Event Handler and to define actions that you desire when you click the button,

I have included a simple program that explains how to create buttons and registering with a Event handler

Program


Flowlayoutmain

import javax.swing.*;
class Flowlayoutmain
{
public static void main(String args[])
{
Flowlayoutdemo f1=new Flowlayoutdemo();
f1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f1.setVisible(true);
}
}


Flowlayoutdemo

import java.util.*;
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;


class Flowlayoutdemo extends JFrame
{
public Flowlayoutdemo()
{
setTitle("FlowLayoutDemo");
setLocationByPlatform(true);
setSize(400,400);
BorderLayout b=new BorderLayout();
setLayout(b);

JPanel p=new JPanel();
JTextArea ta=new JTextArea(12,35);
p.add(ta);
Border bo=BorderFactory.createEtchedBorder();
p.setBorder(bo);
add(p,BorderLayout.SOUTH);


JPanel jp=new JPanel();

//creating the buttons
JButton button1=new JButton("NEXT");
JButton button2=new JButton("CANCEL");

//adding the buttons to the panel
jp.add(button1);
jp.add(button2);
add(jp,BorderLayout.CENTER);

//creating the Listeners for buttons

BListener b1=new BListener("You have pressed NEXT Button",ta);
BListener b2=new BListener("You have pressed CANCEL Button",ta);

//associating those Listeners to the buttons
button1.addActionListener(b1);
button2.addActionListener(b2);

}
}

class BListener implements ActionListener
{
public BListener(String text,JTextArea a)
{
 txt=text;
 a1=a;
}
public void actionPerformed(ActionEvent e)
{
a1.setText(txt);
}
private String txt;
private JTextArea a1;
}

Output:



The first two steps seems to be very easy and so let's go to the third step

Creating the listeners

 What do you mean by listeners?,In general a listener is someone who listens to you when you do something(speaking,dancing..)

                   In this case,a listener is an object that listens to a button click.

Now,we need to create the Listeners(listener objects) for each buttons along with the actions that you desire.To create a Listener object,the class of the object must implement the ActionListener interface. 

So I have created objects for the class BListener which implements ActionListener interface and specified the actions that I would like to do.


BListener b1=new BListener("You have pressed NEXT Button",ta);
BListener b2=new BListener("You have pressed CANCEL Button",ta);

 Associating the listeners to  the buttons


After creating the listeners you have to associate them with the buttons using the addActionListener() method as follows,

button1.addActionListener(b1);
button2.addActionListener(b2);



ClassNotFoundException thrown when deserializing an object

classNotFoundException thrown because of deserialization

 

I guess you may all know about ClassNotFoundException which is thrown,when the class that we try to load(using forName() and loadClass()) is not available in the classpath. Note that this exception is different from the NoClassDefFounderror which is thrown when the SystemClassLoader  tries to load in the class that is not available. 

In both cases the cases one thing remains same, i.e, the class definition is not available in the classpath.

Here,this ClassNotFoundException is thrown  when deserializing an object. Lets see how?

Have you ever wondered what really happens when we serialize an object?You may have read that the state of the object is stored in the stream.What do they really mean by storing the state of the object?

Actually what happens is the values of non-static  and non-transient fields of the class, corresponding to the object that we serialize is stored in the stream in binary format.

When you try to deserialize an object we are not actually retrieving the objects from the stream.We are constructing a new object with the state information provided in the stream    ( i.e, field values stored in the stream).
  
 "we can  construct an object only if the class is available"

So at the time of deserialization we need the actual class to construct that object. Thus it is obvious that if the class is not available in the classpath then this exception would be thrown.

I have explained this with an example as follows.

Program:


 People


import java.io.*;
import java.util.*;
class People implements Serializable
{
String Name;
}
 

Employee


import java.io.*;
import java.util.*;
class Employee extends People
{
public static void main(String[] args) throws Exception{
People p=new People();
p.Name="ganesh";
ObjectOutputStream os=new ObjectOutputStream(new FileOutputStream("out.ser"));
os.writeObject(p);
}
}

 
 These two programs are  used to create an object of people and serialize it into the stream.

The following program tries to deserialize the people object from the stream and see what happens when the people class is not available in the classpath.


PeopleRead


import java.io.*;
import java.util.*;
class PeopleRead
{
public static void main(String args[])throws Exception
{
FileInputStream fis = new FileInputStream("out.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
Object o =ois.readObject();// throws ClassNotFoundException
ois.close();
fis.close();
}
}


Exception thrown:

 

Exception in thread "main" java.lang.ClassNotFoundException: People
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Unknown Source)
        at java.io.ObjectInputStream.resolveClass(Unknown Source)
        at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
        at java.io.ObjectInputStream.readClassDesc(Unknown Source)
        at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
        at java.io.ObjectInputStream.readObject0(Unknown Source)
        at java.io.ObjectInputStream.readObject(Unknown Source)
        at PeopleRead.main(PeopleRead.java:9)
 


Actually i have changed the classpath and compiled & executed it.As you see the line Object o =ois.readObject(); in the above program,it tries to read the state information from the stream and tries to reconstruct the object.Since the class definition is not available i got this exception. You may ask why the hell i am going to change the classpath. 

By the way you are not going to change the classpath, and these kind of exceptions will be thrown when you are dealing with Remote Method Invocation(RMI) where in,the class definition, may reside on the other virtual machine.

 
java errors and exceptions © 2010 | Designed by Chica Blogger | Back to top