Java Technology Home Page
A-Z Index

Java Developer Connection(SM)
Online Training

Downloads, APIs, Documentation
Java Developer Connection
Tutorials, Tech Articles, Training
Online Support
Community Discussion
News & Events from Everywhere
Products from Everywhere
How Java Technology is Used Worldwide
Print Button
 
Training Index

Java Beans Tutorial, Part 4
Making Beans Serializable

By Greg Voss, JavaSoft

[Tutorial Contents]

By adding serialization to a bean you allow it to save itself—to persistente—even after it has been customized in a builder tool.

In this lesson, you will add methods to NervousText03.java to write the beans state to disk and to read the bean back into memory from its serialized representation on disk. One of the important tricks involved is knowing what fields of the bean need to be made transient, in which case their state is not saved or restored. For example the state of a thread (running, stopped, waiting) cannot be saved and restored through serialization. Therefore any fields refering to threads must be marked as transient.

Step 1. Add import Statment for Serilization

Add the following lines at the end of the existing import statements.

import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
to the other import statements in NervousText03.java

It's also a good idea to add support for excptions that can occur while reading or writing a serialized bean to a file. Add the following import statment after the two you just added:

import java.io.IOException;

This should take care of any trouble your bean may have when reading the saved object's state from disk. The beginning of the file should now look like this:

package sun.beanbox.beans;
import java.awt.event.*;
import java.awt.Graphics;
import java.awt.Font;
import java.awt.*;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.IOException;

