The Coad Letter: Modeling and Design Edition, Issue 73, Building Enterprise Systems, by Stephen Palmer
Trying new technology is always cool. However, 'because it would be
cool' is not a sound basis for electing to use a technology on a project.
Technology should always be selected on its merits; what advantages/disadvantages
are there in using a particular technology. To put it another way; what
risk does a specific technology introduce/mitigate in a project?
Sun's Java 2 Enterprise Edition (J2EE) technology is a set of
services and API's aimed squarely at the enterprise information system
developer. One of the central components of the J2EE architecture is the
Java Bean (EJB) specification (currently at version 1.1). This month's
CoadLetter briefly looks at some of the fundamental services required when
implementing enterprise information systems and their implementation in
the EJB world.
Building Enterprise Systems
Building with components:
Component technology - building systems by plugging together ready-made
components instead of writing every object from scratch - is a goal to
which most in the software development world would subscribe.
For components to be pluggable they need to conform to a set of standards.
Nothing demonstrates this better than the differences between electrical,
electronic and telecommunication standards in different countries. Not
only are power and communication sockets and connectors different, voltages,
frequencies, protocols and storage formats also differ. For example, without
using adapters and converters, a television, video recorder or mobile phone,
etc., bought in the USA cannot be used in European countries and vice versa.
Enterprise Java Beans are just one such set of standards for building
software components for enterprise information systems.
Being able to buy off-the-shelf components to implement chunks of an
enterprise system reduces development time and cost.
Building your own in-house components that can be reused in multiple
systems actually increases initial development time because it requires
much more work to design and build a good component than to build a 'good-enough'
custom piece of code. The pay back comes only when components are re-used
in subsequent systems.
Few project managers are rewarded for delivering good components (or
even good maintenance documentation :-( ). The success of a component architecture
is therefore largely dependent on the production of off-the-shelf components
by third parties.
Another success factor is the services provided by the framework into
which the components are deployed. These can help reduce the amount
of work a developer needs to do to perform common tasks. The EJB specification
makes use of numerous standard Java API's to provide a rich set of services
Many business systems today use a relational database to store data when
it is not in main memory.
There are a number of design issues involved in mapping object oriented
information to relational database tables. These include mapping inheritance
hierarchies, retrieving collections of objects, managing concurrent transactions
and using object identifiers versus primary keys. As a result, a
number of significantly different proprietary products exist to help automate
the generation of object to relational mappings.
Enterprise Java Beans come in two distinct blends. Entity Beans are
the 'data centric' blend because they provide some help in manipulating
persistent data. A developer can specify an entity bean as using container
managed persistence or bean managed persistence. All entity
beans must implement a standard set of persistence-oriented operations.
For container managed persistence, the EJB container is responsible
for implementing these operations (normally referring to a mapping of attributes
to table columns supplied in XML files called deployment descriptors that
are packaged with an EJB). Bean managed persistence requires the
bean's developer to implement the standard operations (normally using Java's
JDBC API). Container managed persistence is usually restricted to
mapping a bean's attributes to columns in a single database table. i.e.
each entity bean represents one row in that table thus avoiding many of
the OO to RDBMS mapping issues. Anything more sophisticated is likely to
be specific to that vendor's EJB container and therefore not easily moved
to another vendor's EJB container - undesirable!
The result is data driven object models (yeuch) or difficulty in implementing
a non-trivial best practice domain object model using entity beans
and container managed persistence. In many cases the proprietary
persistence tools offer better solutions. Various attempts have been made
to overcome these shortcomings using the other blend of EJB, Session beans,
in conjunction with a proprietary persistence tool but none of these approaches
An enterprise system must manage communications between client machines
and server applications, between server applications on the same machine
and on different machines within an enterprise, and between the servers
of multiple enterprises.
EJB's use a number of standard Java API's to provide these services.
The JNDI naming service is used to find remote references to factory objects
used to create, retrieve and delete EJB's. The factory objects are remote
objects implementing an EJB's Home Interface.
The only way to invoke
an operation on an EJB is via it's Remote Interface. The RMI
over IIOP protocol and API are used for invoking operations on EJB's
via their remote and home interfaces. Again there is little new here except
a standardizing of the use of Home and Remote interfaces.
The implementation of the standard EJB Home and Remote interfaces pollutes
a Problem Domain class with a large amount of EJB specific code (yeuch
- but most distributed object architectures do similar things). Remote
objects also require artificially large grain operations to avoid large
numbers of network calls that result in poor performance (yeuch - but again
most distributed object architectures require the same).
Thankfully J2EE provides the JSP/Servlet API's and services that are
an excellent alternative approach to client/server communications when
menu-driven, form-oriented user interfaces are sufficient.
Probably the biggest advantage gained from using EJB's is its support for
declarative transaction management. It is no longer necessary to program
explicit transaction control using fairly complex API's like OMG's Object
Transaction Service, its Java implementation, JTS or your own API. Instead
transactional characteristics of objects are declared in deployment descriptors.
Nothing new again - Microsoft was here first with their MTS product.
Changing transactional behavior no longer requires changes to source
code. Objects of the same class can be deployed with different transactional
characteristics in different applications. The responsibility for correct
transactional behavior now falls to the assembler or deployer of the EJB's
instead of the developer. The developer does need to consider how her bean
might react with different transaction characteristics and code and test
appropriately; adding flexibility always adds to the number of paths that
need to be tested.
Declarative transaction management does little to help resolve isolation
level and pessimistic vs optimistic locking issues and these capabilities
can vary across application servers and databases.
Critical to any set of security services is the ability of the system to
establish the identity of a user. End-users of enterprise systems like
to have a single-sign-on where they provide confirmation of their identity
once. Most enterprise applications however, require a user to identify
themselves each time they start the application. This leads to multiple
user ids and multiple passwords (with different rules about what makes
a good password) per user - inconvenient for the user, a headache for system
administrators ... but heaven for that special breed of data security officer
that would prefer people did not use a system at all (thus keeping the
data completely secure) :-)
Authentication is not specified in either the EJB specification or the
J2EE client component specification. This makes this area subject to vendor
specifics. A common approach when using EJB's is to use the JNDI API to
provide authenticating information to access a server or resources on a
server. A future version of J2EE may require the use of the Java Authentication
and Authorization Service (JAAS).
Authorization is the ability of a system to restrict what each user can
see and do.
There are at least three variables in authorization of a non-trivial
User role based security assigns each user to one or more roles. Each role
is given specific permissions and/or capabilities. EJB's provide a declarative
role-based security mechanism. Each role is granted access to methods of
classes by declarations in deployment descriptors. However, method
level is often too granular and an administrative headache where multiple
methods exist to perform the same operation in slightly different ways.
In many cases, a role is allowed to see objects in a class or not, update
objects in a class or not and delete objects in a class or not - but this
level of granularity is not supported by EJB's.
More complicated security rules depend on whether or not the user owns
an object (maybe they created it, or they are assigned to a team that created
it). It gets even more complicated when access depends also on the state
of the object. For example, once submitted to a manager, an owner may not
be able to update their object anymore.
The only support provided by EJB's for this sort of authorization is
a container supplied method to inquire if a user belongs to a certain role.
Many organizations are looking at business rules engines to help manage
these more complex access rules.
Recording who did what and when they did it is a common requirement
within business systems especially where financial transactions are involved.
EJB's do not provide any specific help in this area and can be a distinct
hindrance given their restrictions on writing to files. The JMS messaging
API can be used to send messages to a logging service.
A general rule of thumb is, "The more generic a solution, the slower
the performance". EJB's are no exception. The overheads of the EJB
container services are significant.
Where user numbers and usage patterns benefit from EJB's resource management
capabilities this performance overhead may be offset. Specifically, EJB
containers may reuse instances from pools of objects to reduce the overhead
of creating and destroying objects. An EJB container may also unload (passivate)
and reload (activate) beans from/to memory to reduce memory usage. Obviously
different vendors EJB containers and servers perform differently making
the choice of vendor important (and the pain of switching vendor more likely
to be felt).
Another big issue with EJB's are the restrictions on writing re-entrant
code; that is code from bean A that calls bean B which then calls back
on bean A. Call backs are used in many popular OO design patterns but EJB's
currently make it hard to use call backs.
This has been a very short introduction to each of the enterprise system
services above. I hope to expand on each one in future issues with help
from my colleagues at TogetherSoft and your feedback.
Java's big claim was 'Write Once, Run Anywhere' and today it largely
lives up to that claim. However, EJB's do not! To run Enterprise Java Beans,
we are required to have an application server product written by a third
party vendor. The EJB 1.1 specification, although tighter than 1.0 still
allows for numerous variations between different vendors' EJB Containers
and application servers. Anyone who has had to switch application server
products during development knows that it is not straightforward. However,
as the standard matures this problem will hopefully decrease.
Much work remains before EJB's become a generic solution that meet 80%
of developers' needs. The biggest contribution EJB's and J2EE technology
are likely to make is the standardization of the interfaces to these commonly
Where it fits, EJB technology is there to be used today but, as always,
developers need to continue to pick the right tool for the job.