JavaBeans: The Perfect Roast?
By David S. Renshaw
Hursley Laboratory, IBM
Abstract
Java promises a truly open cross-platform execution environment for permitting
the creation of applications once with deployment everywhere. So far, this "write once, use
everywhere" technology has been restricted to programmers. However, the Java component
model, JavaBeans, will provide these benefits to real people, the non-programmers of the
world, finally fulfilling the promise of software component technology.
What is a JavaBean?
A JavaBean has been defined as "a reusable software component that can be manipulated
visually in a builder tool." A catchy definition that tells us little! There is a clue in the words
"...manipulated visually in a builder tool." Simply, a JavaBean is a software component.
What is a Software component?
The software industry has been talking about software components and how they will change
application development for some time, but it's often hard to find a definition of what they are.
Software components raise the level of software reuse, moving its emphasis from the level of the
skilled programmer to the level of the business application creator. Note this term "business
application creator." What it means is that software components can be assembled into
applications by people skilled in the business, but almost certainly not skilled in programming.
Think of a hi-fi system of separate components. Skilled electronics engineers build each
component: amplifier, CD player, speakers, etc., from small parts (integrated circuits, wires,
circuit boards, etc.). On the amplifier are user controls, on/off switches, volume control, etc.,
and, at the back, connections. The connections use different types of plugs for different functions
to stop me from plugging the speakers into the wrong CD input socket. As the user, I am
expected to be able to understand the controls and to work out which cable plugs in where. I do
not need to know how the electronic circuitry operates.
There are numerous similarities between a hi-fi system and the ideal of computer software built
from components. Consider an HTML page, to be delivered across the World Wide Web, which
allows me to select an item from a catalogue and to buy it using a credit card. The page must
contain a way for me to enter my credit card details, a way to indicate my product choice, and a
way to allow me to say "buy." In this ideal world, the page is created by somebody skilled in
publishing on the Web, not by a programmer. The publisher builds up the Web page and
includes on it three software components. One that takes credit card details, one that allows me
to select an item, and one that displays a button with the word "buy" on it. The publisher "wires"
the components together by connecting the "credit card details available" event from the credit
card component and the "product selection" event from the selector component to the "buy"
component. Now, when the user has entered his or her credit card details and selected an item and
clicked on the "buy" button, a request is sent to the Web server. The constructor of the HTML
page knows nothing of how the credit card component verifies its details or of how the
transaction component processes the request; the HTML author simply plugs the pieces together to provide the
desired end result: a functional Web page.
Why is a Java Component Model Important?
In my opinion, the promise of the Java environment is the software producer's nirvana: write it
once and execute it anywhere. The platform-independent nature of Java and its standardized
class library finally make it possible to develop a single version of an application and have it
execute on any Java-compatible system without the need for recompilation or addition of special
logic.
Components created with existing component models, such as Microsoft's ActiveX and
OpenDoc, do not meet the needs of cross-platform deployment. They exhibit a number of
problems:
The component is written in C or C++ and compiled to provide a platform specific executable.
It uses operating system-specific calls to do such fundamental things as rendering data to the
screen.
The resulting components are too big to use to create lots of small components, such as push
buttons, entry fields, text labels, etc. To create one of these components, the developer must
write numerous methods.
Even using the frameworks for component creation within the leading development
environments, the task is still not simple. Current components are often complete applications:
spreadsheets, drawing editors, word processors, etc.
The platform-dependent nature of existing components restricts their market coverage, making
the creation of components by small companies unattractive. The large application developers
are investing heavily in components for their chosen set of platforms, but this tends to be a small
set and the various platforms do not have a common component model. ActiveX is available
only on the Microsoft Windows platforms (even then a component compiled on an Intel
machine cannot be used on an NT system running on non-Intel hardware). OpenDoc is available
on Apple Macintosh, OS/2, and Windows, but again, one component executable does not fit all!
Existing components are installed and registered as part of the operating system. If this model is
extended to the World Wide Web, the security implications are extremely scary! An ActiveX or
OpenDoc component loaded dynamically as part of a Web page has access to the full range of
operating system interfaces and, therefore, once installed and registered, may do whatever it
pleases with the user's system. A Java component loaded from the Web executes within the Java
"padded cell" or "sandbox," where its access to the user's system can be strictly controlled and
where, by default, it can do no damage.
JavaBeans Objectives
Given the failings of the existing component models, some of the aims of JavaBeans are fairly
obvious. Here are a few of the targeted characteristics:
- Portable: Written in Java with no platform-native code.
- Lightweight: It should be possible to implement a component as small as a push button or as
large as a complete spreadsheet or word processor.
- Simple to create: It should be a simple job to create a Java component without implementing
countless methods. Creation should be possible with or without development tools. It should be
simple to migrate from a simple applet to a Java component.
- Hostable in other component models: It should be possible to use a JavaBean as a first-class
ActiveX, OpenDoc, or other component. A JavaBean may be contained within an ActiveX or
OpenDoc container, such as a word processor, and will behave exactly as if it were a native
component. Thus a JavaBean chart component can be embedded in a word processor document
to interact with a spreadsheet in the same document. The creator of the JavaBean need not
provide special logic to deal with being hosted in another environment, and, indeed, the bean
may not even know it is happening, because all communication and conversion is provided by a
"bridge."
- Able to access remote data: A Java component may use any of the standard distributed object
(JavaIDL or Remote Method Invocation) or distributed data (JDBC) mechanisms to access
remote data. In fact, a bean may use any of the standard environment facilities.
The 1.0 level of the JavaBeans specification came out in October, 1996, and the base supporting
technology is shipped as part of the Java Development Kit (version 1.1) that became available in
February, 1997. The Beans Development Kit (BDK) (version 1.0), which contains sample beans
with source code, was made available via the Web soon after the release of JDK 1.1. When the
1.1 version of Java becomes widely available, the scene will be set for widespread creation and
use of Java components.
The version 1.0 JavaBeans specification bucks the trend in Java specifications. For most areas of
the Java environment, the specifications are simply lists of class definitions and attendant
methods. The beans specification, however, is more of a set of programming rules and practices
and contains very little in terms of class definitions. This difference illustrates that JavaBeans are
truly an extension of the core Java environment and that the creation of a bean involves simply
using the available classes and interfaces in a particular way.
In the 1.02 version of Java, the only mechanism for raising, dispatching, and receiving event
notification was via the Abstract Windowing Toolkit (AWT) classes. This mechanism assumes
that the objects raising the events have some visible form on the computer screen; i.e., they are
user interface (UI) "widgets." The primary mechanism for communication between software
components is event notification. It is, however, wrong for a component to be derived from a UI
widget. Also, the existing AWT event mechanism is not suited for use by a visual builder tool
that needs to create links between event sources and event handlers dynamically.
The new event model, known as the "delegation" event model, requires the definition of a class
of event object, plus a "listener" interface. Within a class of event object, the subtypes, rather
than the subclasses of the event, may be delivered to particular methods defined in the listener
interface. This allows the logical grouping of events while also providing direct delivery of the
event to the appropriate method of the listener. In addition, the raiser of an event is required to
provide methods for allowing objects wishing to listen, to register, and to de-register
themselves. Only objects who have registered with an event source receive notifications.
An example of the use of the event model might look something like this:
Figure 1. Example of an event model
In this example, we define the BlobEvent class and the interface for listening for them, the
BlobListener interface. We have a class of objects that raises BlobEvent, the MySource class,
which provides the addBlobListener and removeBlobListener methods. Finally, we have a class
that wishes to receive BlobEvent notifications, the MyModel class, which implements the
BlobListener interface.
So what does all this new stuff buy me? The new event model avoids the need to subclass AWT
objects unnecessarily and makes it a simple matter for a visual builder tool to generate adapter
classes to perform the event-to-method mapping. For the programmer not using a visual
builder, Java provides "inner" classes to simplify the creation of adapters.
With the current AWT event model, an event-handler method receives every event raised. If I
wish to take some action on a mouseUp event, every mouseClick, mouseMove, keyUp, resize,
etc. event also flows through my event handler. With the new event model, only those objects
that explicitly register with an event source receive notification. Even then, they only receive the
particular group of events in which they have expressed an interest. Filtering is automatic.
Persistence
A persistence scheme permits a component to save its state and, subsequently, for the
component to be recreated. Using the persistence mechanism, a spreadsheet component can be
saved to a file, and, at some later date, opened up again with all its data, formulas, and other
settings intact. Alternatively, a set of components representing a whole document--word
processor pages with charts, spreadsheets, images, etc. all embedded--can be "flattened" and
then transported across the network and executed somewhere else. The JavaBeans persistence
scheme uses the object-serialization mechanism of the Java 1.1 environment to permit
components to be automatically flattened to an I/O stream and later resurrected. Component
creators need only implement the serializable interface to make their component persistent. The
persistent stream used may be a Java file, a network connection, or, more interestingly, a stream
provided by some other underlying component model. If a JavaBean component is contained
within an ActiveX or OpenDoc component, the bean is provided with a persistent stream via the
relevant "bridge," and this is mapped to the underlying component model persistence
mechanism. The act of adding the words "implements serializable" to the class definition of a
component implies that the component authors have thought about the implications of their
component being made persistent and resurrected rather than simply being created and
destroyed; i.e., they have considered the implications on initialization, transient variables, etc.
Customization
Customization is one of the new features of JavaBean components. Simply put, a bean creator
not only creates the runtime component, but also may optionally create a class of UI widget,
extending the java.awt.Component class. This UI widget then may be used to customize an instance
of the bean. With other component models, the development environment, visual builder, or
whatever must provide all the customization logic for the components it uses. The component is
not able to customize itself in any intelligent way. This can be extremely limiting.
A JavaBean component may be shipped with its own class of UI widget, capable of customizing
it intelligently. The development environment can permit customization of Java components
created anywhere. Builders simply look for the associated customizer class and create an
instance of it within one of its windows; they need to know nothing more.
Introspection
For Java components to be reusable in development environments, there needs to be a way to
query what a bean can do in terms of the methods it supports and the types of event it raises
and/or listens for. In the JavaBeans specification, this is termed introspection and is an
extension to the basic reflection mechanisms provided by the 1.1 version of Java.
The reflection mechanisms permit runtime queries to be made to find the class of an object and,
from this, the details of its publicly-available methods and variables. The bean's introspection
mechanism extends this by looking for the use of specific design patterns or, alternatively,
explicit specification of a component's capabilities. The creator of a component may specify
explicitly the capabilities of the component by creating an associated BeanInfo class. The use of
the BeanInfo class allows the author of the bean to expose only a selection of the public methods
and variables of the bean.
A BeanInfo class also is useful when reusing a piece of existing Java code as a component. The
existing implementation may not abide by the design patterns expected of a JavaBean, even
though it has all the capabilities necessary, and the default introspection mechanism will not
correctly identify the public interface of the bean. The programmer may create a BeanInfo class
detailing the method names to be used for getting and setting properties, etc., and thus override
the default introspection scheme.
Packaging
JavaBean components are usually packaged as JAR files. The JAR format allows the component
to be packaged as a single entity along with its supporting classes, such as customization
editors, BeanInfo, and resources such as icon graphics. Development environments must
understand the JAR format and use its manifest file information to identify the beans contained
within a JAR.
A JAR containing a JavaBean component also may contain a serialized version of the
component. If such a persistent instance exists, then it is used, in preference to creating a "new"
instance from the class, when the user asks for a component of this type to be created. This
allows the provider to ship a ready-to-go or customized version of the component.
For example: I am a system integrator providing a set of components to a client for use in
building the client's applications. As an integrator, I have a set of standard components, but they all
have a default look and feel, which has only my logo and color scheme. When I provide these
components to my client, I create customized versions, which use the client's company's standard color
scheme and include their logo (alongside mine, of course). To do this, I simply add a serialized
version of each component to the standard component JAR file. I ship the client the JAR files
with the additional serialized version included. Now, when the client's development
environment creates a new component while building an application, it uses the serialized, i.e.,
the customized version, rather than creating an instance from the class. Therefore, all the
components have the client's look and feel.
Conclusions
Until now, the component-creation industry has lacked a platform-neutral architecture. The
current architectures are tied to specific platforms requiring platform-specific binaries. While the
supply of components for the end user is certainly growing, the platform dependencies and
potential adverse interactions of components from multiple suppliers can be a severely limiting
factor.
Java's truly platform-neutral execution environment, coupled with a lightweight and simple
component model, JavaBeans, provides the potential for an explosive growth in the supply of
useful components. At last, a component supplier can actually create a single component that
can be deployed virtually everywhere. In addition, the built-in safety and security schemes of
the Java environment mean the chances of unfortunate interactions between components from
different suppliers is greatly reduced, and the component-based computing environment may
now span the network.
Some of the unique features of JavaBeans (customization, introspection, etc.) open up the
currently closed development environments. This, coupled with the dynamic download
capabilities of the Java environment, means it is no longer necessary to install every component
into the development environment and allows for dynamic extension of the palette of available
resources.
About the Author:
David S. Renshaw is an object technology specialist in the Centre for
Java Technology Development in the IBM Hursley Laboratory ( IBM
United Kingdom Laboratory, Hursley Park, Winchester, England). The
Centre is responsible for the porting of the Java environment to IBM
platforms. In addition, the Lab acts as a focal point for Java expertise
and future direction discussions. In this latter capacity, Dave's
responsibilities include object technology, component models,
multimedia and telephony. He joined IBM in 1984 after working for
several years as a Systems Programmer for engineering companies in
the UK. While with IBM, Dave has worked in a number of areas
including transaction processing systems, advanced text editors, and object oriented
languages (ObjectREXX). Prior to joining the Java team, he worked in computer
conferencing and collaboration systems.
|