In-Depth
J2EE Earns JAVA a Station in the Enterprise
- By Peter Fischer
- January 1, 2001
While java has gained significant acceptance as the object-oriented language
of choice for e-commerce and Internet-based applications, its acceptance as
a platform for enterprise computing has been lagging. Concerns about other capabilities
of the Java platform as a prime-time player in the enterprise computing game
have historically had many IS managers and CTOs cautious about betting the ranch
on Java as the platform on which to build and deploy the new generation of n-tier
app systems.
Building complex, distributed application systems is more than just having
a solid set of functional APIs readily available. Despite its solid set of APIs,
Java before J2EE was not "ready for prime time" when it came to enterprise computing.
Issues such as a consistent security model, transaction support, administration,
configuration and deployment raised doubts in the minds of potential adopters
about the applicability and usability of Java to solve real-world problems.
However, J2EE has quickly dispelled most of those concerns and has many of
those skeptics seriously considering and evaluating J2EE as "the platform."
Integrated services, combined with dynamic configuration and deployment capabilities,
have clearly entrenched Java in the high-stakes enterprise computing game. In
this article, I will take you on a grand tour of the total J2EE offering with
stops at various key points that will illustrate the power and applicability
of J2EE.
J2EE enables solutions for developing, deploying and managing n-tier server-centric
enterprise apps. It provides numerous capabilities, such as:
- A consistent and integrated API set;
- A consistent component model that extends to all processing tiers;
- Reusable components that can be customized to the runtime environment;
- A consistent and integrated set of enterprise services, including the ability
to configure them in the runtime environment dynamically without requiring
changes to processing logic;
- An architectural framework that allows for the creation of complex applications;
and
- Best practices and guidance in applying the framework to real-world problems.
Despite the obvious advantages, J2EE is more than just a "packaging" of Java-enabling
APIs. J2EE provides a framework for "allocating" component functionality and
code to the appropriate platform using the appropriate technology. It provides
developers and architects alike with a roadmap for how to appropriately apply
the range of Java technologies to real-world programming and architecture challenges.
J2EE consists of the J2EE platform, the J2EE Programming Model, J2EE Compatibility
Test Suite (CTS) and the J2EE Reference Implementation (RI). Before I go into
detail on the first two items, which are the core of J2EE from an application
development and architecture perspective, I will touch on CTS and RI. These
two elements provide the foundation for J2EE in terms of acceptance by the industry
at large.
The J2EE Compatibility Test Suite (CTS) is a suite of compatibility tests that
is used by vendors to validate and certify that their products are completely
J2EE-compliant. Vendors run this test suite on their platform implementations
to ensure that all APIs are supported correctly and that all constituent technologies
work together properly for a completely functional J2EE environment. Products
that carry the J2EE "stamp of approval" are therefore guaranteed to support
the complete set of J2EE technologies and functionality.
The J2EE Reference Implementation (RI) provides a minimal J2EE runtime environment
for J2EE applications and is used by both product vendors and developers. For
vendors, it defines the minimal operational environment or "gold standard,"
allowing vendors to determine what their platform implementations must do under
a particular set of application conditions. For developers, it is used to verify
the portability of their J2EE code base and to provide the standard platform
for running the CTS.
The J2EE platform
The J2EE platform is a consolidated set of Java technologies and APIs that
provide a standard platform for hosting J2EE applications. To connect the components
running across all the tiers of the J2EE model, the platform contains a standard
set of enabling and connectivity APIs. Table 1 lists the constituent APIs for
J2EE.
Historically, Java APIs have been delivered in dribs and drabs with no real
coordination between them. This was fine when the APIs were evolving in isolation.
With J2EE, however, the constituent APIs have "grown up" to become integrated
and dependent on each other for key functionality. For instance, early on there
was no requirement for Java Database Connectivity (JDBC) to support the Java
Naming and Directory Interface (JNDI) or transactions. The 2.0 release of JDBC
provides support for transactions and utilizes JNDI to store target datasource
names.
The key to creating a solid and foundational platform for enterprise computing,
as well as e-commerce-based computing, is a solid set of core services. More
importantly, these services have to be integrated across the platform. With
J2EE, services like security, transaction support, and naming and directory
are not "add-ons" — they are integrated across all tiers of the architecture.
Even though support for the Java Message Service (JMS) is not currently mandatory
for J2EE, I anticipate that most, if not all, J2EE application server vendors
will provide a JMS engine, if only to provide product discrimination and a key
purchase point. JMS supports connectivity and information exchange between Java
components in both point-to-point and many-to-many fashion, providing key messaging
service capabilities for complex and interactive Java apps. In that vein, JMS
is a key and vital element of e-commerce-based solutions, enabling information
exchange between partners on the supply chain.
J2EE security services are designed to ensure that only authorized users access
resources and components. The J2EE security model supports both authentication
and authorization facilities. For authorization, access control is provided
and controlled using an application's security domain, which is configured and
administered independently of application code.
Unlike other enterprise application models, which require platform-specific
security features in each app, J2EE's security environment provides declarative
access to security configuration and attributes. This allows security settings
to be configured outside of program code at deployment time and not at development
time. These rules are interpreted when the application components are deployed
in the runtime environment. In addition, J2EE requires that all app server and
platform vendors provide standard login mechanisms, eliminating the need for
developers to supply this logic.
The J2EE transaction model is a flat model, which means that a transaction
cannot have any child or nested transactions. J2EE takes the complexity out
of the transaction management process by implicitly handling many transaction
details, such as propagating transaction context and coordinating transactions
across multiple transaction managers. This is done by leveraging the methods
on the interfaces of the JTA.
However, it is important to note that the transactional capabilities of J2EE
are clearly tipped toward the business logic or Enterprise JavaBean (EJB) tier
— Web components (Java Server Pages [JSPs] and servlets) are not designed to
be transactional in nature. Transactional behavior should always be delegated
to an EJB, which can use one of two styles of transactional behavior: bean-managed
transaction demarcation or container-managed transaction demarcation. In the
former case, the EJB programmer takes responsibility for managing all aspects
of the transaction in program code such as transaction start, rollback and commit.
With bean-managed demarcation, the EJB container handles all transaction details
and operations, driven by instructions in the EJB's deployment descriptor. Session
beans can support both types, but they cannot be used at the same time.
J2EE naming services provide application clients, EJBs and Web components with
access to a JNDI naming and directory environment. J2EE components locate other
components by looking them up in a naming context, a hierarchically organized
collection of logical names that map to the physical location of the component.
This provides a structured and disciplined approach to managing and locating
objects in complex distributed environments, overcoming the chaotic and free-for-all
approach that typically occurs.
A J2EE component can access both system-provided and user-defined objects.
The names of system objects, such as JTA transaction objects, are stored in
a special naming context. In addition, J2EE allows a component to name user-defined
objects such as EJBs, environment entries, JDBC datasource objects and JMS message
connections. For JDBC datasource objects, this allows application code to locate
and open a database source based upon an easy-to-read logical name instead of
the often clumsy and usually long database URLs that were prevalent with JDBC
1.x.
Table
1: J2EE API thumbnail |
API |
Product |
Version |
J2SE |
Java
2 Standard Edition |
1.2 |
JSP |
Java
Server Pages |
1.1 |
Servlets |
Servlet
API |
2.2 |
RMI/IIOP |
RMI
over IIOP |
1.0 |
EJB |
Enterprise
JavaBeans |
1.1 |
JNDI |
Java
Naming and Directory Interface |
1.2 |
JTA |
Java
Transaction API |
1.0 |
JDBC 2.0
Extension |
Java
Database Connectivity |
2.0 |
JMS |
Java
Message Service |
1.0 |
JavaMail |
Java
Mail API |
1.1 |
JAF |
Java
Activation Framework |
1.0 |
A listing
of the constituent application programming interfaces (APIs) for J2EE. |
The J2EE Programming Model
The J2EE Programming Model provides a standard and extensible model for architecting,
building and deploying multi-tier, distributed, thin-client apps. J2EE is positioned
to be the platform for distributed computing supporting the architecting, development
and deployment of e-commerce systems as well as Internet-, intranet- and extranet-based
apps.
J2EE applications consist of three fundamental elements — components, containers
and connectors. Figure 1 illustrates the relationship between components and
containers. Containers provide all J2EE application components with the J2SE
platform APIs, which include both the Java Interface Definition Language (IDL)
and JDBC core enterprise APIs. In addition, support is provided for the APIs
listed in Table 1. Containers provide the execution environment for components
that run on all three processing tiers of J2EE — client, Web and server. These
containers are really a formalization of what we have seen in the various Enterprise
Java initiatives — browsers on the client side, servlet and JSP engines in the
Web middle tier, and EJB containers in the business logic middle tier.
Connectors sit under the J2EE platform and define a portable service-level
API to connect heterogeneous information systems and sources into a J2EE app.
These connectors provide the EAI functionality for the J2EE platform by allowing
processing assets stored in diverse EIS-tier systems — host-based systems, pre-packaged
apps and ERP systems such as Baan, PeopleSoft and SAP — to be accessed in a
consistent manner from middle-tier components.
The J2EE Programming Model partitions application components and models into
three logical tiers: client, middle and EIS, as shown in Figure 2. At the top
of the model is the client tier, which is composed of a combination of HTML
page-based clients and HTTP content-based clients. These clients interact with
components in the middle tier. These middle-tier components are either servlets
and/or JSPs in the Web tier, or EJBs in the business-logic tier. Middle-tier
components provide the underlying server-side processing capabilities of J2EE
apps. In the business-logic tier, business code packaged as EJBs executes in
an application server-based environment. At the bottom of the J2EE "stack" lies
the ultimate pot of gold, the EIS tier, which contains the key processing systems
and apps.
J2EE apps can be Web- or non-Web-based, allowing the user interface to be presented
as HTML pages, Java applets, Java-Beans or a combination of the three. For example,
HTML-based apps can be generated via dynamically generated HTML pages and forms.
More sophisticated application services will interact with first-tier clients
by exchanging business data directly. In this scenario, JSPs and servlets are
used to format and present this data in a way that is easy for J2EE clients
to consume and use. These clients can be both Java applets running in a Web
browser and Java technology-based programs (such as wireless or hand-held devices,
for example).
With HTTP content-based clients, advanced functionality is attained through
the use of client-side logic execution. In this case, raw information such as
eXtensible Markup Language (XML) is exchanged between the middle and client
tiers, while execution on the client is typically in the form of Java apps,
applets or JavaBeans. To support the plethora of browsers and their various
versions dynamically, J2EE provides the ability to load the runtime environment
dynamically using the Java plug-in.
Servlets and JSP components comprise the Web tier of a J2EE application. Servlets
are a portable way to deliver dynamic content, while JSPs provide a text-based,
presentation-centric approach to developing servlets. In the runtime environment,
JSPs are compiled into servlets that are then run in a Web container. Combining
JSPs with JavaBeans offers all the advantages of servlets with the added benefit
of separating content and display logic cleanly.
One key advantage to this approach is that content developers do not have to
be concerned with app logic, eliminating the need for presentation developers
to understand Java app code and the need for EJB developers to understand HTML
or presentation logic. This fits in with the roles associated with J2EE, which
I will discuss later. In addition, with this approach, Web templates can be
created easily, allowing a Web-based J2EE app with a consistent look and feel
to be created with minimal effort.
From my experience, I have noticed that a typical dilemma is determining how
to leverage JSPs and servlets, as well as deciding among the various approaches
and technologies to developing and packaging Web components. The advice and
guidance that I typically offer is that servlets provide a programmatic approach
to capturing functionality on the Web server. Servlets are used to capture code
that changes infrequently or that provides access to low-level functionality.
JSPs are used as a presentation-centric, declarative approach to binding dynamic
content with processing logic.
As we have seen, J2EE is more than just a collection of APIs that provide the
ability to create distributed Java systems. J2EE is positioned to be the foundation
of a complete application and architectural framework, providing the services
required to build e-commerce-based applications. A key component of this "architectural
blueprint" is the inclusion of a guide for architecting and building these applications.
This integrated set of documentation provides guidance and best practices for
architecting, designing and building n-tier distributed application systems.
The J2EE Blueprints component provides the "cookbook" for building well-architected
applications that leverage the J2EE product and technology set.
Assembling and deploying J2EE applications
As an integral element of J2EE's discipline, a set of six roles has been defined
to cover the range of activities that are performed in creating and deploying
a J2EE application system. These roles are product provider, application component
provider, application assembler, deployer, system administrator and tool provider.
The roles reflect the distinct and clear separation of product purchase from
development, deployment and administration. Most of these are derived from typical
industry usage and should be familiar to application development organizations.
The identification of such roles is not novel, but their formalization into
a platform such as J2EE is. An application component provider creates J2EE components
— such as Web components or EJBs — and packages them in archive files, while
an application assembler takes these packaged components and assembles them
into a complete J2EE app.
The deployer role entails deploying the complete J2EE application into the
runtime environment. This role is key because of the declarative nature of a
significant portion of J2EE functionality. For example, a deployer would be
responsible for setting all the attributes of an EJB deployment descriptor targeted
for a specific environment, including transaction and security attributes. The
system administrator is responsible for the day-to-day health of the J2EE system.
This person will typically utilize the administrative capabilities of the application
server environment to tune and optimize the J2EE runtime environment.
J2EE extends the deployment model we are familiar with from Java and EJBs,
with a few new acronyms thrown in. A J2EE application is packaged as an Enterprise
Archive (EAR) file, which is a standard Java JAR file. These EARs comprise one
or more J2EE modules and a J2EE deployment descriptor, as illustrated in Figure
3.
The creation of an EAR is a two-step process. In the first step, application
component providers create the constituent tier deployment modules — EJB, Web
and client modules. One key point to keep in mind is that each of the constituent
deployment modules is an independent deployable unit. The client components
are packaged as .jar files, while the EJBs are packaged in EJB-JAR files. A
new archive construct, the Web Archive (WAR file), contains all the elements
of the Web tier, including JSPs, servlets, HTML files and supporting Web files
(images, sound files and so on).
In the second step, the application assembler packages these modules into an
EAR file that contains the complete, deployable J2EE application. During this
step the application assembler edits deployment descriptors for each of the
constituent J2EE modules to link dependencies between components that are contained
within each archive as well as components in different archives. For example,
the JSP and servlets in the WAR file need to refer to the correct EJBs in the
EJB-JAR file.
Once the assembly step is complete, the EAR should be run through a J2EE verifier
tool (one is included in the J2EE SDK) to ensure that the contents are well
formed. While this verification is not a solid guarantee that the application
will behave correctly at runtime, the verifiers provide a significant number
of static checks to ensure that the deployment descriptor and the archive file
contents are consistent with the EJB, servlet, JSP and J2EE specifications.
Unlike earlier deployment descriptors, the J2EE deployment descriptor is XML-based
and consists of a series of name-value pairs that are organized in a hierarchical
manner. Deployment descriptors contain a variety of information, such as structural
information that describes the components that comprise the archive and assembly
information. Most important, a deployment descriptor contains attributes and
values that control the runtime behavior of the components stored in the archive.
For example, an EJB-JAR file contains entries and attributes that control the
security and transactional behavior of contained EJB components.
To be continued ...
As we have seen, the J2EE platform is a significant step in the evolution of
Java as a platform for enterprise computing. However, this is not the end of
the story. During the next year, improvements will be made in the platform to
tighten up some loose ends and to solidify J2EE as the platform for enterprise
computing. This includes the addition of JMS as a first-class API in the platform
and its integration with EJB as a core service.
Of more importance is the evolution of the EJB container with new enterprise-class
features that will enable it to become the standard execution environment for
components. The addition of key and core services to the container framework,
including inheritance, persistence and the ability to support dynamic relationships,
provides the foundation of an extensible and reliable execution environment
for J2EE applications.