-tiered enterprise.
If you thought Beans were merely a client-side toy, you may be surprised. This article looks at just what Beans are, what it's like to develop with them, what they can do now -- and what they'll be able to do in the future, as well as what role they can play in the enterprise.
Beans and ActiveX
For many of us, the most familiar component model is Microsoft's Windows-based ActiveX. By far, ActiveX dominates today's component market. ActiveX components and
JavaBeans are similar on the surface, but the real, functional differences between them are numerous and deep. I'll address these differences first.
A JavaBean is a software component written entirely in Java, or at least compiled from some source language to Java bytecode. A JavaBean might encapsulate the function of some part of the user interface (using Java's Abstract Window Toolkit [AWT], for example), or it might work as something without a visible representation (e.g., a server Bean). A component constructed according to the JavaBean recipe will execute on any system that provides a Java execution environment. In other words, JavaBeans are platform independent.
This is one of the major differences between ActiveX components and JavaBeans: ActiveX is a platform-specific model. An ActiveX component is written and compiled for a particular OS and hardware and uses OS calls. It runs only on the platform that it's built for. The only platform ActiveX components initially could be built for was
Windows, but Microsoft recently moved the ActiveX technologies to other platforms, such as the Macintosh and some Unix variants. However, ActiveX is still far from having support on all the platforms that are currently in widespread use.
Compared to ActiveX components, JavaBeans are lightweight. The encapsulation of function into a Java component does not cause code bloat, the executable objects are quite small, and the developer is not required to implement countless methods. Another significant difference between ActiveX components and JavaBeans is in their respective security implications (see the sidebar "Safe Beans").
There are additional areas where the advantages of the JavaBeans model are evident. One of these areas is DLLs. ActiveX components can be packaged in several different forms, but they are usually delivered as DLLs. As such, these components need to be installed, if only temporarily, into a user's system so that they can be executed.
Registering a control in a system has ef
fects on other applications executing on the system. For instance, Windows allows only one copy of a particular DLL to be loaded. If your browser downloads an ActiveX component that loads a DLL, that DLL is shared by all the processes that are running. If you start another application that uses the same DLL, it will be linked to the DLL already in memory. If the two applications need different versions of the DLL, problems can result. However, with JavaBeans executing in separable sandboxes (for more information about the Java sandbox, see the sidebar "Safe Beans"), this problem does not happen.
Cooking Beans
So Beans are cross-platform, small, and safe. But how do you create them? The answer: pretty easily. Essentially, a Bean is a Java class that abides by a few relatively simple rules and design patterns. The infrastructure for executing Beans is provided by version 1.1 of Java. What are the basic parts of a Bean that we are required to provide?
- Beans must have null constructors.
- Beans communicate with each other by raising and listening for events, so they must define event interactions.
- Beans must have persistence mechanisms.
- Beans must be easy and efficient to distribute.
- Beans must provide mechanisms that enable a visual development tool to work out what methods and events the Beans have.
Apart from these five features, there is nothing special about a Bean; you could just as easily build a Java applet or application. In fact, Bean development can be a little simpler because you don't need to worry about starting, stopping, or initializing. Here's a closer look at each of the above five characteristics.
Bean creation. You create a JavaBean by using either the new instruction or the static instantiate method on the java.Beans.Beans class:
MyBean Bean = new MyBean();
or
ClassLoader cl = this.
getClass().getClassLoader();
MyBean Bean =
(MyBean)Beans.instantiate
(cl,"xx.yy.MyBean");
The latter method is preferred. In order for this to work, the Bean must have a null constructor -- that is, a constructor with no parameters.
Why are there two ways to create a Bean? Because a new object is not always a new object when it's a Bean; Beans can be resurrected from a persistent data stream. If you are actually creating a new Bean and you know for sure that there's no possibility of there being a saved version, then you can use the
new instruction. In a normal case, though, you should use the instantiate method because it gives the system's infrastructure the chance to use a template-serialized Bean or the new instruction as appropriate. Using the instantiate method creates a Bean using the default constructor and then restores its state data to the way it was when it was stored.
Why is this a big deal? Because Beans are meant to be reused with as little programming as possible. If you're a solution provider and have a set of JavaBeans that you supply to your customers, you can use templates effectively.
For example, you can create your Beans with a particular look and feel (e.g., a nice shade of blue with a company logo). When you supply solutions to your customers, each wants its own look and feel. All you have to do is create an instance of your components, adjust a few properties (e.g., colors and logo image), and then save them back into the JAR file (more on these later) as templates. When your customers use your components in their applications, the template versions are used, so they always see their company's own look (see the figure
"Life of a Bean"
).
Bean events.
Beans
raise events
to show that something significant has happened -- for instance, a button push. Other Beans might listen for certain events to know when to perform their particular action.
JavaBeans employ the
delegation
event model, which is defined in the 1.1 version of Java. Events are defined in a Java cl
ass that extends
java.util.EventObject
. Beans listen to each other by implementing a listener interface and then registering themselves with a source of events. In practice, the visual application builder usually creates this listener-interface implementation.
Persistent Beans.
A persistence mechanism allows a Bean or a collection of Beans to be saved in a file or transmitted across a network. Persistence enables some neat capabilities. For example, you can create a complex compound document made up of text Beans, spreadsheet Beans, chart Beans, and so on. When you attach the document to an e-mail message, the message's receiver can resurrect the document and view or edit it further -- you basically send a lightweight application along with the data.
Beans use Java serialization mechanisms to provide persistence. In Java serialization, all the member variables of an object can be made persistent by the Java run-time -- even whole trees or networks of objects that refer to each othe
r. All the Bean creator needs to do is implement the
java.io.Serializable
interface. This is a simple task, as this interface contains no methods.
There is some work that needs to be done, though. Each member variable that should not, or cannot, be made persistent must be marked as transient. This instructs the serialization mechanism to ignore the field when making the Bean persistent and to create an uninitialized field when resurrecting the Bean.
Packaging Beans.
You package a Bean by putting it into a JAR -- a Java archive (another Java 1.1 addition). A JAR file is basically a Zip file with the addition of a
manifest
, a kind of table of contents. The JAR can contain not only the Bean's own class file but also other classes that the Bean uses, icons, graphics, internationalized text, and HTML-format help files. The whole thing can be installed or downloaded across the Web as a single HTTP request (a feature that reduces load times for Beans-based applications and applet
s).
Packaging in a JAR requires only the creation of a manifest file that indicates the name of the class that defines the Bean. Execute the JAR utility, with some suitably obscure incantations, and you're done. Unfortunately, the JAR utility is not the greatest of programs and will often just accept your command-line options, execute quietly, and then do nothing. It can take several attempts and rereads of the help information to get this seemingly simple piece of work completed.
Introspective Beans.
Introspection
refers to the way in which the public interfaces to a Bean. Methods, events raised, events listened for, and public properties can be discovered at run time. This is the information that a visual builder needs in order to be able to use a Bean. The Beans introspection mechanism builds on yet another base Java feature,
reflection
, which provides the capability to discover method information about a class. The introspection mechanism also searches for design patte
rns defined in the JavaBean specification so that the events raised and listened for can be deduced.
Sometimes it isn't appropriate to simply assume that all public methods are to be accessible to other users. You might want to explicitly specify which methods, events, and properties constitute the public interface of your component.
To do this, you create a BeanInfo class. BeanInfo allows complete control of the definition of the public interface to a Bean. If a BeanInfo class exists, it's the definitive source of interface information, and no attempt is made to use automatic introspection mechanisms. BeanInfo hides methods and properties even if they are accessible through public methods at the Bean-class level. This means the Bean can present one view of itself in an application builder and another when used as a simple Java class.
In addition, and very important, BeanInfo allows the reuse of Java code not originally designed as a Bean. Often, existing code does not abide by the JavaBeans
design patterns that identify public properties. A BeanInfo class can specify the names and types of a property and define the "getter" and "setter" method names. (You still have to provide code for the other features, such as persistence.)
These five features are the fundamental ones that most Beans define, although more complex Beans might define more exotic ones, such as customization or property editors. This might sound like a lot of work, but the use of a smart
development environment
can create the constructor, BeanInfo, and property fields; accessor methods; and JAR files with little effort on the part of the user.
Beans Everywhere
JavaBeans are not just execution-platform independent; they're also creation-platform, assembly-platform, and reuse-platform independent. You can build a JavaBean on one development platform and then assemble it into a solution using a different platform. Other users can reuse and extend your Bean using other tools running on othe
r platforms. And the solutions that use the Bean can be deployed and executed on any Java platform. This is true platform independence; no other component model comes close to it.
It's obvious why a JavaBean is independent of its execution platform: It's Java. But how is it able to declare independence from the development environment? Introspection and customization.
With a typical programming environment, you purchase your development tools and install them on your system (burning up acres of hard disk space in the process). After installation, you have a large library of classes and components available to be reused. The catch is that once you build a new component using a particular development environment, it isn't always easy to use or extend from within another environment. This is because each development environment creates its own protocols for event handling, property setting, and so on -- something that needs to be common among all components. In addition, the underlying support classe
s for each environment are often delivered as DLLs and are invariably different for different tools, so a component from one environment needs access to these classes wherever it goes.
The JavaBeans specification carefully details the event model that Java components are supposed to use when they are connected to each other. This means that whatever environment a Bean is built in, it can always raise and receive events from other Beans. In addition, JavaBeans use only the standard Java class libraries, so they have no hidden run-time dependencies. Thus, two potential major problems with JavaBeans are avoided.
Further, the Introspection mechanism of JavaBeans allows a builder environment to query everything about the runtime interfaces of a Bean. That means a JavaBean-capable development environment can accept and use any Bean.
Enterprise Beans
Probably the single biggest advantage of JavaBeans as a component model is its truly platform-independent nature -- not only in terms of the
execution platform, but also with regard to the development environments. And this isn't just a promise of future independence; it's a reality today on the platforms that now support the business systems of the world. The Java environment has become available on an enormous array of platforms in an extremely short period of time.
From the start, JavaBeans have been expected to be used not just in client systems but in back-end servers as well. The next wave of JavaBean technology will include extensions specifically targeted at these server systems.
Thus far, I've talked about building Beans. But what can you do with them? Obviously, they make great components for building user interfaces (just as ActiveX controls do). The newest wave of JavaBeans technology, called Enterprise JavaBeans, includes extensions specifically targeted at these server systems.
An Enterprise JavaBean is an encapsulation of a piece of business logic. It can be executed in an environment that supports transaction-proc
essing constructs. In fact, current transaction-processing environments, such as IBM's CICS, will support Enterprise JavaBeans in the future.
The basic structure of an Enterprise JavaBean is the same as that of any other Bean, but with a few wrinkles. First, the
Enterprise Bean
comes in a JAR, but with more information that defines its transaction-scope rules. The basic model for the Enterprise Bean is one of client and server, where communication between the client application (probably built with conventional Beans) and the Enterprise Beans executing in the server is via remote method invocation (RMI), the CORBA Internet Inter-ORB Protocol (IIOP), or the forthcoming RMI over IIOP.
For transaction-processing monitors to provide Enterprise Bean support, these Beans will likely have to abide by further rules that limit the things they can do. For instance, they have no AWT capabilities, so they are invisible Beans. Also, to ensure that Enterprise Beans cannot cause deadlocks o
r denial-of-service attacks within the server, the use of threads and synchronization will be limited. These are the kinds of limitations that current applications live with in transaction processors, so they shouldn't cause great problems; after all, this is a specialized environment.
Choosing Beans
People in the computer industry have been talking about the great advantages of software components for years, if not decades. Many developers already experience these advantages when they build applications with ActiveX controls.
However, selecting a component model for the creation of client-side applications has many implications, not the least of which is platform dependence. If you choose ActiveX as the client in a multitiered distributed-object solution, you have to grapple with introducing ActiveX-capable systems in many places. You must ask questions such as: How many of my existing systems support ActiveX technologies? How much will it cost to replace these systems with ActiveX-capab
le systems? Will I be choosing the appropriate hardware and OS platform for my solution, or is the choice of component model giving control to a single supplier? Do I want this kind of platform lock-in?
Heterogeneous networks of systems are a reality in today's business environment, yet the selection of the wrong component model for the client in an
n
-tiered solution could force a corporation to spend millions of dollars changing its back-end systems.
JavaBeans is not just a component model for the client; it holds the key to integrated,
n
-tiered solutions using the diverse array of platforms that make up today's critical business systems. In this light, the advantage of JavaBeans is obvious: platform independence -- independence from the development platform, independence from the execution platform, and independence from development tools.
Where to Find
Borland International, Inc.
Scotts Valley, CA
Phone: 408-431-1000
Internet: http://www.borland.com
IBM Corp.
White Plains, NY
Phone: 800-426-3333
Internet: http://www.ibm.com