public class NervousText03 extends Panel 
  implements Runnable, MouseListener {
...

Step 2. Make thread Fields transient

Any thread fields declared inside a class whose instances are to be serialized must be marked as transient. This is because at the time a serialzed bean is reinstaniated, the original context under which the program was running no longer exists. There are other types of objects which can not be serialized. They too must be marked as transient. Refer to documentation on object serialiazation for details.

Following this requirement, the killme in NervousText03 must be marked as transient. Change the line

  Thread killme = null;
to
  transient Thread killme = null;
You can't save the context of a thread and reload it in the same state because the thread's state depends on the runtime environment.

The instance fields declared in NervousText03 now look like this.

public class NervousText03 extends Panel 
  implements Runnable, MouseListener {
    
  char separated[];
  String s = null;
  transient Thread killme = null;
  int i;
  int x_coord = 0, y_coord = 0;
  String num;
  int speed=35;
  int counter =0;
  boolean threadSuspended = false; //added by kwalrath
  boolean lefttoright = true;
  ...

Step 3. Add Serialization Methods for Persistence

Now you're ready to add the writeObject and readObject serialization methods to NervousText03. When writing the object you can determine whether the NervousText bean is running or not. When reading the serialized representation of the bean back into memory you must initialize the thread again.

Add the following definitions for writeObject and readObject at the end of the class.

  private void writeObject(ObjectOutputStream s)
    throws IOException
  {
    s.defaultWriteObject();
    if(killme == null)
      s.writeBoolean(false);
    else
      s.writeBoolean(true);

  }


  private void readObject(ObjectInputStream s)
    throws ClassNotFoundException, IOException
  {
    s.defaultReadObject();
    if(s.readBoolean()==false)
      killme=null;
    else
      start();
  }

Step 4. Build the JAR and Install it in the BeanBox

Compile NervousText03.java:

  javac -d . NervousText03.java

Create the mainfest:

  echo "Manifest-Version: 1.0" > manifest.tmp
  echo "" >> manifest.tmp
  echo "Name: sun/beanbox/beans/NervousText03.class" 
    >> manifest.tmp
  echo "Java-Bean: True" >> manifest.tmp
The resulting temporary manifest file should look like this:
  Manifest-Version: 1.0

  Name: sun/beanbox/beans/NervousText03.class
  Java-Bean: True
Create the JAR file:
  jar cfm NervousText03.jar manifest.tmp 
    sun/beanbox/beans/NervousText03.class

Remove the temporary manifest and install the JAR in the BeanBox jars directory (substituting your BDK installation directory for BDK_HOME:

  rm manifest.tmp
  cp -p NervousText03.jar BDK_HOME/beans/jars

Step 6. Test NervousText03 in the BeanBox

To test that serialziation is working, first build a simple application by performing the same steps in the BeanBox that you did in the previous lesson. Run the BeanBox by switching to your BDK_HOME/beans/beanbox directory. Invoke run.sh (UNIX) or run.bat (Window/DOS). Select an OurButton bean from the menu and place it in the BeanBox. Select a NervousText03 bean from the menu, placing it in the BeanBox below the button.

Use the Edit menu to choose Edit->Events->action->actionPerformed. Join the event line to NervousText03 by clicking over the NervousText03 component. When the EventTargetDialog appears, select the changeDirection method and click on the OK button. Pressing OurButton should now cause the text displayed by the NervousText03 button to be reversed from right to left.

Change the text property of NervousText03 to read "Anxious Text". Do this by selecting the Press the OurButton, to reverse the order of the text so it displays backwards. You're now ready to save the serialized state of all components displayed in the BeanBox.

Serialize the BeanBox components by choosing the menu item File->Save. A file dialog box appears to let you specify the file name for the application. Enter NervousText03.beanbox for the filename and press OK. The BeanBox application has now been serialzed and saved to disk.

Be aware that this is not a true application since it will run only in the BeanBox. However the same steps would be performed to create a real application in a beans-enabled builder tool.

Clear the BeanBox. Choose the menu item File->Clear. All components should disappear. You're now ready to reload the application. Choose the menu item File->Load. A Load File dialog appears. Select NervousText03.beanbox from the Files pane and press OK. The application appears exactly as it did when you saved it.

Step 7. Reheating Your Flambee

Notice when the saved file is restored, the text is reversed and is set to the same string you specified in the property sheet editor. Also notice, that the application comes up in a running state. That's because NervousText03 simulates the saving of the bean's thread state by appending the value of the boolean variable, killme at the end of the serialized output stream when the bean is serialized to disk. It does this by calling writeBoolean on the ObjectOutputStream used to serialze the bean with an argument of either true or false, depending on the value of killme:

  private void writeObject(ObjectOutputStream s)
    throws IOException
  {
    s.defaultWriteObject();
    if(killme == null)
      s.writeBoolean(false);
    else
      s.writeBoolean(true);

   }
Because the thread was running when you saved the application, the code to reinstantiate the bean in readObject gets a value of true when it calls readBoolean immediately after reinstantiating the bean with defaultReadObject. Here's the full definition:
  private void readObject(ObjectInputStream s)
    throws ClassNotFoundException, IOException
  {
    s.defaultReadObject();
    if(s.readBoolean()==false)
      killme=null;
    else
      start();
  }
If killme was true when the bean was saved, the bean's start method is called to reactivate the bean when it is reinstantiated. Had you saved out the appplication with the thread suspended, the thread would not run when you reinstantiated the bean. This is what Calvin is talking about when he says you need to relight the fire get the flambee heated again. As an exercise, try adding two more OurButtons. Label them "stop" and "start". First label the existing button "change direction."

You'll have to figure out how to hook up the action events generated by the start and stop buttons to the appropriate handlers to start and stop the thread in the NervousText03 bean. If you need a hint, go back and review how this was done with the original OurButton used to change the text's direction. Now stop the application by pressing the stop button, serialize it, clear the bean box and reload it. Then press the start button and try the exercise again.


Program Source Code

The makefile for this lesson automates source code compilation, JAR file construction, and copying of JAR files to the appropriate BeanBox directory. You'll have to edit several of the variables in the makefile to indicate the location of your JDK 1.1 and BDK installation directories.

You may want to look at the final source file for NervousText Bean, Version 03 to verify the changes you have made to the original NervousText.java file.


Print Button
[ This page was updated: 21-Sep-2000 ]
Products & APIs | Developer Connection | Docs & Training | Online Support
Community Discussion | Industry News | Solutions Marketplace | Case Studies
Glossary | Feedback | A-Z Index
For more information on Java technology
and other software from Sun Microsystems, call:
(800) 786-7638
Outside the U.S. and Canada, dial your country's AT&T Direct Access Number first.
Sun Microsystems, Inc.
Copyright © 1995-2000 Sun Microsystems, Inc.
All Rights Reserved. Terms of Use. Privacy Policy.