What JavaBeans is, how it works, and why you want to use it
The Java Development Kit (JDK) 1.1 hit the streets in February, bringing with it a new API called JavaBeans. JavaBeans is the software component architecture for the Java language. Why should Java developers be interested in this component technology? In this article, weโll start with a brief explanation of component technology and why itโs useful in system architecture. Then weโll look at JavaBeans to see what features the Beans API provides. Weโll finish with a preview of a regular series of articles that will explain how the new core APIs work with and within Beans, and how to use the JavaBeans API to create your own software components.
What is software component technology?
Software components are to software what integrated circuits (ICs) are to electronics: โblack boxesโ that encapsulate functionality and provide services based on a specification. Software reusability has long been a holy grail of software engineering and a major goal of object-oriented programming. Software components are designed to be reusable, even interchangeable.
In the โold days,โ people experimenting with radio had to spend a lot of time building chassis, winding inductors, and wiring together smaller components to create amplifiers, filters, and oscillators. Today, these components come packaged as integrated circuits with inputs, outputs, and specifications that tell how each component works. The specification is a sort of contract between the creator of the component and its user, explaining how the component will behave in various circumstances. Combine these components correctly, and, voila!, you have a radio. (Or, voila!, a heart rate monitor or microwave oven. You get the picture.) If the component doesnโt perform to its specification, it is considered defective and can be replaced.
Software components give programmers the same benefits that the above components give to people building radios. They provide specific functionality that can be reused in different places. Any software component conforming to the same specification can be replaced with another that performs the same function โ without breaking the system. Programmers can then connect software components together to create different applications, just as an electrical engineer wires together components to create a new radio, heart rate monitor, or microwave oven.
What is a software component?
Software components hide implementation, conform to interfaces, and encapsulate data, just like classes do in object-oriented languages. So how do components differ from classes? The answer: Almost all software components are also classes. What makes them components is their conformance to a software component specification. The JavaBeans Specification is the document that describes what a Java class must do to be considered a โBean.โ Programmers (and, as importantly, integrated development environments [IDEs]) can depend on any class that advertises itself as a Bean to conform to the rules set out in the specification. If it doesnโt conform, the contract has been broken and the Bean is defective.
To make a class into a component, the programmer must add functionality to the class that has little to do with what makes the class useful. The only requirement to make a class into a Bean is that the class implement the interface java.io.Serializable. The Serializable interface is a new Java 1.1 feature. Serializable classes know how to package themselves into streams of bytes to be transmitted through networks or saved to disk, awaiting later reincarnation.
Interfaces and classes defined in the package java.beans allow a Beans developer to control how the Beans user (a programmer using a particular Bean) may set and get Beansโ properties, hook Beans up to communicate with other components, and ask a Beans to describe themselves. (More on all this later.) The component specification outlines how the component must implement these methods.
Given class files that contain Beans, a programmer can create instances of the Beans and connect them together to do useful work. Writing applications with software components instead of writing a traditional program is analogous to wiring together ICs to build a radio instead of using discrete components or rolling your own inductors. Whatโs more, IDEs can analyze Beans, determining their methods and properties, and make wiring Beans together as simple (in some cases, anyway) as drag-and-drop! (If you work through Sunโs Beans Tutorial, youโll see just how this works.)
Understanding JavaBeans gives a developer the knowledge necessary to use these new components as they become available. The concepts involved relate to many of the new (post-Java 1.1) features of the Java core. And whatโs most exciting, itโs now possible for a developer to turn existing classes into reusable software components that automatically integrate with Beans-aware IDEs.
What JavaBeans is, and what it does
JavaBeans is not a product, program, or development environment. It is both a core Java package (java.beans) that Beans may use to provided extended functionality, and a document (the JavaBeans Specification) that describes how to use the classes and interfaces in the java.beans package to implement โBeans functionality.โ The class specification is a part of the base release of Java 1.1, and so no additional software must be installed in order to use it. The addition of Beans required little change to the Java language per se, although several new and sorely-needed APIs were added to the core release to support Beans features. Reading the specification can be informative but soporific. Fortunately, itโs optional if you already understand how and why to use the JavaBeans package. Perhaps you already understand Beans through reading an entertaining and enlightening series of articles on JavaBeans in JavaWorld, for example.
JavaBeans turns classes into software components by providing several new features. Some of these features are specific to Beans. Others, like serialization, can apply to any class, Bean or otherwise, but are crucial to the understanding and use of Beans.
Software components have properties, which are attributes of the object. Customization is the process of configuring a Bean for a particular task. The new event handling scheme in Java 1.1 was created in part to ease communication between Beans. Beans may be dissected by IDEs or by other classes through a process called introspection. Beans may be persisted (i.e., serialized) into byte streams for transmission or storage, and persisted Beans may be packaged into โJAR filesโ to ease downloading and access. Finally, Beans have been designed to interoperate easily with legacy component technologies such as ActiveX and LiveConnect, and participate in transactions with Object Request Broker systems such as CORBA.
Letโs look at each one of these capabilities in a bit more depth.
Properties and customization
Properties, as noted above, are attributes of a Bean. Visual properties might include color or screen size. Other properties may have no visual representation: a BrowserHistory Bean, for example, might have a property specifying the maximum number of URLs to store. Beans expose setter and getter methods (called โaccessor methodsโ) for their properties, allowing other classes or IDEs to manipulate their state. The process of setting up a Beanโs properties at design- or runtime is called customization.
The developer has a great deal of control over access and modification of Beansโ properties. For a simple property, the developer writes a method called setProperty() and another called getProperty().
BarChart
For example, if youโre using a Java-enabled browser, you will see to the left an applet which uses a small class called BarChart. The BarChart is the colored bar between the two buttons. BarChart lacks only one thing to become a Bean: it doesnโt implement the interface java.io.Serializable (because most browsers donโt yet handle Java 1.1, and so the example applet would fail.)
With the exception of being Serializable, BarChart is a simple Bean, with just a very few methods. It has void setPercent(int pct), which floods the bottom pct percent of the bar with red. The method int getPercent() returns the current percentage stored in the Bean (this is the Beanโs state). The setPercent() method also calls repaint() if it changed the percentage, so that the visual representation of the object stays up-to-date.
The applet code calls setPercent(getPercent()+10) when the +10% button is clicked, causing the BarChart to increment its percentage (if itโs Percent is an example of a Bean property, with setter and getter methods named in accordance with the JavaBeans specification. As this series continues, we will transform this humble little BarChart into a useful software component that may be plugged into a variety of applications.
The value of an indexed property is an array. Indexed propertiesโ accessor methods receive and return arrays of values instead of scalars. Accessor methods may throw checked exceptions to report error conditions.
Sometimes itโs useful for an action to occur when a certain property of an object changes. Bound properties cause events to be sent to other objects when the propertyโs value changes, possibly allowing the receiver to take some action. So, a SpreadSheet Bean might be configured to tell a PieChart Bean to redraw itself whenever the spreadsheet data changes.
Often, certain values for properties are illegal, based on the state of other Beans. A Bean can be set up to โlistenโ to these constrained properties of other Beans, and โvetoโ changes it doesnโt like. For example, a nuclear reactorโs ControlRodArray Bean might want to interfere with someone trying to change the state of a DrainReactorCorePump Bean to ON if the control rods are pulled out. (Donโt try this at home. Probably no one should be using JavaBeans for such applications just yet.)
When a developer is connecting Beans together to create an application, the IDE can present a property sheet containing all the Beansโ properties and their current values. (A property sheet is a dialog box used to set and/or view properties, like what you get by selecting Optionsโฆ on a menu.) The developer sets the properties graphically, which the IDE translates into calls to the Beansโ setter methods, changing the Beansโ state. This customizes the Beans for the particular application.
Using lists of properties is not always the best way to handle customizing Beans. Some Beans have state that is too complex to be easily manipulated in this way. Other Beans would simply be cooler if there were a more intuitive way to set them up. Imagine the poor manager who simply wants to look at sales reports, and has to figure out what to type into the โRemote ODBC Data Sourceโ text box in a property sheet. Wouldnโt it be cooler if she could simply drag and drop a DataSource Beanโs icon (customized with the label โSales Data,โ of course) onto a DataConnection Bean, thereby configuring it automatically? A Beans developer can embed a property sheet into the Bean itself, and the IDE then uses this โcustomizerโ to customize the Bean.
The relevant classes for manipulating properties and customization are in the java.beans package.
Event handling
All of this interaction between Beans presupposes some way for them to communicate. JDK 1.1 defines a new event model that classes (not just Beans!) use to communicate. In fact, this new event model has found its way into one of Javaโs most widely-used packages: java.awt!
In the new event model, a class registers interest in the activities of another class by way of a listener interface. In effect, the target object (the interested party) tells the source object (the object of interest), โLet me know whenever so-and-so happens.โ When the so-and-so occurs, the source object โfiresโ an event at the target by invoking the targetโs event handler with a subclass of EventObject as the argument.
Events can be used to implement bound and constrained properties. In the PieChart and SpreadSheet example above, the PieChart โregistersโ interest in any change to the SpreadSheetโs (letโs say) DataList property. When the SpreadSheet is going to change its DataList property, it passes a DataListChangedEvent (subclassed from EventObject), indicating what changed, to every interested listenerโs event handler method. The target (PieChart) then examines the event, and takes appropriate action.
The nuclear reactor example works similarly; but in that case, the target vetoes the change by throwing an exception. Thus the world is saved from widespread radioactive destruction.
The EventObject class can be extended to create user-defined events. Classes can now define and use new event types to send messages to one another. This means that Beans running inside the same container may communicate by passing messages around. This helps uncouple dependencies between objects, which we know is A Very Good Thing.
User-defined (and other) events are derived from the class java.util.EventObject.
Introspection
The rather odd term introspection is Java-speak for the process of programmatically analyzing a classโs public methods and members. This process is also sometimes called discovery. The new reflection mechanism in the Java core, which can dissect an object and return a description of its contents, makes introspection possible. (Although Java may be reflective, even introspective, omphaloskepsis is still not part of the core distribution.)
Weโve already run across one application of this capability. Above, we described an IDE that could construct a list of Bean properties to present to a developer. How can the IDE know what properties a Bean has? The IDE discovers a Beanโs properties in one of two ways: by asking the Bean for a description of its properties, or by dissecting the Bean by introspecting it.
A typical IDE will start by asking a Bean for a BeanInfo object, which describes the Beanโs properties, among other things. The IDE will then use the BeanInfo object to construct a property sheet. (This is assuming the Bean doesnโt provide a customizer of its own.) If the Bean doesnโt know how to return a BeanInfo object, the IDE then introspects the Bean, and scans the list of methods for names beginning with set and get. It assumes (by convention) that these methods are accessors for properties, and creates a new property sheet based on the accessor methods that exist and the types of the arguments those methods take. So, if the IDE finds methods like setColor(Color), Color getColor(), setSize(Size), and Size getSize(), then it will create a property sheet with the properties Color and Size, and appropriately-typed widgets for setting them.
This means that if a developer simply follows the conventions for naming accessor methods, an IDE can determine automatically how to create a customization property sheet for the component.
The reflection mechanism that performs introspection is in the new language core package java.lang.reflect.
Persistence and packaging
Itโs often useful to โfreeze-dryโ an object by converting its state into a blob of data to be packed away for later use โ or transmitted through a network for processing elsewhere. This process is called serialization and is a new feature of the Java core.
One of the simplest uses for serialization is to save the state of a customized Bean, so that a newly-constructed Beanโs properties can be correctly set at run time.
Also, serialization is a mainstay of component technology, making possible distributed-processing schemes such as CORBA. If an object doesnโt have the information locally that it needs to perform its task, it can send itself to a Request Broker, which serializes the object and sends it elsewhere for processing. On the remote end, the object is reconstituted and the originally-requested operation is performed. This is also a way to realize load balancing (for expensive tasks, that is: serialization and deserialization often arenโt cheap).
Where do you keep a group of freeze-dried Beans that have been โpickledโ in this way? Why, in a JAR, of course! The JavaBeans specification describes a JAR file as a structured ZIP file containing multiple serialized objects, documentation, images, class files, and so on, with a manifest that describes whatโs in the JAR. A JAR file, containing many compressed small files, can be downloaded all in one piece and decompressed on the client end, making applet downloading (for example) more efficient. (JAR is pretty obviously a play on the Unix tar file format.)
The java.io package provides object serialization. The JavaBeans Specification describes the format of JAR files.
Interoperation
Some wag once said that the nice thing about standards is that there are so many to choose from. Component technologies are no exception. There are many existing systems based on OLE (or its latest incarnation, ActiveX), OpenDoc, and LiveConnect. JavaBeans has been designed to (at least eventually) interoperate with these other component technologies.
Itโs not realistic to expect developers to abandon existing investments in other technologies and reimplement everything in Java. Since the release of Java 1.1, the first Beans/ActiveX โbridgeโ kits have become available, allowing developers to link Beans and ActiveX components seamlessly into the same application. The Java IDL interface, which will allow Java classes to operate with existing CORBA systems, is due out this year.
While the Beans/ActiveX bridge and Java IDL are not part of the standard JavaBeans distribution, they round out JavaBeansโ capabilities as an industrial-strength, open technology for portable component software.
Conclusion
Weโve covered a lot of ground. In this article, youโve learned what software components are and why theyโre valuable. You then learned about the various properties of JavaBeans, including properties, customization, events, introspection, persistence, packaging, and interoperation with legacy component systems.
In the next article in this series, weโll get you started using JavaBeans, and look at Bean properties in depth: how they work, and how to make your Beans customizable. As we go along, weโll discuss the new Java core features that make Beans possible. Future articles in this series will delve into the details of the topics we discussed this month.


