The results of using J2EE in practice are often disappointing -- applications are often slow, unduly complex, and take too long to develop. I believe that the problem lies not in J2EE itself, but in that it is often used badly. Many J2EE publi- cations advocate approaches that, while fine in theory, often fail in reality, or deliver no real business value.
In this book I offer a real-world, how-to guide so that you can make J2EE work in practice. I draw on my experience of designing successful high-volume J2EE applications and salvaging failing projects, as well as intimate knowledge of the J2EE specifications.
I'll help you to solve common problems with J2EE and avoid the expensive mistakes often made in J2EE projects. I will guide you through the complexity of the J2EE services and APIs to enable you to build the simplest possible solution, on time and on budget. I take a practical, pragmatic approach, questioning J2EE orthodoxy where it has failed to deliver results in practice and instead suggesting effective, proven approaches.
Introduction
J2EE Myths
How is this Book Different?
My Approach
Who this Book is for
Aims of this Book
What this Book Covers
Assumed Knowledge
Recommended Reading
What You Need to Use this Book
Chapter 1: J2EE Architectures
Goals of an Enterprise Architecture
Deciding Whether to Use a Distributed Architecture
New Considerations in J2EE Design
When to Use EJB
Implications of Using EJB
Questionable Arguments for Using EJB
Compelling Arguments for Using EJB
Arguments for Using EJB to Consider on a Case-by-Case Basis
Accessing Data
J2EE Data Access Shibboleths
Entity Beans
Java Data Objects (JDO)
Other O/R Mapping Solutions
JDBC
State Management
J2EE Architectures
Common Concepts
Architectural Tiers in J2EE Applications
The Importance of Business Interfaces
Non-distributed Architectures
Web Application with Business Component Interfaces
Web Application that Accesses Local F_JBs
Distributed Architectures
Distributed Application with Remote EJBs
Web Application Exposing Web Services Interface
Web Tier Design
The Model View Controller (MVC) Architectural Pattern
Connectivity Between the Web Tier and Business Objects
Designing Applications for Portability
Summary
Chapter 2 J2EE Projects: Choices and Risks
Developing a Policy on Specification Versions
Choosing an Application Server
When'to Choose an Application Server
Defining the Requirements
Evaluation Criteria
Supported Specifications
Sun Resources
Cost
Vendor Relationship
Vendor Viability
Development and Deployment
Value-added Features
Quality of Documentation
Availability of Skills
User Experience
Choice Process
Top Mistakes in Choosing an Application Server
The "Neat Technology" Trap
When to Use Alternative Technologies to Supplement J2EE
Portability Issues
What does Portability Mean?
A Pragmatic Approach to Portability
Staging Environments and Release Management
Building a Team
Team Structure
Who Owns the Architecture?
Vertical or Horizontal Responsibility
Choosing Development Tools
Visual Modeling Tools
IDEs
Build Utilities
Code Generators
Version Control
Identifying and Mitigating Risks
Summary
Chapter 3: Testing J2EE Applications
What Can Testing Achieve?
Definitions
Testing Correctness
The XP Approach to Testing
Writing Test Cases
What Makes a Good Test Case?
Recognizing Test Case Authoring and Maintenance as a Core Task
Unit Testing
main() Methods
Using JUnit
Test Practices
Should Testing Strategy Affect How We Write Code?
Integration and Acceptance Testing
Testing Business Objects
Testing Business Objects Implemented Without Using EJB
Testing EJBs
Testing Database Interaction
Testing Web Interfaces
Unit Testing Web-Tier Components
Acceptance Testing Web Interfaces
Design Implications
Testing Performance and Scalability
Load Testing EJBs and Other Business Objects
Load Testing Web Interfaces
Automating Tests
Complementary Approaches to Testing
Summary
Chapter 4: Design Techniques and Coding Standards for J2EE Projects
O0 Design Recommendations for J2EE Applications
Achieving Loose Coupling with Interfaces
Prefer Object Composition to Concrete Inheritance
The Template Method Design Pattern
The Strategy Design Pattern
Using Callbacks to Achieve Extensibility
The Observer Design Pattern
Consider Consolidating Method Parameters
Exception Handling - Checked or Unchecked Exceptions
Good Exception Handling Practices
Exceptions in J2EE
Making Exceptions Informative
Using Reflection
Reflection idioms
Using JavaBeans to Achieve Flexibility
Avoid a Proliferation of Singletons by Using an Application Registry
Refactoring
Coding Standards
Start from the Standard
Allocation of Responsibilities
Avoid Code Duplication
Avoid Literal Constants
Visibility and Scoping
Public Instance Variables
Protected and Package Protected Instance Variables
Method Visibility
Variable Scoping
Inner Classes and Interfaces
Using the final Keyword
Method Overriding and Final Methods
Final Classes
Final In~tance Variables
Implementing toString0 Methods Useful for Diagnostics
Defensive Coding Practices
Handle Nulls Correctly
Consider the Ordering of Object Comparisons
Use Short-circuit Evaluation
Distinguish Whitespace in Debug Statements and Error Messages
Prefer Arrays to Collections in Public Method Signatures
Documenting Code
Logging
Choosing a Logging APl
Logging in the EJB Tier
Why (and How) Not to Reinvent the Wheel
Help! APl Overload
Using Frameworks
What Makes a Good Framework?
Benefits of Using Existing Frameworks
Evaluating Existing Frameworks
Implementing your own Framework
Summary
Chapter 5: Requirements for the Sample Application
Overview
User Populations
Public Internet Users
Box Office Users
Administrators
Assumptions
Scope Limitations
Delivery Schedule
Internet User Interface
Basic Workflow
Error Handling
Application Screens
Welcome Screen
Display Show Screen
Book Seats Screen
Show Reservation Screen
Payment Details Screen
Confirm Reservation Screen
Box Office User Interface
Non-Functional Requirements
Hardware and Software Environment
Summary
Chapter 6: ADDIVing J2EE Technologies
When is a Distributed Architecture Appropriate?
Distributed Applications and Scalability
Distributed Applications and Reliability
Scalable and Robust Architectures
High-level Architecture for the Sample Application
Deciding When to Use EJB
Using EJB to Implement a Distributed Architecture
Transaction Management
Transaction Management in J2EE Applications
Transaction Management and EJB
Transaction Management in the Sample Application
EJB and Authorization
EJB and Multi-threading
Declarative Configuration Management
The Downside of EJB
So Much Infrastructure
Programming Restrictions Applying to EJBs
The Singleton Problem in FIB
Timer Functionality
EJBs in the Sample Application
Deciding How to Use EJB
What Should EJBs Do?
When to Use Local or Remote Interfaces
Does it Make Sense for a Bean to Have Both Local and Remote interfaces?
Phony Remote Interfaces
EJB Interface Summary
Using EJBs in the Sample Application
Deciding when to Use Asynchronous Calling with JMS
Message-Oriented Middieware (MOM) and JMS
Producing Messages
Consuming Messages
Consuming Messages without Using EJB
Consuming Messages with Message*Driven Beans (MDB)
When to Use Asynchronous Calling
Indications for Using Messaging
Disadvantages of Using Messaging
JMS and Performance
Alternatives to JMS Messaging
JMS in the Sample Application
Authentication and Authorization
The Standard Security Infrastructure
The Server Implementation
Deciding When to Use XML
Using XSLT in J2EE Applications
"Deep" Use of XML
Converting Between JavaBeans and XML
J2EE and XML in the Future
XML in the Sample Application
Caching to Improve Performance
Caching Options
A Caching Strategy for the Sample Application
Summary
Chapter 7: Data Access in J2EE Applications
Data Access Goals
Business Logic and Persistence Logic
Object-Driven and Database-Driven Modeling: A Philosophical Debate
O/R Mapping and the "Impedance Mismatch"
The Data Access Object (DAO) Pattern
Working with Relational Databases
Referential Integrity
Stored Procedures, Triggers, and Views
RDBMS Performance Issues
RDBMS Performance Tuning
Denormalization
Portability Versus Performance
Exchanging Data in Distributed Applications
The Value Object J2EE Pattern
"Generic" Value Objects
"Disconnected" Data Access Using JDBC Rowsets
Common Data Access Issues
Transaction Isolation
Pessimistic and Optimistic Locking
Primary Key Generation Strategies
Sequence Entity Bean
Unique ID Generation in Java
Database-Specific ID Generation
JDBC 3.0
Where to Perform Data Access
Data Access in the EJB Tier
Entity EJBs
Session EJBs and Helper Classes
Data Access in the Middle Tier without Using EJB
Data Access in the Web Tier
Servlets and Web-Specific Classes
Data Access from JSP Pages
Summary
Data Modeling in the Sample Application
Chapter 8: Data Access Using Entity Beans
Entity Bean Concepts
Definition
How Should We Use Entity Beans?
The Granularity Debate
The Business Logic Debate
Session Beans as Mediators
CMP Versus BMP
Entity Beans in EJB 2.0
Local Interfaces
Home Interface Business Methods
EJB 2.0 CMP
Basic Concepts
Container-Managed Relationships (CMR)
EJB QL
Limitations of O/R Modeling with EJB 2.0 Entities
Custom Entity Behavior with CMP/BMP Hybrids
Entity Bean Caching
Entity Bean Locking Strategies
Exclusive Locking
Database Locking
Read-only and "Read-mostly" Entities
Transactional Entity Caching
Entity Bean Performance
Tool Support for Entity Beans
Summary
Chapter 9: Practical Data Access
Data Access Technology Choices
SQL-Based Technologies
JDBC
SQU
O/R Mapping Technologies
Established Commercial Products
Java Data Objects (JDO)
Choosing a Data Access Strategy for the Sample Application
JDBC Subtleties
Correct Exception Handling
Extracting Information from SQLExceptions
The PreparedStatement Question
A Generic JDBC Abstraction Framework
Motivation
Aims
Exception Handling
A Generic Data-Access Exception Hierarchy
Converting JDBC Exceptions to Generic Exceptions
Two Levels of Abstraction
A Framework to Control JDBC Workflow and Error Handling
"Inversion of Control" Revisited
The com.interface21jdbc.core package
Using the JdbcTemplate Class
A Higher Level of Abstraction: Modeling RDBMS Operations as Java Objects
Implementation of the com.interface21.jdbc.object Package
Using the JDBC Object Abstraction
JDBC Abstraction Summary
Implementing the DAO Pattern in the Sample Application
Summary
Chapter 10: Session Beans
Using Stateless Session Beans
Benefits of Stateless Session Beans
Stateless Session Beans and Internal State
Implications of Stateless Session Bean Pooling
Using Stateful Session Beans
Why Not to Use Stateful Session Beans
Performance and Scalability Issues
Reliability Issues
When to Use Stateful Session Beans
Session Synchronization
Protecting Stateful Session Beans from Concurrent Calls
Patterns for Achieving Stateful Functionality with SLSBs
Object Parameter
Using a "Required Workflow Exception" to Mimic an SFSB State Machine
Using a Stateful Session Bean as Controller
J2EE Design Patterns Applicable to Session Beans
The Session Fa(;ade Pattern in Distributed J2EE Applications
The EJB Command Design Pattern
Implementing the EJB Command Design Pattern
Advantages and Disadvantages of the FJB Command Design Pattern
Using Commands without Adopting the Command Design Pattern
Session Bean Implementation issues
Error Handling in EJBs
The EJB Container's Behavior on Exceptions
Understanding EJB APl Exceptions
Transaction Attributes for EJBs using CMT
The Business Methods Interface "Pattern"
Session Beans in the Sample Application
Summary
Chapter 11. Infrastructure and Application Implementation
Infrastructure
Goals of a Strong Infrastructure
Using a Framework to Configure Application Components
The Problem
Using JavaBeans
Using a "Bean Factory"
The Application Context
Testing Implications
Summary of Application Configuration Infrastructure
Managing APl Complexity
Implementing EJBs
Accessing EJBs
Using JMS
Implementing Business Logic
Implementing the Sample Application
Defining Business Interfaces
Determining Implementation Strategy
Implementing the BoxOffice
Using JMS to Propagate Data Updates
Pulling It All Together
Summary
Chapter 12: Web-Tier MVC Design
The Challenges of Web Development
Lessons Learned in Java Web Development
The Shortcomings of Servlet-only Solutions
JSP: Promise and Temptation
"JSP Model 1" Architecture
The Temptation of the JSP Standard Infrastructure
Striking a Balance
Web-Tier Design Goals
A Clean Web Tier
A Thin Web Tier
MVC Concepts and the Front Controller J2EE Pattern
Concepts
The MVC Triad
Control Flow
Pattern Variants
Template Selection Servlet
How Many Controller Servlets?
JSP or Servlet Controller?
Should a Request Cause the Creation of a Command?
Implementation Goals
Web Application Frameworks
Common Concepts
Available Frameworks
Struts
Maverick
WebWork
Integrating a Web Application Framework into Overall Application Architecture
The Web Application Framework Used in the Sample Application
Design Goals
Basic MVC Control Flow
Controller Servlet
Request to Controller Mapping (com.interface21.web.servlet. HandlerMapping)
Request Controller (com.interface21.web.servlet.mvc. Controller)
Models
Views
ViewResolver
ContextLoaderServlet
Custom Tags
Workfiow Refinements
Examples
A Basic Controller Implementation
A Controller Exposing Bean Properties
A Multi-Action Controller
Web-Tier Session Management
Session State Managed by the J2EE Server
Clustering and Replication
Simple Optimizations
Session State Held in the Browser
Session State Management with Cookies
Session State Management with Hidden Form Fields
Processing User Input
Data Binding and Displaying Input Errors for Resubmission
Approaches to Data Binding in MVC Frameworks
JSP Custom Tags
Data Validation
Where Should Data Validation be Performed?
Data Validation in the Framework Described in this Chapter
Implementing the Web Tier in the Sample Application
Overview
Handling a Seat Reservation Request
Implementation Review
Summary
Chapter 12: Views in the Web Tier
Decoupling Controllers and Views
Constructing the View for the Reservations Page
Information Presented and Required Formatting
The Model Behind this View
Model Principles
JSP Views
What We Want to Avoid
How to Use JavaBeans in JSP Pages
JSP Custom Tags
The Java Standard Tag Library
Other Third-Party Tag Libraries
Implementing Your Own Tag Libraries
Guidelines for Custom Tag Use
Guidelines for JSP Use
Looking Ahead: Implications of JSP 2.0
A JSP View for the Example
JSP Summary
Dedicated Template Languages
Common Concepts
WebMacro
Velocity
Velocity Concepts
A Velocity Template for our Example
Velocity Summary
FreeMarker
XSLT
When to Use XSLT
What Do We Want from XSL?
How to Use XSLT in Views
Using XSLT Instead of JSP
Using XSLT from JSP Custom Tags
Implementing our Example Using a "Pure" XSLT Approach
Alternative Approaches to Markup Generation
HTML Generation Libraries
XMLC
An XMLC Template for Our Example
Compiling the Template
Manipulating the XMLC Object Generated from the Template
Further Reading on XMLC
Generating Binary Content
Generating PDF with iText
View Composition and Page Layout
Summary
Chapter 14: Packaging and Application Deployment
Packaging
Deployment Units
Expanded Deployment Units
Understanding J2EE Class Loading
Java Class Loading Concepts
Class Loading in J2EE
Server Check List
Recommendations
Further information
Packaging the Sample Application
Application Deployment: Common Concepts
Configuring a Server to Run the Application
Creating Connection Pools
Creating JMS Destinations
Setting up Authentication
Installing Libraries
Writing Proprietary Deployment Descriptors for an Application
EJB-Specific Configuration
Web-Tier Configuration
Deploying an Application
Deployment Parameters for the Sample Application
Deploying the Sample Application on JBoss 3.0
Understanding the JBoss Directory Structure
Configuring a JBoss Server to Run the Sample Application
Creating a Connection Pool
Creating JMS Destinations
Installing the Service Definition File
Reviewing Configuration
Writing JBoss Deployment Descriptors for the Sample Application
Deploying the Application
Summary
Chapter 15: Performance Testing and Tuning an Application
Strategic Issues and Definitions
Performance and Scalability
Setting Clear Goals for Performance and Scalability
Design Versus Code Optimization
Tools for Testing Performance and Throughput
Preparing to Benchmark
Web Test Tools
Microsoft Web Application Stress Tool
Non-Web Testing Tools
Locating Performance or Scalability Problems
Testing in Layers
Profiling Tools
JVM Profiling Options
The JProbe Profiler
Addressing Performance or Scalability Problems
Server Choice and Server Configuration
Dispensing with Redundant Container Services
Caching
When to Cache
Where to Cache
Third-party Caching Products for Use in J2EE Applications
Code Optimization
Case Study: The "Display Show" Page in the Sample Application
Performance in Distributed Applications
The Overhead of Remote Method Invocation (RMI)
Minimizing Remote Calls
Application Partitioning
Consolidating Remote Calls
Moving Data Efficiently
Serialization Optimizations
Other Data Transfer Strategies
Collocating Components in the Same JVM
Web-Tier Performance Issues
View Performance
Web Caching Using HTTP Capabilities
Cache Control HTTP Headers
Using the Servlet APl to Control Caching
Implications for MVC Web Applications
The Welcome Page in the Sample Application
Edged Side Caching and ESl
The Primary Causes of Performance and Scalability Problems in J2EE Applications
Summary
Chapter 16: Conclusion: Making J2EE Work for You
General Principles
Projects
Appendix A: Implementing View Technologies
Decoupling Controllers from View Technologies Using a View Interface
View Implementations
JSP
Configuring the JSTL
The InternalResourceView View Implementation
Defining JSP Views for Use in an Application
Velocity
Installing and Configuring Velocity
Implementing the View Interface for Velocity
Exposing Model Data to a Velocity Template
Providing Support for Date and Currency Formatting
Defining Velocity Views for Use in an Application
XSLT
Installing Domify
Implementing the View Interface for XSLT
Performing XSLT transforms
Date and Currency Formatting Support
Defining XSLT Views for Use in an Application
XMLC
Installing and Configuring XMLC
Implementing the View Interface for XMLC
Defining XMLC Views for Use in an Application
Generating PDF with IText
Installing iText
Implementing the View Interface for PDF Generation with iText
Defining PDF Views for Use in an Application
Additional Views
Custom Views
Index
I believe thatJ2EE is the best platform available for enterprise software development today. It combines the proven merits of the Java programming language with the lessons of enterprise software development in the last decade.
Yet this promise is not always fulfilled. The return on investment in manyJ2EE projects is disappointing. Delivered systems are too often slow and unduly complex. Development time is often disproportionate to the complexity of business requirements.
Why? Not so much because of shortcomings inJ2EE as becauseJ2EE is often used badly. This often results from approaches to architecture and development that ignore real world problems. A major contributing factor is the emphasis in manyJ2EE publications on theJ2EE specifications rather than the real world problems people use them to address. Many issues that commonly arise in real applications are simply ignored.
When readingJ2EE discussion forums, I'm struck by how little guidance and direction many developers find, and how much time and effort they waste as a result. In many cases, these developers have years of IT experience, and yet are finding it hard to come to grips withJ2EE.
The problem is not a lack of information aboutJ2EE components. Many books and web sites do a good job describing servlets, EJBs etc. Enabling technologies such asJNDI, RMI, andJMS are equally well served.
The problem is in getting to the next level - taking these construction materials and using them to build applications that meet real business requirements in a reasonable period of time. Here, I feel that much of the existing literature onJ2EE is a hindrance rather than help. There is a gulf between the world of J2EE books - the world as it perhaps should be - and the real world of enterprise software projects.
This book aims to address this problem and provide clear guidance and direction on usingJ2EE effectively in practice. I'll help you to solve common problems withJ2EE and avoid the expensive mistakes often made inJ2EE projects. I will guide you through the complexity of theJ2EE services and APIs to enable you to build the simplest possible solution, on time and on budget. I'll take a practical, pragmatic approach, questioningJ2EE orthodoxy where it has failed to deliver results in practice and suggesting effective, proven approaches.
I feel that no existing book delivers this. The closest is probably CoreJ2EE Patterns from Prentice Hall (ISBN: O- 130648-84-1), which generated much excitement on its release. Here at last was a book that addressed how to useJ2EE components. CoreJ2EE Patterns is a good book and a valuable resource for J2EE architects and developers. In particular, the terminology it uses has become widely accepted, but it's a Sun publication, and can't help reflecting the "party line".
It also deals purely with theJ2EE standards, paying little attention to issues encountered in working with real application servers. It fails to provide clear guidance: too often, it sits on the fence, presenting a variety of very different alternative "patterns". Readers able to choose confidently between them have little to learn from the book.
The more I considered the available publications, sample applications, and discussion forums, the more convinced I became thatJ2EE needed a healthy dose of pragmatism. J2EE is a great platform; unfortunately, many of the architectural practices promoted for it are not, and don't help to solve many common problems. ManyJ2EE sample applications, such as Sun's Java Pet Store, are disappointing. They don't face real world problems. They perform poorly, and their code often contains sloppy practices, providing a poor model.
I was also struck by the difference in outlook between developers new toJ2EE and those who had actually usedJ2EE to build enterprise systems. A former colleague used the wonderfully evocative word "gnarly" to describe developers who've come to grips with practical challenges of working with a technology and bear the scars. While those new toJ2EE sounded likeJ2EE evangelists, the "gnarly" developers told a different story. They had had to jettison some of the ideological baggage of the innocents to implement necessary functionality or achieve adequate performance. Like my colleagues and myself, they'd found that reality intruded harshly on the initial vision.
In this book I'll draw on my experience and industry knowledge to help you design and develop solutions that work in practice, without the need for you to go through a painful process of discovering the difference betweenJ2EE theory and reality.
J2EE Myths
I believe that the causes of disappointing outcomes withJ2EE can usually be traced to a few common myths, which underpin many explicit and implicit assumptions in development projects:
J2EE is about portability, between application servers and databases.
J2EE is the best answer to all the problems of enterprise development. If a problem that would traditionally have been solved using non-J2EE technologies, such as RDBMS stored procedures, can be solved with standardJ2EE technology, it's always best to use the "pure" J2EE approach.
J2EE servers take care of performance and scalability, leaving developers to get on with implementing business logic. Developers can largely ignore the performance implications of
J2EE "patterns" and rely on acceptable performance in production.
J2EE enables developers to forget about low-level problems such as data access and multi-threading, which will be handled transparently by the application server.
AllJ2EE applications should use EJB, which is the essentialJ2EE technology for developing enterprise-class applications.
Any problems withJ2EE will soon be addressed by more sophisticated application servers.
Let's quickly consider each of these myths in turn.
Portability is a great bonus of theJ2EE platform. As we'll see, portability can be achieved in real applications, but it's not the point of J2EE. The requirement of the vast majority of projects is to build an application that solves a particular problem well on one target platform. An application that runs badly on one platform will never be ported to other platforms (the application might be ported to another operating system that runs on more powerful hardware to gain adequate performance, but that's not the kind of portability that professional developers aspire to).
J2EE orthodoxy holds that an application should be portable acrossJ2EE application servers and must be able to work with different databases. The distinction between these two goals is important, and sometimes missed. Portability between application servers may deliver business value and is usually a realistic goal. Portability between databases is much more fraught, and often provides no business value.
Portability is usually taken to mean code portability: the ability to take the application and run it on another platform without any change. I believe that this is an expensive misconception. Naive emphasis on total code portability often leads to heavy costs in lost productivity and less satisfactory deliverables.Write Once Run Anywhere (WORA), while a reality where Java itself is concerned, is a dangerous slogan to apply to enterprise development, which depends on a range of resources.
I'm not talking about the minority of projects to develop "Shrink-wrapped" components (usually EJBs). This appealing concept is still to be proven in the market. Furthermore, I'm yet to see a non-trivial component that aimed For both, application server portability (which makes sense in this situation) and database portability (which will almost certainly be more trouble than it ~ worth).
I prefer Design Once, Re-implement a Few Interfaces Anywhere (DORAFIA). I accept that this is not so catchy, and that people are unlikely to leave Java One chanting it. This more realistic approach is widely used in other domains, such as windowing systems.
The portability myth has led to wide acceptance thatJ2EE applications can't use the capabilities of today's relational databases, but should use them only as dumb storage. This does great harm in the real world.
This is not to say that I don't believe thatJ2EE applications can or should be portable. I'm just arguing for a more pragmatic and realistic view of portability. We can designJ2EE applications to be ported easily; we can't do the same thing with a proprietary technology such as .NET.
It's pleasant to imagine thatJ2EE is the f'mal stage of the evolution of enterprise architecture; that finally,the application of object technology and the Java language has cracked problems the industry has wrestled with for decades. Unfortunately, this is not the reality, although it's implicitly assumed in many approaches to J2EE development. J2EE builds on many of the technologies that preceded it. It's a step forward, but it won't be the last and it doesn't address all the issues of enterprise software development.
Exaggerated emphasis on portability, along with thisJ2EE-centric attitude, has led to the assumption that if something can't be done in standardJ2EE, it's a design error to do it. This is even creeping into the EJB specification with the introduction of EJB Q L: a portable but immature query language that's more complex but far less powerful than the familiar, mature, and largely standard SQL that is available to the great majority of J2EE applications.
I like to think of aJ2EE server as the conductor of a group of enterprise resources such as databases. A good conductor is vital to any performance. However, a conductor doesn't attempt to play individual instruments, but leaves this to skilled specialists.
Perhaps the most dangerous myth is thatJ2EE is the easy route to good performance and scalability, and that efficiency is a lesser concern than approvedJ2EE "patterns". This leads to naive and inefficient designs. This is unfortunate, as outside the Java community Java has always been dogged by fears of poor performance. Today, the evidence is that the Java language offers good performance, while some popularJ2EE "patterns" offer very poor performance.
We cannot assume that the application server can take care of performance and scalability. In fact, J2EE gives us all the rope we need to tie up not only ourJ2EE application server, but the database as well. Had optimal performance been the main goal of software development, we'd have been writing web applications in C or assembly language. However, performance is vital to the business value of real-world applications. We can't rely on Moore's Law to allow us to solve performance problems with faster hardware. It's possible to create problems that prevent adequate performance, regardless of hardware power.
The idea that theJ2EE server should transparently handle low-level details such as data access is appealing. Sometimes it's achievable, but can be dangerous. Again, let's consider the example of relational databases. Oracle, the leading enterprise-class RDBMS, handles locking in a completely different way compared to any other product. The performance implications of using coarse or fine-grained transactions also vary between databases. This means that "portability" can be illusory, as the same code may behave differently in different RDBMS products.
Oracle and other leading products are expensive and have impressive capabilities. Often we'd want (or need) to leverage these capabilities directly. J2EE provides valuable standardization in such infrastructure services as transaction management and connection pooling, but we won't be saying goodbye to those fat RDBMS product manuals any time soon.
The "J2EE = EJB" myth can lead to particularly expensive mistakes. EJB is a complex technology that solves some problems well, but adds more complexity than business value in many situations. I feel that most books ignore the very real downside of EJB, and encourage readers to use EJB automatically. In this book, I'll provide a dispassionate view of the strengths and weaknesses of EJB, and clear guidance on when to use EJB.
Allowing the technology used (J2EE or any other technology) to determine the approach to a business problem often leads to poor results. Examples of this mistake include determining that business logic hould always be implemented in EJBs, or determining that entity beans are the one correct way to implement data access. The truth is that only a small subset of J2EE components - I would include servlets and stateless session EJBs - are central to mostJ2EE applications. The value of the others varies greatly depending on the problem in hand.
I advocate a problem-driven, not technology-driven, approach (Sun's 'J2EE Blueprints" have probably done as much harm as good, by suggesting aJ2EE technology-driven approach). While we should strive to avoid reinventing the wheel, the orthodoxy that we should never ourselves implement something that the server can (however inefficiently), can be costly. The coreJ2EE infrastructure to handle transaction management, etc., is a godsend; the same cannot be said for all the services described in theJ2EE specifications.
Some will argue that all these problems will soon be solved, asJ2EE application servers become more sophisticated. For example, ultra-efficient implementations of entity bean Container-Managed Persistence (CMP) will prove faster than RDBMS access using raw SQL. This is na'ive and carries unacceptable risk. There is little place for faith in IT. Decisions must be made on what has been proven to work, and faith may be misplaced.
There are strong arguments that some features of J2EE, such as entity beans, can never be as performant in many situations as some alternatives. Furthermore, the Promised Land is still just around the corner. For example, entity beans were soon going to provide brilliant performance when they were first introduced into the EJB specification in 1999. Yet the next two years revealed severe flaws in the original entity bean model. Today, the radical changes in the EJB 2.0 specification are still to be proven, and the EJB 2.1 specification is already trying to address omissions in EJB 2.0.
How is this Book Different?
First, it's an independent view, based on my experience and that of colleagues working withJ2EE in production. I don't seek to evangelize. I advocate usingJ2EE, but caution againstJ2EE orthodoxy.
Second, it has a practical focus. I want to help you to implement cost-effective applications usingJ2EE.This book aims to demystifyJ2EE development. It shows how to useJ2EE technologies to reduce,rather than increase, complexity. While I don't focus on any one application server, I discuss some of the issues you're likely to encounter working with real products. This book doesn't shy away from real-world problems that are not naturally addressed by theJ2EE specifications. For example, how do we use the Singleton design pattern in the EJB tier? How should we do logging in the EJB tier?
This book doesn't seek to cover the whole of J2EE. It aims to demonstrate effective approaches to solving common problems. For example, it focuses on usingJ2EE with relational databases, as most J2EE developers face O/R mapping issues. In general, it aims to be of most help in solving the most common problems.
We'll look at a single sample application throughout the book. Rather than use an unrealistic, abstract example as we discuss each issue, we'll look at a small part of a larger, more realistic, whole. The sample application is an online ticketing application. It is designed not to illustrate particularJ2EE technologies (like many sample applications), but common problems facingJ2EE architects and developers.
This book is about quality, maintainability, and productivity.
This is the book I wished I'd had as I worked on my firstJ2EE project. It would have saved me a lot of effort, and my employer a lot of money.
My Approach This book is problem-oriented rather than specification-oriented. Unlike many books onJ2EE, it doesn't aim to cover all the many services and APIs. Instead, it recognizes that not all parts of J2EE are equally useful, or of interest to all developers, and focuses on those parts that are used in building typical solutions.
Software design is as much art as science. The richness of J2EE means that it is often possible to find more than one good solution to a problem (and many bad solutions). While I make every effort to explain my views (or prejudices), this book naturally reflects my experience of and attitude towards working withJ2EE. I present an approach that I've found to work well. However, this doesn't mean that it's the only valid approach.
The book reflects my attitudes towards software development in general:
I try to avoid religious positions. I've never understood the energy and passion that so many developers devote to flame wars. This benefits no one.
I'm a pragmatist. I care about outcomes more than ideology. When I work on a project, my primary goal is to deliver a quality result on time and budget. The technology I use is a tool towards that goal, not an end in itself.
I believe that sound OO principles should underpinJ2EE development.
I believe that maintainability is crucial to the value of any deliverable.
In keeping with this pragmatic approach, rll jCrequently repr to the Pareto Principle, which states that a small number of causes (20%) are responsible for most (80%) of the ef~ct. The Pareto
Principle, originally drawn from economics, is highly applicable to practical software engineering, and we'll come across it repeatedly in approachingJ2EE projects. For example, it can suggest that trying to solve all problems in a given area can be much harder (and less cost-elective) than solving just those that matter in most real applications.
My approach reflects some of the lessons of Extreme Programming (XP). I'm a methodology skeptic, and won't attempt to plug XP. This isn't an XP book, but I feel that XP offers a valuable balance to J2EE theory. In particular, we'll see the value of the following principles: Simplicity. XP practitioners advocate doing "the simplest thing that could possibly work". Avoiding wasted effort. XP practitioners don't add features they may never need. This approach is captured in the acronym YAGN! (You Aren't Going to Need It).
Focus on testing throughout the development process.
Who this Book is for
This book is aimed at Java architects, developers already working withJ2EE, and Java developers who have a basic knowledge of J2EE and expect to work onJ2EE projects.
This book is not an introduction to EJBs, servlets,JSP, orJ2EE. Readers unfamiliar with these areas might read this book while referring to a comprehensive reference (see Recommended Reading below).
Aims of this Book
This book aims to leave the reader comfortable making architectural and implementation decisions aboutJ2EE development.
After working through this book, a developer familiar with the basic concepts of J2EE but who might not have any experience working with it would be confident in attempting aJ2EE project. A more experienced architect or developer would benefit from the discussion of J2EE architecture and implementation from a practical perspective. The chapters on project choices, testing and tools might be of interest to managers trying to understand the implications of adoptingJ2EE technology.
What this Book Covers
This book covers:
How to make keyJ2EE architectural choices, such as whether to use EJB and where to implement business logicJ2EE web technologies, and effective use of the Model-View-Controller (MVC) architectural pattern in web applications
How to use EJB 2.0 effectively, including the implications of the introduction of EJBs withlocal interfaces
How to choose an application server
OO development practices important toJ2EE applications
UsingJavaBeans inJ2EE applications, and how this can help develop maintainable and portable applications
Using XML and XSLT inJ2EE applications
J2EE transaction management
How to access relational databases efficiently inJ2EE applications
How to use generic infrastructure code to solve common problems and ensure that application code focuses on business logic in the problem domain
How to testJ2EE applications, and especially web applications
How to designJ2EE applications for satisfactory performance, and how to improve the performance of existing applications Packaging and deployingJ2EE applications
Aspects of leading application servers, such as BEA WebLogic and Oracle 9 Application
Server, which may affect how we designJ2EE applications
Understanding the implications of fundamental design choices for scalability
This book also includes and discusses much generic infrastructure code that can be used in your applications.
Assumed Knowledge
The following knowledge is assumed:
Strong Java language skills
Solid grasp of OO principles
Familiarity with classic OO design patterns
Familiarity with servlets and EJB
Some familiarity withJSP
Familiarity with web and distributed object protocols such as HTTP and IIOP
Understanding of fundamental underpinnings of J2EE such as RMI,JDBC, andJNDI
The following knowledge is desirable:
Relational database fundamentals
Understanding of transaction concepts (ACID properties and isolation levels)
Basic understanding of XML and XSLT
Basic understanding of UML, especially class and sequence diagrams
Familiarity with basic Computer Science concepts such as data structures
Recommended Reading
This book refers to many of the 23 design patterns discussed in the classic book Design Patterns: Elements of Reusable Object-Oriented Software from Addison Wesley (ISBN 0-201633-61-2). Although many of the patterns presented in this book merely codify the practice of any skilled OO practitioner, it provides a common language for architects and is essential reading for any serious developer. It is assumed that the reader has read, and has access to, this book.
I also use pattern names introduced in CoreJ2EE Patterns: Best Practices and Design Strategies from Prentice
Hall (ISBN 0-130648-84-I), as these are widely accepted. Although the present book can be read without reference to CoreJ2EE Patterns, it is recommended reading. Note, however, that I advocate a different approach in several areas. Also, some sections of CoreJ2EE Patterns, especially those relating to entity beans, are out-dated by the release of the EJB 2.0 Specification.
SomeJ2EE patterns are also discussed from EJB Design Patterns from Wiley (ISBN 0-471208-31-0). Again, this is recommended, although not essential, background reading.
A good reference covering theJ2EE 1.3 platform is essential. I recommend Proj~ssionalJava Server
ProgrammingJ2EE 1.3 Edition from Wrox Press (ISBN 1-861005-37-7). Ed Roman's Mastering Enterprise JavaBeans, (Second Edition), from Wiley (ISBN 0-471417-11-4)is a good book on EJB.
FullJavadoc for theJ2EE 1.3 platform is available online at
http://java.sun.com/j2ee/sdk_1.3/techdocs/api/index, html
Finally, all professionalJ2EE architects and developers should refer to the specifications that define the J2EE 1.3 platform, which are avaihtblc h'om http://java.sun.com/j2ee/download.html. Throughout this
book, I will refer to the relevant sections (such as EJB 17.4.1) of the following specifications:
J2EE 1.3
EJn 2.0
Servlet 2.3
JSP 1.2
Where relevant, I'll also refer to theJ2EE 1.4 specification releases, now in public draft and also available from Sun: notably EJB 2.1, Servlet 2.4 andJSP 2.0.
What You Need for Using this Book
To run the samples in this book you will need:
Java 2 Platform, Standard Edition SDK v 1.3 or above. We used the SunJDK 1.3.1_02 to runall sample code.
AJ2EE 1.3-compliant application server. We usedJBoss 3.0.0 for the sample application.
An RDBMS. We used Oracle 8.1.7i for the sample application. A free evaluation copy of the
"Personal Edition" is available from the Oracle site. Some changes (clearly identified in the text) will need to be made to the sample application to use a database other San Oracle 8.1.7or above.
To run the sample application, you will need the following third-party libraries:
Apache Log4j 1.2
An implementation of the JSP Standard Tag Library (JSTL) 1.0
To use the testing strategies discussed in Chapter 3, you will need:
JUnit 3.7 or above
The Apache CactusJ2EE testing framework
To run all the web content generation examples in Chapter 13 you will need:
Apache Velocity 1.3
Lutris XMLC 2.1
The iText PDF generation library
The Domify XML generation library
See Appendix A for information on how to install and configure these last four products.
All the third-party products and libraries discussed above are free and open source.
To build the source code you will need Apache Ant 1.4.1 or later, including optional task support. The complete source code for the samples is available for download from our web site at http://www.wrox.com/. There are two versions of the download: one which contains all the binaries discussed above, and a much smaller bundle that includes only the source code and compiled code discussed in this book. Download the smaller version if you already have, or want to download, the third-party products listed above.
Conventions
To help you get the most from the text and keep track of what's happening, we've used a number of conventions throughout the book.
These boxes hold important, not-to-be-forgotten information, which is directly
relevant to the surrounding text.
While the background style is used for asides to the current discussion.
As for styles in the text:
When we introduce them, we highlight important words
We show keyboard strokes like this: Ctrl-K
We show filenames and code within the text like so: persistence, properties
Text on user interfaces and URLs are shown as: Menu
We present code in two different ways:
In our code examples, the code foreground style shows new, important, pertinent code.
While code background shows code that's less important in the present context, or has been seen before.
Customer Support
We always value hearing from our readers, and we want to know what you think about this book: what you liked, what you didn't like, and what you think we can do better next time. You can send us your comments, either by returning the reply card in the back of the book, or by e-mail to feedback@wrox.com. Please be sure to mention the book title in your message.
How to Download the Sample Code for the Book
When you visit the Wrox site http://www.wrox.com/simply locate the title through our Search facility or by using one of the title lists. Click on Download in the Code column, or on Download Code on the book's detail page.
The files that are available for download from our site have been archived using WinZip. When you have saved the attachments to a folder on your hard-drive, you need to extract the files using a de-compression program such as WinZip. When you extract the files, the code is usually extracted into chapter folders. When you start the extraction process, ensure your software (WinZip) is set to use folder names.
Errata
WeTve made every effort to make sure that there are no errors in the text or in the code. However, no one is perfect and mistakes do occur. If you find an error in one of our books, like a spelling mistake or faulty piece of code, we would be very grateful for your feedback. By sending in errata you may save another reader hours of frustration, and of course, you will be helping us provide even higher quality information. Simply e-mail the information to support@wrox.com; your information will be checked and if correct, posted to the errata page for that title, or used in subsequent editions of the book.
To find errata on the web site, go to http://www.wrox.com/, and simply locate the title through our
Advanced Search or title list. Click on the Book Errata link, which is below the cover graphic on the book's detail page.
E-Mail Support
If you wish to directly query a problem in the book with an expert who knows the book in detail then e-mail support@wrox.com, with the title of the book and the last four numbers of the ISBN in the subject field of the e-mail. A typical e-mail should include the following things:
The title of the book, last four digits of the ISBN, and page number of the problem in theSubject field
Your name, contact information, and the problem in the body of the message
We won't send you junk mail. We need the details to save your time and ours. When you send an e-mail message, it will go through the following chain of support:
Customer Support - Your message is delivered to our customer support staff, who are the firstpeople to read it. They have files on most frequently asked questions and will answer anything general about the book or the web site immediately.
Editorial - Deeper queries are forwarded to the technical editor responsible for that book.
They have experience with the programming language or particular product, and are able to answer detailed technical questions on the subject.
The Authors - Finally, in the unlikely event that the editor cannot answer your problem, they will forward the request to the author. We do try to protect the authors from any distractions to their writing; however, we are quite happy to forward specific requests to them. All Wrox authors help with the support on their books. They will e-mail the customer and the editor with their response, and again all readers should benefit.
The Wrox Support process can only offer support to issues directly pertinent to the content of our published title. Support for questions that fall outside the scope of normal book support is provided via the community lists of our http://p2p.wrox.com/forum.
p2p.wrox.com
For author and peer discussion join the P2P mailing lists. Our unique system provides programmer to programmerTM contact on mailing lists, forums, and newsgroups, all in addition to our one-to-one e-mail support system. If you post a query to P2P, you can be confident that it is being examined by the many Wrox authors and other industry experts who are present on our mailing lists. At p2p.wrox.com you will find a number of different lists to help you, not only while you read this book, but also as you
develop your applications.
To subscribe to a mailing list just follow these steps:
1. Go to http://p2p.wrox.com/
2. Choose the appropriate category from the left menu bar
3. Click on the mailing list you wish to join
4. Follow the instructions to subscribe and fill in your e-mail address and password
5. Reply to the confirmation e-mail you receive
6. Use the subscription manager to join more lists and set your e-mail preferences
Why this System Offers the Best Support
You can choose to join the mailing lists or you can receive them as a weekly digest. If you don't have
the time, or facility, to receive the mailing list, then you can search our archives. Junk and spam mails
are deleted, and your own e-mail address is protected by the unique Lyris system. Queries about joining
or leaving lists, and any other general queries about lists, should be sent to listsupport@wrox.com.