WSAD Programming Guide
WSAD Programming Guide
WebSphere Studio
Application Developer
Version 5 Programming Guide
Develop Java, Web, XML, database, EJB,
and Web services applications
Deploy to WebSphere
Application Server
Ueli Wahli
Ian Brown
Fabio Ferraz
Maik Schumacher
Henrik Sjostrand
ibm.com/redbooks
International Technical Support Organization
July 2003
SG24-6957-00
Note: Before using this information and the product it supports, read the information in
“Notices” on page xix.
This edition applies to Version 5 of WebSphere Studio Application Developer and WebSphere
Application Server.
This book is a rewrite of the IBM Redbook, WebSphere Studio Application Developer
Programming Guide, SG24-6585, which was based on Version 4 of the products.
Notices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix
Trademarks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xx
Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi
The team that wrote this redbook . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxii
Become a published author . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiii
Comments welcome . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiv
Summary of changes from SG24-6585 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxv
July 2003, First Edition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxv
Chapter 4. Projects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
J2EE architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
Web containers and EJB containers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
EAR files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
WAR files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
JAR files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
Projects and folders . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
Application Developer’s project types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
Simple project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
Java project. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
Enterprise Application project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
Web project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
EJB project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
Application Client project. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Server project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Creating a new project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
Project properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
Using templates to create application projects . . . . . . . . . . . . . . . . . . . . . . . . . 88
Running the Application Template Wizard . . . . . . . . . . . . . . . . . . . . . . . . . 88
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
Contents v
Debugging your code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
Preparing a utility project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
Banking model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
Importing the implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
Testing the model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
Programming assists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Pluggable JDK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Java Scrapbook . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Code assist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
Navigating through your code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
Import generation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
Tasks view . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
Refactoring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
Code generation actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
Smart compilation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
Java search and working sets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
Bookmarks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
Javadoc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
Preferences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
Generating Javadoc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
Using Ant to generate Javadoc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
Contents vii
Chapter 8. Developing Web applications with database access . . . . . . 247
Accessing databases from a Web application . . . . . . . . . . . . . . . . . . . . . . . . 248
Creating a Web project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
Generate Web pages from SQL queries . . . . . . . . . . . . . . . . . . . . . . . . . . 249
Defining a data source in the server. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256
Testing the database application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
Accessing a database using DB Beans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
Creating a JSP using DB Beans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261
Accessing a database using JSP taglib . . . . . . . . . . . . . . . . . . . . . . . . . . 262
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270
Contents ix
Object-relational mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409
Implementing the session facade . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415
Creating the session bean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 416
Creating an EJB reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 418
Editing the session bean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421
Generating the deployed code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 426
Completing the EJB deployment descriptor . . . . . . . . . . . . . . . . . . . . . . . . . . 427
Changing the data source for EJB access . . . . . . . . . . . . . . . . . . . . . . . . 428
Testing the EJBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 428
Universal test client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 428
Adapting the Web applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 436
Web project dependencies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 437
EJB references . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 438
Testing the Web interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 439
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 440
Contents xi
Configuration page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545
Applications page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545
Administrative console . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 548
Applying Fix Packs to the WebSphere test environment . . . . . . . . . . . . . . . . 549
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 551
Contents xiii
Build targets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 639
Running Ant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 641
Where is the output? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 643
Rerunning Ant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 643
Forced build . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 644
Classpath problem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 644
Building J2EE applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 644
Using or importing a J2EE project. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 645
Ant J2EE build script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 645
Running Ant for J2EE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 650
Building Javadoc with Ant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 651
Running Ant outside of Application Developer . . . . . . . . . . . . . . . . . . . . . . . . 652
Preparation of the command file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 652
Running the command file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 653
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 654
Contents xv
Installing ClearCase LT Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 750
Installing the ClearCase LT client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 752
ClearCase integration with Application Developer . . . . . . . . . . . . . . . . . . . . . 752
ClearCase help in Application Developer . . . . . . . . . . . . . . . . . . . . . . . . . 753
ClearCase preferences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 753
Using ClearCase with Application Developer . . . . . . . . . . . . . . . . . . . . . . . . . 754
Setting up ClearCase for a new project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 756
Creating a new VOB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 756
Creating new ClearCase project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 757
Joining a ClearCase project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 759
Creating a Web project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 762
Adding a project to ClearCase source control. . . . . . . . . . . . . . . . . . . . . . 762
Development scenario . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 765
Developer 1 adds a servlet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 765
Developer 1 delivers work to the integration stream . . . . . . . . . . . . . . . . . 768
Developer 1 makes a baseline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 770
Developer 2 joins the project. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 772
Developer 2 imports projects into Application Developer . . . . . . . . . . . . . 774
Developer 2 adds a new servlet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 776
Developer 2 delivers work to the integration stream . . . . . . . . . . . . . . . . . 778
Developer 2 makes a new baseline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 779
Developers synchronize . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 779
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 782
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 821
Contents xvii
xviii WebSphere Studio Application Developer Version 5 Programming Guide
Notices
This information was developed for products and services offered in the U.S.A.
IBM may not offer the products, services, or features discussed in this document in other countries. Consult
your local IBM representative for information on the products and services currently available in your area.
Any reference to an IBM product, program, or service is not intended to state or imply that only that IBM
product, program, or service may be used. Any functionally equivalent product, program, or service that
does not infringe any IBM intellectual property right may be used instead. However, it is the user's
responsibility to evaluate and verify the operation of any non-IBM product, program, or service.
IBM may have patents or pending patent applications covering subject matter described in this document.
The furnishing of this document does not give you any license to these patents. You can send license
inquiries, in writing, to:
IBM Director of Licensing, IBM Corporation, North Castle Drive Armonk, NY 10504-1785 U.S.A.
The following paragraph does not apply to the United Kingdom or any other country where such provisions
are inconsistent with local law: INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES
THIS PUBLICATION "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF NON-INFRINGEMENT,
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Some states do not allow disclaimer
of express or implied warranties in certain transactions, therefore, this statement may not apply to you.
This information could include technical inaccuracies or typographical errors. Changes are periodically made
to the information herein; these changes will be incorporated in new editions of the publication. IBM may
make improvements and/or changes in the product(s) and/or the program(s) described in this publication at
any time without notice.
Any references in this information to non-IBM Web sites are provided for convenience only and do not in any
manner serve as an endorsement of those Web sites. The materials at those Web sites are not part of the
materials for this IBM product and use of those Web sites is at your own risk.
IBM may use or distribute any of the information you supply in any way it believes appropriate without
incurring any obligation to you.
Information concerning non-IBM products was obtained from the suppliers of those products, their published
announcements or other publicly available sources. IBM has not tested those products and cannot confirm
the accuracy of performance, compatibility or any other claims related to non-IBM products. Questions on
the capabilities of non-IBM products should be addressed to the suppliers of those products.
This information contains examples of data and reports used in daily business operations. To illustrate them
as completely as possible, the examples include the names of individuals, companies, brands, and products.
All of these names are fictitious and any similarity to the names and addresses used by an actual business
enterprise is entirely coincidental.
COPYRIGHT LICENSE:
This information contains sample application programs in source language, which illustrates programming
techniques on various operating platforms. You may copy, modify, and distribute these sample programs in
any form without payment to IBM, for the purposes of developing, using, marketing or distributing application
programs conforming to the application programming interface for the operating platform for which the
sample programs are written. These examples have not been thoroughly tested under all conditions. IBM,
therefore, cannot guarantee or imply reliability, serviceability, or function of these programs. You may copy,
modify, and distribute these sample programs in any form without payment to IBM for the purposes of
developing, using, marketing, or distributing application programs conforming to IBM's application
programming interfaces.
AIX® ^™ Redbooks™
BookMaster® Informix® Redbooks (logo) ™
Cloudscape™ IBM® SAA®
CICS® ibm.com® VisualAge®
Domino™ IMS™ WebSphere®
DB2® Lotus® z/OS®
™ Notes®
The following terms are trademarks of International Business Machines Corporation and Rational Software
Corporation, in the United States, other countries or both.
ClearCase® Rational®
Intel, Intel Inside (logos), MMX, and Pentium are trademarks of Intel Corporation in the United States, other
countries, or both.
Microsoft, Windows, Windows NT, and the Windows logo are trademarks of Microsoft Corporation in the
United States, other countries, or both.
Java and all Java-based trademarks and logos are trademarks or registered trademarks of Sun
Microsystems, Inc. in the United States, other countries, or both.
UNIX is a registered trademark of The Open Group in the United States and other countries.
SET, SET Secure Electronic Transaction, and the SET Logo are trademarks owned by SET Secure
Electronic Transaction LLC.
Other company, product, and service names may be trademarks or service marks of others.
Fabio Ferraz is the Chief Consultant for e-Voilà Enabling in Rio de Janeiro,
Brazil. He has years 11 years of experience in the IT field, and 8 of those
dedicated to e-business.
Osamu Takagiwa, Joseph Korchmar, Arne Lindquist, and Martin Vojtko, who
wrote the original redbook, WebSphere Studio Application Developer
Programming Guide, SG24-6585.
Your efforts will help increase product acceptance and customer satisfaction. As
a bonus, you'll develop a network of contacts in IBM development labs, and
increase your productivity and marketability.
Find out more about the residency program, browse the residency index, and
apply online at:
ibm.com/redbooks/residencies.html
Preface xxiii
Comments welcome
Your comments are important to us!
Summary of Changes
for SG24-6957-00
for WebSphere Studio Application Developer Version 5 Programming Guide
as created or updated on July 16, 2003.
This revision reflects the addition, deletion, or modification of new and changed
information described below.
New information
Support for J2EE 1.3, including EJB 2.0, Servlet 2.3, and JSP 1.2 levels
New chapters on XML development, EJB development, Web services
development, Struts development, GUI application development
Filters and listeners in Web development
Support for DB2® stored procedures
Component testing in the JUnit chapter
Usability enhancements for Common Versions System
Changed information
General update of existing information to Version 5
Deleted information
Migration—covered very well in the migration guide that is shipped with the
product
Plugin development—Very good information in a new book: The Java
Developer’s Guide to Eclipse (see “Other publications” on page 818)
Preface xxv
xxvi WebSphere Studio Application Developer Version 5 Programming Guide
Part 1
Part 1 Introducing
WebSphere Studio
Part 1 introduces WebSphere Studio Application Developer with concepts about
the Workbench, tools, workspace, perspectives, and projects.
The Eclipse Workbench platform was designed by IBM and released to the open
source community. It is an open, portable, universal tooling platform that provides
frameworks, services, and tools for building tools.
Eclipse
Eclipse is an open platform for tool integration built by an open community of tool
providers. With a common public license that provides royalty free source code
and world wide redistribution rights, the Eclipse platform provides tool developers
with ultimate flexibility and control over their software technology.
Industry leaders like IBM, Borland, Merant, QNX Software Systems, Rational®
Software, RedHat, SuSE, TogetherSoft, and WebGain formed the initial
eclipse.org board of directors of the Eclipse open source project. Visit the
Eclipse Web Site for more information about the project:
http://www.eclipse.org
Platform architecture
Figure 1-1 shows an overview of the Eclipse platform.
Eclipse is a platform that has been designed from the ground up for building
integrated regardless of presentation technology and application development
tooling. By design, the platform itself does not provide a great deal of end user
functionality. The value of the platform is what it encourages: rapid development
of integrated features based on a plug-in model.
Eclipse provides a common user interface (UI) model for working with tools. It is
designed to run on multiple operating systems while providing robust integration
with each underlying OS. Plug-ins can be programmed to the Eclipse portable
APIs and run unchanged on any of the supported operating systems.
The Eclipse platform uses the model of a common Workbench to integrate the
tools from the end user's point of view. Tools that you develop can be plugged
into the Workbench using well defined hooks called extension points.
The underlying platform runtime uses the same extension model to allow plug-in
developers to add support for additional file types and customized installations,
such as Web servers, workgroup servers, and repositories. The artifacts for each
tool, such as files and other data, are coordinated by a common platform
resource model.
The platform gives the users a common way to work with the tools, and provides
integrated management of the resources they create with plug-ins.
Within the Workbench based products, task-oriented perspectives filter out much
of the overall complexity, and present the developer only with those functions that
are relevant to the task at hand.
Users can switch perspectives depending on what they are working on at any
given moment, or depending on their current role in the project.
All development resources for all projects are stored in a single repository,
therefore developers have consistent team support for their projects, and are
able to easily share their work products.
Open standards
The whole Eclipse Workbench, as well as all products of the WebSphere Studio
family of products, are built on open standards and the code that they generate
also complies with open standards.
This allows you to build and deploy state-of-the-art, server-side applications that
conform to the Servlet 2.2, JavaServer Pages 1.1, and EJB 1.1 specifications.
File-based IDE
The Eclipse Workbench is a platform for building file-based IDEs. All content is
saved as files. Workbench resources, such as Java classes and HTML files, are
stored in the file system, making them easy to access.
The WebSphere Studio family of products currently has the following members
(Figure 1-2):
WebSphere Studio Site Developer Advanced
WebSphere Studio Application Developer
WebSphere Studio Application Developer Integration Edition
WebSphere Studio Enterprise Developer
The WebSphere Studio product family provide integrated development tools for
most e-business development roles including Web developers, Java developers,
business analysts, architects, and enterprise programmers. The customizable,
targeted and role-oriented approach of the Workbench will be a common
characteristic of future products in the WebSphere Studio family.
Eclipse Workbench
Provides frameworks for tool builders
to focus on tool building
Site Developer enables Web developers to use their favorite content creation
tools in conjunction with the built-in local and remote publishing capabilities.
Using Site Developer, you can develop Web applications that use the following
technologies.
JSPs—A simple, fast, and consistent way to extend Web server functionality
and create dynamic Web content. JSPs enable rapid development of Web
applications that are server and platform-independent.
Servlets—Server code that executes within a Web Application Server.
Web services—Self-contained, modular applications that can be described,
published, located, and invoked over the Internet or within intranets.
It includes all of the features of Site Developer, and adds tools for developing EJB
applications, as well as performance profiling and logging tools for both local and
remote execution.
Developers can quickly build and test business logic and enhance the
presentation artifacts with built-in Web creation tools inside the Application
Developer IDE before deploying to a production server.
The migration guide also provides some migration examples that show you, step
by step, how to migrate to Version 5 from previous versions.
Tools
The WebSphere Studio product family include the following basic tools:
Web development
Relational database
XML
Java development
Web services development
Team collaboration
Integrated debugger
Server tools for testing and deployment
Enterprise JavaBean development tools (not in Site Developer Advanced)
Performance profiling (not in Site Developer Advanced)
Plug-in development
Wizards are available to generate ready to run Web applications based on SQL
queries and JavaBeans. Links between Web pages can be automatically
updated when content is moved or renamed.
You can explore, import, design, and query databases working with a local copy
of an already existing design. You can also create an entirely new data design
from scratch to meet your requirements.
The database tools provide a metadata model used by all other tools that need
relational database information, including database connection information. In
that way, tools, although unaware of each other, are able to share connections.
The SQL Statement Wizard and SQL Query Builder provide a GUI-based
interface for creating and executing SQL statements. When you are satisfied with
your statement, you can use the SQL to XML Wizard to create an XML
document, as well as XSL, DTD, XSD, HTML, and other related artifacts.
The relational database tools support connecting to, and importing from, several
database types, including DB2, Oracle, SQL Server, Sybase, and Informix®.
XML tools
The comprehensive XML toolset provided by the WebSphere Studio family of
products includes components for building DTDs, XML schemas (XSD) and XML
files. With the XML tools you can perform all of the following tasks:
Create, view, and validate DTDs, XML schemas, and XML files.
Create XML documents from a DTD, from an XML schema, or from scratch.
Generate JavaBeans from a DTD or XML schema.
Define mappings between XML documents and generate XSLT scripts that
transform documents.
Create an HTML or XML document by applying an XSL style sheet to an XML
document.
Map XML files to create an XSL transformation script and to visually step
through the XSL file.
Define mappings between relational tables and DTD files, or between SQL
statements and DTD files, to generate a document access definition (DAD)
script, used by IBM DB2 XML Extender. This can be used either to compose
XML documents from existing DB2 data or to decompose XML documents
into DB2 data.
Generate DADX, XML, and related artifacts from SQL statements and use
these files to implement your query in other applications.
The WebSphere Studio family of products that include the Web services feature,
help you to build and deploy Web services-enabled applications across the
broadest range of software and hardware platforms used by today's businesses.
These tools are based on open, cross-platform standards such as Simple Object
Access Protocol (SOAP), Web Services Description Language (WSDL), and
Universal Description Discovery and Integration (UDDI).
All products of the WebSphere Studio family support the Concurrent Versions
System (CVS) and the Rational ClearCase® LT products.
Debugging tools
The WebSphere Studio family of products include a debugger that enables you to
detect and diagnose errors in your programs running either locally or remotely.
The debugger allows you to control the execution of your program by setting
breakpoints, suspending launches, stepping through your code, and examining
the contents of variables.
You can debug live server-side code as well as programs running locally on your
workstation.
The debugger includes a debug view that shows threads and stack frames, a
process view that shows all currently running and recently terminated processes,
and a console view that allows developers to interact with running processes.
There are also views that display breakpoints and allow you to inspect variables.
The profiling tools collect data related to a Java program's run-time behavior, and
present this data in graphical and non-graphical views. This assists you in
visualizing program execution and exploring different patterns within the
program.
The server tools support the following run-time environments, which can be
installed locally or remotely and support testing of Web applications:
WebSphere Application Server Version 5.0
WebSphere Application Server Express Version 5.0
WebSphere Application Server Version 4.0 (AEs)
Apache Tomcat Version 4.1
Apache Tomcat Version 4.0
Apache Tomcat Version 3.2
business logic
Bank
Deposit, Withdraw,
1:m Transfer
Customer
update create
m:m
1:m
Account TransRecord
Checking Savings
For simple Java and Web development we implement the model in memory. For
advanced development, such as Web with database and EJB, we use the
relational database.
CUSTOMER Bank customer with ID, title, firstname, lastname, user ID, password,
and address.
ACCOUNT Bank account with ID, balance, interest rate, account type, overdraft
amount (CHECKING) and minimum amount (SAVINGS).
TRANSRECORD Transaction record with ID, account ID, transaction type (deposit,
withdraw), and amount.
CUSTADDRESS Customer address with customer ID, street, city, state, zipcode (not
used in this book).
CUSTOMERINFO Customer information, for example picture (not used in this book).
Naming convention
All projects and packages used in this book follow a naming convention:
ItsoProGuideXxxxx for projects
itso.xxxx for packages
At the far left of the window is a shortcut bar that allows you to open new
perspectives and navigate between perspectives that are already open. The
name of the active perspective is shown in the title of the window and its icon in
the shortcut bar (left side) is a pushed button.
The J2EE Hierarchy, Tasks, and Outline views are open, along with an editor on
the welcome page. The welcome page provides a quick starting point if you are
eager to customize your Workbench or learn about other installed features.
Workspace basics
The Application Developer workspace is a private work area for the individual
developer. It holds the environment metadata and the loaded projects’ data in
regular files.
Every time you save a resource, the changes are reflected in the file system.
Normally this is your local file system, but you can also choose to store your
workspace in a network file system (NFS) as well.
Application Developer also allows you to open more than one Workbench at a
time. To open a new Workbench in another window, click Window -> New
Window and a new Workbench with the same perspective opens in a new
window.
Tip: If for some reason you ever need to clean your workspace and start over
from scratch, the quickest way would be to exit Application Developer and
rename the workspace directory. Upon restarting Application Developer, you
would have a clean workspace. You could then import the resources that you
still require from the old workspace directory.
For example, if your second instance should use the NewWorkspace workspace
folder, you can launch Application Developer with this command (this assumes
Application Developer has been installed in the default installation directory):
c:\Program Files\IBM\WebSphere Studio\wsappdev.exe -data c:\NewWorkspace
There are a number of parameters that you can add when launching Application
Developer (Table 2-1).
-vm vmPath This optional option allows you to set the location of Java
Runtime Environment (JRE) to use to run Application
Developer. Relative paths are interpreted relative to the
directory that Eclipse was started from.
-debug [optionsFileURL] Puts the platform in debug mode and loads the debug
options from the file at the given URL, if specified. This
file indicates which debug points are available for a
plug-in and whether or not they are enabled. If a file path
is not given, the platform looks in the directory that
Application Developer was started from for a file called
".options". Note that relative URLs are not allowed.
Do not select the check box Use this workspace as the default..., otherwise you
are not prompted again.
Tip: If you want to work with multiple workspaces create a duplicate startup
icon for Application Developer and use the -data flag to point to the
workspace.
All other startup parameters are described in Application Developer’s help facility.
Memory consideration
Use the -vmargs flag to set limits to the memory that is used by Application
Developer.
For example, with only 512 MB RAM you may be able to get better performance
by limiting the memory:
-vmargs -Xmx150M
You can also modify VMArgs initialization parameters in the wsappdev.ini file (in
the installation directory):
VMArgs=-Xms64M -Xmx150M -Xquickstart -Xgcpolicy:optavgpause
These arguments significantly limit the memory utilization. Setting the -Xmx
argument below 150M does begin to degrade performance.
For more information on memory management for the built-in WebSphere server,
see “Environment page” on page 547.
The only reason to use log files is if you encounter unexpected program behavior.
In some cases, an error message tells you explicitly to look at the error log.
There are two main log files in the .metadata directory of the workspace folder:
.log—The .log file is used by the Workbench to capture errors, and any
uncaught exceptions from plug-ins. The .log file is cumulative, each new
session of Application Developer appends its messages to the end of the .log
file without deleting any previous messages. This enables you to see a history
of past messages over multiple Application Developer sessions, each one
starting with the !SESSION string.
LoggingUtil.log—The LoggingUtil.log file is provided by the Application
Developer specific tools (a set of plug-ins added on top of the Workbench).
The Application Developer plug-ins use LoggingUtil.log to log various
events, errors, and caught exceptions through a logging API.
Both log files are ASCII files and can be viewed with any text editor.
Preferences
Application Developer’s preferences can be modified by selecting Window ->
Preferences from the menu bar. Opening the preferences displays the dialog
shown in Figure 2-3.
In the left pane you can navigate through many entries. Each entry has its own
preferences page, where you can change the initial options.
This section describes the most important options. Application Developer’s help
manual contains a complete description of all options available in the preferences
dialogs.
Automatic builds
By default, builds in Application Developer are done automatically whenever a
resource has been modified and saved. If you require more control regarding
builds you can disable the auto-building feature. To perform a build you have to
explicitly start it. This may be a desirable in cases where you know that building is
of no value until you finish a large set of changes.
If you want to turn off the automatic build feature, select Windows -> Preferences
-> Workbench and deselect the Perform build automatically on resource
modification check box (see previous Figure 2-3).
File associations
The File Associations preferences page (Figure 2-4) enables you to add or
remove file types recognized by the Workbench. You can also associate editors
or external programs with file types in the file types list.
The top right pane allows you to add and remove the file types. The bottom right
pane allows you to add or remove the associated editors.
If you want to add, for example, the Internet Explorer as an additional program to
open your .gif files, select *.gif from the file types list and click Add next to the
associated editors pane.
Confirm the Editor Selection dialog with OK and you will notice that the program
has been added to the editors list. Optionally you can set this program as the
default program for this file type by clicking Default.
Now you can open the file by using the context menu on the file and select Open
With and select the appropriate program.
Local history
A local edit history of a file is maintained when you create or modify a file. A copy
is saved each time you edit and save the file. This allows you to replace the
current file with a previous edit or even restore a deleted file. You can also
compare the content of all the local edits. Each edit in the local history is uniquely
represented by the data and time the file has been saved.
Note: Only files have local history. Projects and folders do not have a local
history.
Select Window -> Preferences -> Workbench -> Local History to open its
preferences page (Figure 2-6).
Table 2-2 explains the options for the local history preferences.
Days to keep files Indicates for how many days you want to maintain changes
in the local history. History state older than this value will be
lost.
Entries per file This option indicates how many history states per file you
want to maintain in the local history. If you exceed this value,
you will lose older history to make room for new history.
Maximum file size (MB) Indicates the maximum size of individual states in the history
store. If a file is over this size, it will not be stored.
Internet preferences
When using Application Developer and working within an intranet, you may want
to use a proxy server to get across the firewall to access the Internet.
To be able to access the Internet from Application Developer, you have to set
preferences for the HTTP proxy server within the Workbench. You can do this by
clicking Window -> Preferences and selecting Internet (Figure 2-8).
Depending on the type of Java coding you plan to do, you may have to add
variables pointing to other code libraries. For example, this can be driver classes
to access relational databases or locally developed code that you would like to
reuse in other projects.
Once you have created a Java project, you can add any of these variables to the
project’s classpath. Chapter 5, “Developing Java applications” on page 93
provides more information on adding classpath variables to a Java project.
To view and change the default classpath variables, click Window -> Preferences
and select Java -> Classpath Variables from the list. A list of the existing
classpath variables is displayed as shown in Figure 2-9.
You can create, edit and remove variables by using this dialog. Click New to add
a new variable. A new dialog comes up where you have to enter the name of the
variable and specify its path and file.
Figure 2-10 shows the New Variable Entry dialog with a DB2Java variable that
points to the DB2 JDBC driver class. The name of the file containing the class,
db2java.zip, is specified along with the file system path to it.
Code formatter
The Java editor in the Workbench can be configured to format code in
conformance with personal preferences or team standards. When setting up the
Workbench you can decide what formatting should be applied.
To modify the default code formatting select Windows -> Preferences -> Java ->
Code Formatter as shown in Figure 2-11.
Use the tabs at the top of the page to modify various aspects of the code
formatting. The sample code in the bottom right pane shows you a preview of the
effects of changes that you make.
The code formatting options are almost self explaining. However, a detailed
description of each option is provided in Application Developer’s help manual.
Note: To apply the formatting rules defined here, select Format from the Java
editor context menu. Some formatting, for example indenting of braces, will be
done on the fly while you are editing the source code.
Compiler options
Problems detected by the compiler are classified as either warnings or errors.
The existence of a warning does not affect the execution of the program. The
code executes as if it had been written correctly. Compile-time errors (as
specified by the Java Language Specification) are always reported as errors by
the Java compiler.
For some other types of problems you can, however, specify if you want the Java
compiler to report them as warnings, errors or to ignore them. To change the
default settings, use the Window > Preferences > Java > Compiler preferences
page (Figure 2-12).
Note: The Java compiler can create .class files even in presence of
compilation errors. In the case of serious errors (for example, references to
inconsistent binaries, most likely related to an invalid build path), the Java
builder does not produce any .class file.
There are a number of options for the code assist feature, which specify the
behavior and appearance of code assist. A description of how to use the code
assist feature is provided in “Code assist” on page 118. Also Application
Developer’s help manual contains a detailed description of each option of the
code assist feature.
Select Window -> Preferences -> Java -> Installed JREs to display the dialog as
shown in Figure 2-14.
By default, the JRE used to run the Workbench will be used to build and run Java
programs. It appears with a check mark in the list of installed JREs. You can add
another JRE and indicate whether it should be the default JRE or not.
When setting up the project you can also choose which of the JREs you would
like to use. If you do not explicitly specify the JRE for the project, the default JRE
is used.
In the JRE type field, select the type of JRE you want to add from the drop-down
list and enter a unique name in the JRE name field. In the JRE home directory
field, type or click Browse to select the path to the root directory of the JRE
installation (usually the directory containing the bin and lib directories for the
JRE). This location is checked automatically to make sure it is a valid path.
In the Javadoc URL field, type or click Browse to select the URL location. The
location is used by the Javadoc export wizard as a default value. If you want to
use the default libraries and source files for this JRE, select the Use default
system libraries check box. Otherwise, clear it and customize as desired. Source
can be attached for the referenced JARs as well.
Javadoc documentation
Application Developer supports the creation of Javadoc documentations.
Javadoc is the tool from Sun Microsystems for generating API documentation in
HTML format from doc comments in source code.
The JDT uses the Javadoc command (typically available in JDK distributions) to
generate Javadoc documentation from source files. Before you create Javadoc
documentation, you have to set the location of the Javadoc command.
Select Window -> Preferences -> Java -> Javadoc to open the Javadoc
preferences page (Figure 2-16).
In the Javadoc command field you have to enter the absolute path to the Javadoc
command. A javadoc.exe file is located any JDK installed on your system, for
example, the JDK within the built-in WebSphere Application Server:
<wsadhome>\runtimes\base_v5\java\bin\javadoc.exe
Organize imports
You can specify how you want the Java editor to handle imports when using the
automatic import generation feature. For more information on this feature see
“Import generation” on page 120.
In the Organize Imports preferences (Figure 2-17) you can specify the order of
the import statements. You can also control at what stage <package name>.*
import statements should be generated rather than fully qualified import
statements. The default number of fully-qualified import statements that are
allowed from the same package before <package>.* is 99.
Use the Up and Down buttons to change the order to imports. You can also add,
edit and remove imports. To add a new import entry, click New.
In the new dialog, simply type the package name or the package name prefix you
would like a add to the import statements list and confirm the dialog with OK.
Tip: You can also save and load your import statements settings by using the
Load and Save buttons. This might be a good idea when working in a team
where you have to apply coding standards.
Refactoring
Refactoring refers to the process of moving or renaming Java elements. A more
detailed description about Application Developer’s refactoring capabilities and
the refactoring preferences is provided in “Refactoring” on page 122.
Templates
Application Developer also provides templates. Templates are often reoccurring
source code patterns. The JDT of Application Developer offers support for
creating, managing, and using templates.
You can use a template in the Java editor by pressing Ctrl-Space (see “Code
assist” on page 118 for more information) and the templates appear in the
presented list. Note that the list is filtered as you type, so typing a few first
characters of a template name will reveal it.
The Templates preference page allows you to create new and edit existing
templates. A template is a convenience for the programmer to quickly insert often
reoccurring source code patterns.
To open the Templates preferences page, click Window -> Preferences -> Java
and select Templates from the Java tree, as shown in Figure 2-19.
To create a new template, click New. The New Template dialog comes up as
shown in Figure 2-20. Here you have to enter the name of the template, the
description and its pattern.
The name you enter here, will be displayed in the code assist list when you press
Ctrl-Space. In the Pattern field you have to enter the actual code you want to be
inserted by using the template.
There are also some predefined variables available. These variables can be
inserted by clicking Insert Variable. This will bring up a list and a brief description
of the variable.
You can also enable or disable specific or all templates by either using the check
boxes in front of the template or using the Enable All or Disable All buttons.
Exporting templates exports them to an XML file in a folder you can specify.
Summary
In this chapter we covered the basic functionality of the Workbench and the
underlying Java development environment.
Views provide different ways of looking at the resource you are working in.
Editors allow you to create and modify the resource. Perspectives are a
combination of views and editors that show various aspects of the project
resource, and are organized by developer role or task. For example, a Java
developer would work most often in the Java perspective, while a Web designer
would work in the Web perspective.
Application Developer provides the help content in a separate window that you
can open by selecting Help -> Help Contents from the menu bar (Figure 3-1).
In the new help window you see the available books in the left pane and the
content in the right pane. When selecting a book in the left pane, the appropriate
table of contents opens up and you can select a topic.
At any time, you can return to the bookshelf by clicking the Table of Contents
button .
You can navigate through the help documents by using the Go Back and Go
Forward buttons on the top right side. There are also buttons for printing the
document, toggling and synchronizing the navigation. Synchronizing the
navigation synchronizes the navigation frame with the current topic. This is
helpful if you have followed several links to related topics in several files, and
want to see where the current topic fits into the navigation path.
Figure 3-2 shows the help window with the table of contents of the Application
developer information book.
The Search field allows you to do a search over all books. The link Advanced
Search opens a dialog box where you can specify your search in more detail
(Figure 3-3).
Note: The first time you search the online help, the help system initiates an
index-generation process. This process builds the indexes for the search
engine to use. It may take several minutes, depending on the amount of
documentation. Each time you add or modify the documentation set (for
example, when you install a new feature or update an existing one), the index
will be updated to reflect the new information set.
Enter your search expression in the appropriate field of the search dialog and
select the set of books to searched. Click Search to start your search.
Perspectives
Perspectives provide a way to look at a project through different “glasses”.
Depending on the role you are in and/or the task you have to do, you open a
different perspective. A perspective defines an initial set and layout of views and
editors for performing a particular set of development activities, for example, EJB
development, profiling, and so forth. You can change the layout and the
preferences and save a perspective that you can have customized, so that you
can open it again later.
Views
Views provide alternative presentations of resources or ways of navigating
through the information in your Workbench. For example, the Navigator view
displays projects and other resources that you are working as a folder hierarchy.
Application Developer provides synchronization between different views and
editors.
A view might appear by itself, or stacked with other views in a tabbed notebook
arrangement. A perspective determines the views that you are likely to need. For
example, the Java perspective includes the Packages view and the Hierarchy
view to help you work with Java packages and hierarchies.
Editors that have been associated with specific file types open in the editor area
of the Workbench. By default, editors are stacked in a notebook arrangement
inside the editor area. You also have the option of tiling open files. However, if
there is no associated editor for a resource, Application Developer will attempt to
launch an external editor outside the Workbench.
Perspective layout
Most of Application Developer’s perspectives use a similar layout. Figure 3-4
shows a layout of a perspective which is quite common.
synchronize
synchronize
In some perspectives you can see that the editor pane is a little larger and the
Outline or Properties view is placed at the bottom left corner of the perspective.
The content of the views is synchronized. This means that if you change a value
in the Properties view, for example, the Editor view is automatically updated to
reflect the change.
Switching perspectives
There are two ways to open another perspective. You can use the Open a
Perspective icon in the top left corner of the Workbench working area and
select the appropriate perspective from the list. Alternatively, you can click
Window -> Open Perspective and either select a perspective or click Other to
bring up the Select Perspective dialog (Figure 3-5).
Select the perspective you would like to open and confirm the dialog with OK.
In the dialog you can use the check boxes to select which elements you want to
see on drop-down menus of the selected perspective. Items you do not select
are still accessible by clicking the Other menu option. These options can be
customizes:
The New menu
The Window -> Open Perspective menu
The Window -> Show View menu
Action sets (icons) that show up on the toolbar
You can also customize a perspective by adding, closing, moving, and resizing
views. To add a new view to the perspective, simply click Window -> Show View
and select the view you would like to add to the currently open perspective.
You can move a view to another pane by using drag and drop. To move a view,
simply select its title bar, drag the view, and drop it on top of another view. Both
views are now stacked and you can use the tabs at the bottom of the view to
switch between them.
While you drag the view, the mouse cursor changes into a drop cursor. The drop
cursor indicates what will happen when you release the view you are dragging:
The floating view appears below the view underneath the cursor.
The floating view appears as a tab in the same pane as the view
underneath the cursor. You can also drop the view on the
perspective toolbar to make it a fast view.
You cannot dock the floating view at this point.
Once you have configured the perspective to your preferences, you can save it
as your own perspective by selecting Window -> Save Perspective As.
To restore the currently opened perspective to its original layout, select Window
-> Reset Perspective.
Tip: You can double-click a view’s title bar to maximize the view. Double-click
again to restore it to the original size. Alternatively, you can press CTRL-M to
maximize and restore the view.
Perspectives walkthrough
In this section we describe the perspectives that we are using to develop, test,
and deploy the samples in this document.
J2EE perspective
The default perspective of Application Developer is the J2EE perspective, shown
in Figure 3-7. Application Developer lets you change the default perspective. See
“Specifying the default perspective” on page 54 for an instruction to change the
default perspective.
The J2EE perspective contains the following views that you would typically use
when you develop resources for enterprise application, EJB, Web, and
application client, or connector projects or modules:
J2EE Navigator view—This view provides a project and Java-centric view of
your J2EE and other projects in the workspace. It will show the project
resources and not the individual model objects as in the J2EE Hierarchy view.
For Java projects, the source folders will show the packaged based grouping
Resource perspective
The Resource perspective is a very simple perspective (Figure 3-8).
Web perspective
Web developers can use the Web perspective to build and edit Web resources,
such as servlets, JSPs, HTML pages, Style sheets and images, as well as the
deployment descriptor file, web.xml (Figure 3-9).
Java perspective
The Java perspective (Figure 3-10) supports developers who create, edit and
build Java code.
The Java perspective consists of an editor area and displays by default the
following views:
Package Explorer view—This is displayed by default in the Java perspective
and shows the Java element hierarchy of all the Java projects in your
Workbench. It provides you with a Java-specific view of the resources shown
in the Navigator. The element hierarchy is derived from the project's build
classpath. For each project, its source folders and referenced libraries are
shown in the tree view. From here you can open and browse the contents of
both internal and external JAR files.
Fields/Methods
Packages/Classes
Tasks
Tip: To get a larger Java editor view, you can move the Outline view and
place it tabbed next to the Package Explorer and Hierarchy view.
Java Editor
The Java Browsing perspective also displays an editor area, but unlike the Java
perspective, it displays by default the following views: Projects, Packages,
Types, Members, and an editor pane.
Java Editor
By default this perspective displays the Hierarchy view and the Editor pane. The
Hierarchy view does not display a hierarchy until you select a type (Figure 3-13).
Once you have selected a type and opened it to the type hierarchy, the type
hierarchy is displayed in the Hierarchy view. Figure 3-14 shows the Hierarchy
view of the Java Swing class JList.
Icons are provided at the top of the Hierarchy view to display the type hierarchy
, the supertype hierarchy (bottom-up) , or the subtype hierarchy
(top-down) . The supertype hierarchy also shows interfaces that are
implemented for each class in the hierarchy.
Servers can be controlled (start, stop, restart) either using the Server
Configuration view or the Servers view. Select the server and choose the
appropriate action from its context menu. If a server configuration is opened (by
double-clicking it) it opens up in the upper right pane and allows for editing of its
properties.
Data perspective
The Data perspective lets you access relational databases tools and you can
create and manipulate the data definitions for your project. This perspective also
lets you browse or import database schemas in the DB Servers view, create and
work with database schemas in the Data Definition view, and change database
schemas in the table editor. You can also export data definitions to another
database installed either locally or remotely. The Data perspective is shown in
Figure 3-17.
Debug perspective
Application Developer provides a Debug perspective that supports testing and
debugging of your applications.
Debug view—Displays the stack frame for the suspended threads for each
target you are debugging. Each thread in your program appears as a node in
the tree. If the thread is suspended, its stack frames are shown as child
elements.
If the resource containing a selected thread is not open and/or active, the file
opens in the editor and becomes active, focusing on the source with which
the thread is associated.
The Debug view enables you to perform various start, step, and terminate
debug actions as well as enable or disable step-by-step debugging
Variables view—Displays information about the variables in the
currently-selected stack frame.
Breakpoints view—Lists all the breakpoints you have set in the Workbench
projects. You can double-click a breakpoint to display its location in the editor.
In this view, you can also enable or disable breakpoints, delete them, or add
More information about the Debug perspective can be found in “Testing and
debugging” on page 553.
Profiling perspective
Profiling is controlled from the Profiling perspective (Figure 3-19). To open the
perspective, select Window -> Open Perspective -> Other -> Profiling.
The Profiling Monitor view displays profiling objects such as project folders,
monitors, hosts, processes, and agents that get created during a profiling
session.
On the right of the Workbench, the Profiling perspective offers the following
views, which display data that is collected from a profiling session:
Statistical profiling views:
– Package Statistics view
– Class Method Statistics view
– Method Statistics view
– Class Instance Statistics view
– Instance Statistics view
Graphical profiling views:
– Execution Flow view
– Object References view
– Method Execution view
– Method Invocation view
– Heap view
More details about using the CVS Repository Exploring perspective can be found
in Chapter 22, “Using Concurrent Versions System” on page 701.
To learn more about plug-in development, refer to The Java Developer’s Guide
to Eclipse (see “Other publications” on page 818).
Chapter 4. Projects
This chapter introduces the project types and some of the main terms used in
Application Developer.
J2EE architecture:
– EAR files
– WAR files
– JAR files
Projects and folders
Project types:
– Simple project
– Java project
– Web project
– Enterprise Application project
– EJB project
– Application Client project
– Server project
Creating a new project
J2EE makes all Java enterprise APIs and functionality available and accessible
in a well integrated fashion. This helps in simplifying complex problems in the
development, deployment, and management of multi-tier, server-centric
enterprise solutions.
Figure 4-1 shows an overall view comprising the different J2EE technologies.
Applet WebSphere
Container HTTP
SSL
Applet
Web Container EJB Container
Java
RMI-IIOP
Java
RMI-IIOP
J2SE
JDBC
JDBC
JNDI
JNDI
Mail
JMS
Mail
JMS
JTA
JTA
JAF JAF
Application
Client
RMI-IIOP
Database
JDBC
JNDI
JMS
J2SE
For additional information regarding the J2EE architecture and its technologies,
consult the J2EE specification on Sun’s Web Site:
http://java.sun.com/j2ee
EAR files
Enterprise archive (EAR) files represent a J2EE application that can be deployed
in a WebSphere application server. EAR files are standard Java archive files and
have the file extension .ear. EAR files also contain a deployment descriptor (an
XML file) that describes the contents of the application and contains instructions
for the entire application, such as security settings to be used in the run-time
environment.
An EAR file has the following modules (zero, one, or more of each type):
Web modules
EJB modules
Application client modules
Utility JAR files required by other modules
WAR files
Web archive (WAR) files contain all the components of a Web application. These
components are usually:
HTML files
CSS files
JSP files
Servlets
Compiled Java files
Images
JAR files
The Java archive (JAR) file format allows you to store multiple files into a single
archive file. Typically, a JAR file contains the class files and additional resources
associated with applets and applications.
Chapter 4. Projects 81
Projects and folders
Application Developer organizes all resources into projects.
Unless not specified differently, projects are created in the workspace directory
of Application Developer’s installation folder. Also, the metadata is stored in the
workspace directory. The .metadata directory of a workspace directory stores
important information about the workspace structure, such as a project’s
reference or a resource’s properties.
Tip: Closed projects require less memory. Because they are not examined
during builds, closing a project can improve the build time.
Simple project
A Simple project in Application Developer does not have any default folders and
does not have an associated builder. The files stored inside the project are not
compiled when you select to rebuild all projects in the Workbench.
Java project
A Java project contains Java packages and Java code as .java files and .class
files. Java projects have an associated Java builder that incrementally compiles
Java source files as they are changed. Java projects can be exported as JAR
files or into a directory structure.
DD = Deployment Descriptor
Application J2EE
Developer EAR Application Application
Project EAR file
DD
application.xml
EJB
Project
Web
EJB Project Web Client
Module Module Module
Client
JAR file WAR file JAR file
Project
ejb-jar.xml web.xml
Chapter 4. Projects 83
Web project
A Web project contains resources needed for Web applications, such as source
files and metadata, that correspond to the hierarchy of files necessary to deploy
a Web page or Web application. There are two types of Web projects:
Static Web project
J2EE Web project
A static Web project contains only static content such as HTML pages or images,
and any associated metadata. In addition to static content, J2EE Web projects
can contain additional kinds of resources for Web applications, including servlets,
JSP files, and Java files. J2EE Web projects incur more system overhead
because of additional validation and Java compilation that is automatically
performed by the Workbench. A Web project is deployed as a WAR file.
Struts project
With Application Developer Version 5, a Web project with Struts support can be
created. Such a project is tailored to provide an organization suitable for Struts
development, including the Struts runtime, configuration file, a Web diagram
editor, and wizards to create Struts components.
Refer to Chapter 10, “Developing Struts applications” on page 293 for details
about Struts and the support in Application Developer.
EJB project
Enterprise JavaBeans (EJB) projects contain the resources for EJB applications.
The EJB project contains the metadata files (such as the deployment descriptor,
IBM extensions, and RDB mappings) for the EJB application, Java source files,
compiled code for the enterprise beans, and stubs for the beans. An EJB project
is deployed as an EJB JAR file.
EJB projects allow you to organize your enterprise beans logically. As you
develop EJB applications in the Workbench, your source and output files are
kept in the ejbModule folder of the EJB project. As you make changes and
generate deployment code, the Java classes are compiled into the ejbModule
folder. You cannot use the EJB project as the source folder; doing so will cause
errors.
When you place the client code in an application client module instead of a
simple JAR file, the application client benefits from the server's resources (it does
not need to re-specify the class path to J2EE and server JAR files), as well as
benefiting from easier JNDI lookup (the server fills in the initial context and other
parameters). The application client project allows you to work as if you are
creating a standalone Java application in a Java project.
When creating a new Application Client project, you can choose between these
two project types:
J2EE 1.2 Application Client project
J2EE 1.3 Application Client project
Application client projects allow you to organize your client applications logically.
As you develop client applications in the Workbench, your source files will be
kept in the appClientModule folder of the application client project and the binary
files will be kept in the bin folder.
Server project
A Server project stores information about test and deployment servers and their
configurations. To test an EJB or Web project, you have to define a server with a
server configuration to publish and run the code. Servers identify where you can
test your projects, and server configurations contain setup information.
See the section “Creating a Server project” on page 519 in Chapter 15, “Servers
and server configurations” on page 513 for a detailed instruction of how to create
a Server project and a server.
Chapter 4. Projects 85
Creating a new project
You normally start developing a new application by creating one or more projects.
The Workbench provides wizards to create each specific type of project.
In general (it differs, depending on what type of project is created), when you
create a new project, you have to specify the following:
Name—Project name (we will use ItsoProGuideXxxxx).
Location—By default projects are store in the workspace directory, but
another location may be specified.
Organization—Directories for source and compiled files (unless this is
dictated by J2EE standards).
Dependencies—Within an enterprise application you have dependencies
between modules, for example a Web module requires an EJB module and a
utility JAr file.
After creation of a project, the appropriate perspective opens and displays a view
of the project.
Project properties
To make changes to the definition of a project, select the project and Properties
from the context menu. Figure 4-4 shows the properties dialog for a Web project.
Chapter 4. Projects 87
Using templates to create application projects
Application Developer provides an Application Template Wizard that creates
projects containing complete model applications based on application templates.
Chapter 4. Projects 89
Summary
In this chapter we described the type of projects provided by Application
Developer for the development of J2EE applications.
Part 2 Developing
applications
Part 2 describes how to develop applications. These chapters are provided:
Developing Java applications
Developing database applications
Developing Web applications
Developing Web applications with database access
Developing applications with stored procedures
Developing XML applications
Developing EJBs
Developing Web services
Developing Struts applications
Developing GUI applications
The sample Java code used in this chapter is provided in the directory:
\sg246957\sampcode\dev-java
Existing Java code can also be imported and integrated into new applications.
Application Developer 5 also introduces the Visual Editor for Java, which allows
you to design applications containing a graphical user interface (GUI). See
Chapter 14, “Developing GUI applications” on page 469 for a detailed description
of the Visual Editor.
To create a new Java project, select File -> New -> Project. This displays the New
Project dialog (Figure 5-1).
Select Java and Java Project from this dialog and click Next to start the Java
project wizard (Figure 5-2).
On the first page you name the Java project and specify the directory, where the
project files should be stored. In this example the project is named
ItsoProGuideJava. By default, the project files will be stored in a directory
created under the Application Developer workspace directory. You can change
the project directory by removing the Use default check box and specifying
another directory.
We click Next to bring up the second dialog of the wizard, where we define the
Java build settings for the new project (Figure 5-3).
On the Source tab you decide whether it is appropriate to store source code
directly in the project folder, or if you want to use separate source folders. For our
sample project, the simple model is used. If you want to use the complex model
instead, you can create the required folders by clicking Create New Folder and
adding them to the list.
Here you can also select the target folder for the generated class files. By default
the class files are placed in the same folder as the source folder, but you can edit
the Build output folder field to define a different target folder.
Note: In the Package Explorer view you cannot see the generated .class
files. If you open the Navigator view (Window -> Show View -> Navigator) you
can see source and class files.
On the Libraries tab, you can add other code libraries that have to be included in
the build path of your project (Figure 5-5). By default, the library list contains an
entry representing the Java runtime library.
You can also add Java classpath variables which have been defined in the
Classpath Variable preferences page. Consult the section “Java classpath
variables” on page 33 for more information about the Classpath Variable
preferences page.
The Add Variable button allows you to add classpath variables to the build path.
Classpath variables are symbolic pointers to JAR files with the benefit of
avoiding local file system paths in a classpath.
On the last tab, Order and Export, you can specify the order in which you want
items in the build path to be searched. Using the Up and Down buttons allow you
to arrange the order of the classpath entries in the list (Figure 5-6).
The checked list entries are marked as exported. Exported entries are visible to
projects that require the project. Use the Select All and Deselect All buttons to
change the checked state of all entries. The source folder itself is always
exported, and cannot be deselected.
You can also set the modifiers, the name of the superclass, add interfaces which
should be implemented, and create method stubs for the new class.
After all settings have been made, you click Finish to create the class. The Java
editor opens with the new class and its selected method stubs (Figure 5-9).
Tip: Notice the Javadoc comment that is generated for a new class. You can
tailor the comment by selecting Window -> Preferences -> Java -> Templates
and editing the typecomment entry.
CustomerListing sample
Complete the CustomerListing class with the sample code from:
\SG246957\sampcode\dev-java\CustomerListing.java
We do not explain in detail the code for the CustomerListing class. The basic
functions of the sample code are:
Connect to the DB2 database.
Select all customers from the CUSTOMER table.
Display the first name, the last name and the user ID of the customers.
Figure 5-10 shows the complete code of the sample CustomerListing class.
If you launch the program the first time, the Launch Configuration dialog opens
(Figure 5-11). Here you can select the type of configuration you would like to
create to run the program.
Select Java Application from the list and click New. A new launch configuration
with the appropriate settings for the selected class is created. You can also
specify arguments, JRE, and classpath settings for your launch configuration.
Clicking Run invokes the main method of the class.
Tip: By defining launch configurations for a program you can create multiple
configurations with different arguments and settings (such as the JRE).
You can also use the drop-down arrow of the Run icon. Clicking this drop-down
arrow the first time allows you either to open the configuration launcher or select
the type of application you would like to run, directly.
You can add other launch configurations for any program. Each configuration is
displayed when clicking the drop-down arrow of the Run icon.
The exception information indicates that there was a problem locating a class
required to run the program. To correct the error you have to add the JAR file with
the DB2 JDBC driver code to the classpath.
Figure 5-12 Java Build Path settings for the ItsoProGuideJava project
There are two ways you can specify access to the required classes:
Select Add External JARs and locate the db2java.zip file in the file system.
Select Add Variable to add a variable that refers to the db2java.zip file.
It is recommended to use the second option because you are not directly
referencing a physical path that could be different for another developer within a
team.
To add this variable to the Java build path for the project, select Add Variable to
display the New Variable Classpath Entry dialog (Figure 5-13).
Select the DB2JAVA variable and close the dialog with OK.
If the DB2JAVA variable is not available in the dialog, you have to create a new
variable. Click the New button to display the New Variable Entry dialog
(Figure 5-14). Enter DB2JAVA in the name field and select the file db2java.zip
from the file system by clicking the File button and confirm the dialog with OK.
DB2JAVA
c:\sqllib\java\db2java.zip
The sample code can now be executed again and the list of customers in the
database table should be displayed in the Console view.
Note: The EJBBANK database must be defined for this example. See “Installing
the EJBBANK database” on page 811 for instructions.
This dialog allows you to select the destination of the export. In this example
we will do a simple export to the file system. If the code would have been in
several class files, or if there would have been other resources required to run
the program, you could have chosen to export the sample project as a JAR
file instead.
When you have made your selection—in this case select File system—click
Next to specify the resources to export (Figure 5-16).
Expand the project which is shown in the left pane and select the
CustomerListing.class file in the right pane. You can specify the directory
where you would like to export the file. In this example we use C:\ as the path
and check the Create directory structure for files check box. This option
creates the directory path ItsoProGuideJava\itso\java for the file.
To run the application, open a command prompt window, switch to the
ItsoProGuideJava directory and enter the command:
java -cp ".;c:\sqllib\java\db2java.zip" itso.java.CustomerListing
The db2java.zip file is already added to the classpath after DB2 has been
installed. Therefore the following command should also execute the sample
application:
java itso.java.CustomerListing
After running this program, the customer list is displayed in the command
window.
You also need to ensure that the file java.exe is accessible in the path. In the
Application Developer installation folder you will find a copy of java.exe
located in the <wsadhome>\eclipse\jre\bin directory.
The line where the error occurs is also indicated by a yellow light bulb. If you
move the mouse over the light bulb, the error message is shown.
To more easily find the errors in the file you are working in, you can filter the
Tasks view to only show errors related to the current resource. To do this, click
the Filter icon in the Tasks view and select the entry On selected resource
only (or On any resource in same project) in the Filter Tasks dialog (Figure 5-18).
To set a breakpoint in the code, double-click in the grey area left of the statement
in the Java editor where you want to set the breakpoint. You can also open the
context menu and select Add Breakpoint (Figure 5-19).
To debug the CustomerListing class, you can start the program in debug mode
by clicking the Debug icon in the toolbar .
This opens the Debug perspective and run the program until the first breakpoint
has been reached. Within the Debug perspective you can view, inspect, and
modify variables, and can trace your code (Figure 5-20).
Step through
the code
Breakpoint
J2EE 1.3 provides support for utility JAR files at the enterprise application level.
Such JAR files are then made available to Web and EJB modules as JAR file
dependencies.
Banking model
Later in this book, when we implement an enterprise application with a Web
module in Chapter 7, “Developing Web applications” on page 179, we will use a
banking model that we define in the Java project. Figure 5-21 shows the types
used in the banking model.
Customer Account
m:m
1:m
JSP
TransRecord
Note: Both mediator and facade are documented design patterns. Refer to
Design Patterns: Elements of Reusable Object-Oriented Software.
Design considerations
This design with separation of front-end and backend enables us to implement
multiple front-ends and multiple business models that work with each other.
In Chapter 7, “Developing Web applications” on page 179, we implement a
front-end Web application using basic servlets and JSPs.
In Chapter 10, “Developing Struts applications” on page 293, we implement a
front-end Web application using the Struts framework.
In Chapter 12, “Developing EJB applications” on page 373, we implement the
business model as enterprise beans (EJBs). With a small change to the
facade bean we can then run both Web applications against the EJB business
model.
However, we can redesign the model with the use of an underlying database at
any time.
The Bank class initializes the data in memory. Instances of customers and
accounts are kept as java.util.Map. The customer-account relationship is held
as a java.util.Vector for each customer within a java.util.Map. The
transaction records of an account are held as a java.util.TreeSet for each
Account within a java.util.Map.
Business logic
All classes provide getter and setter methods for the attributes. To work with the
model the following business logic methods are provided:
The Customer class provides no special methods.
The Account class provides deposit and withdraw methods to perform
banking transactions.
After importing the code you find the five packages in the ItsoProGuideJava
project.
Alternatively, you can run the BankMain program using the instruction in “Running
your programs” on page 103.
The program executes a few of the business methods and displays the output in
the Console view.
Pluggable JDK
To provide support for different JDK levels and run-time environments, new JREs
can be added to the Workbench. For each project you can then select which
particular JRE you would like to use. By default the current version of Application
Developer supports the IBM JDK 1.3.1. The corresponding JRE will be used for
all projects unless it has been specified differently.
Java Scrapbook
Snippets of Java code can be entered in a Scrapbook window and evaluated by
simply selecting the code and running it. This feature can be used to quickly test
code without having to modify any actual Java source file.
Click Finish to create the scrapbook page. After the page has been created and
opened in the source editor, you can start entering code snippets in it.
To test a scrapbook page, we use code similar to the BankingTest class from the
banking model (Figure 5-23). The code is available in:
sg246957\sampcode\dev-java\JavaTest.jpage
Tip: All class names in a scrapbook page must be fully qualified or you have to
set import statements:
Select Set Imports from the context menu anywhere in the scrapbook.
For our example, select the itso.bank.model, itso.bank.util, and
java.util packages.
After you have added the code, you can run one of the snippets by selecting the
code and Run Snippet (context) or click the Run the Selected Code icon in
the toolbar. The result are displayed in the Console view.
// ------------------------------------- snippet 2
Bank bank2 = Bank.getInstance();
itso.bank.facade.BankingTest banking = new itso.bank.facade.BankingTest();
String acct1 = "101-1001";
String acct2 = "101-1002";
System.out.println("Transfer 33 from " + acct1 + " to " + acct2);
banking.transfer(acct1, acct2, new java.math.BigDecimal("33"));
System.out.println("Account: " + acct1 + " "
+ AmountConverter.fromDecimal(banking.getAccount(acct1).getBalance()));
TransRecord[] tx = banking.getTransactions(acct1);
for (int j=0; j<tx.length; j++) {
TransRecord tr = tx[j];
System.out.println(" - Tx: " + tr.getTimeStamp() + " " +
tr.getTransType() + " "+
AmountConverter.fromDecimal(tr.getTransAmt()));
}
Note: You cannot run code in a scrapbook page until you have at least one
statement selected.
You can also select Display from (context) to display the result expression or
Inspect to bring up the Expressions view, which allows you to inspect the result
like a variable in the debugger (see Chapter 16, “Testing and debugging” on
page 553 for more information about debugging and inspecting).
Change one of the account numbers for the transfer in snippet 2 to an invalid
account and run the code again. The debugger opens when the exception is
thrown.
A window is displayed and lists all methods and fields available for this object. In
addition, an infopop window is displayed, which shows the Javadoc associated
with the selected item. To insert a call to the method createStatement, simply
double-click the method’s name or press Enter on your keyboard.
The Java editor also supports syntax highlighting and hover help for the Java
code, which displays the Javadoc associated with the selected code.
Application Developer also provides templates, which helps the user to add
occurring source code patterns. For more information regarding templates see
“Templates” on page 43.
By selecting elements in the Outline view, you can navigate to the corresponding
point in your code. This allows you to easily find methods and field definitions
without scrolling the editor window.
Tip: If you have a source file with many fields and methods, you can use the
Show Source of Selected Element Only icon from the toolbar to limit the
edit view to the element that is currently selected in the Outline view.
The Package Explorer view, which is available by default in the Java perspective,
can also be used for navigation (Figure 5-26).
The Package Explorer view provides you with a Java-specific view of the
resources shown in the Navigator. The element hierarchy is derived from the
project's build paths.
Import generation
The Application Developer Java Editor simplifies the task of finding the correct
import statements to use in your Java code.
Simply select the type name in the code and select Add Import from the context
menu. If the type name is unambiguous, the import will be pasted at the correct
place in the code. If the type exists in more than one package, a window with all
the types is displayed and you can choose the correct type for the import
statement.
Figure 5-27 shows an example where the selected type (Statement) exists in
several packages. Once you have determined that the java.sql package is what
you want, double-click the entry in the list and the import statement is generated
in the code.
You can also add the required import statements for the whole compilation unit.
Open the context menu somewhere in the Java source editor and select Source
-> Organize Imports. The code in the compilation unit is analyzed and the
appropriate import statements are added.
You can control the order in which the imports are added and when package level
imports should be used through the Preferences dialog. See “Organize imports”
on page 42 for details about this feature.
Tasks view
The Tasks view displays the following information:
System generated tasks errors
User-defined tasks that you add manually
System generated tasks are typically created by the various builders. System
generated tasks can be errors, warnings, or information associated with a
resource. For example, if you save a Java source file that contains syntax errors,
the errors will automatically be logged in this view.
Figure 5-28 shows an example of the Tasks view with one user-defined task and
five system generated tasks (a broken link warning in an HTML file and four
compile errors in a Java file).
Also, the Tasks view can be filtered to show only specific types of tasks. For
example, you may want to see only error or tasks related to a specific resource.
For more information on this issue, refer to “Locating compile errors in your code”
on page 108.
A typical filter in a Java project would be to display the tasks that apply to any
resource in same project (see Figure 5-18 on page 109).
Refactoring
When developing Java applications, it is often necessary to perform tasks such
as renaming classes, moving classes between packages, and breaking out code
into separate methods. The term refactoring is sometimes used to describe
these types of changes. In traditional programming environments such tasks are
both time consuming and error prone, because it is up to the programmer to find
and update each and every reference throughout the project code. Application
Developer provides functions to automate this process.
Move Starts the Move refactoring wizard. Moves the selected elements
and (if enabled) corrects all references to the elements (also in
other files). Can be applied on one or more static methods, static
fields, types, compilation units, packages, source folders and
projects and on a text selection resolving to one of these element
types.
Pull Up Starts the Pull Up refactoring wizard. Moves a field or method to its
super class. Can be applied on one or more methods and fields
from the same type or on a text selection resolving to a field or
method.
Extract Method Starts the Extract Method refactoring wizard. Creates a new
method containing the statements or expressions currently
selected and replaces the selection with a reference to the new
method.
Extract Variable Starts the Extract Variable refactoring wizard. Creates a new
variable assigned to the expression currently selected and replaces
the selection with a reference to the new variable.
Inline Local Starts the Inline Local Variable refactoring wizard. Replaces the
Variable references to the selected local variable with the variable's initializer
expression and removes the variable.
Self Encapsulate Starts the Self Encapsulate Field refactoring wizard. Replaces all
Field references to a field with getter and setter methods. Is applicable to
a selected field or a text selection resolving to a field.
The set of radio buttons is used to indicate what type of error reporting you want
to see in the refactoring dialog. These options are listed in order of severity. By
default Application Developer will display any error that would occur if the
refactoring is performed.
If you check the option Save all modified resources automatically prior to
refactoring, any outstanding changes will be saved without displaying a prompt.
Refactoring example
The following example of a refactoring operation assumes that you want to
rename a class in your Java program. To initiate the renaming, simply select the
class and select Refactor -> Rename in the context menu. The Refactoring
wizard is displayed, where you rename the class and select the appropriate
refactoring settings (Figure 5-30).
Enter the new name for the class and click Next. If there are any files with
unsaved changes in the Workbench and you have not indicated in the
preferences that the save should be done automatically, you are prompted to
save these files before continuing the refactoring operation.
If problems more severe than the default level set in the refactoring preferences
are anticipated, then the problems page is displayed (Figure 5-31). If the
problems are severe, the Next and Finish buttons are disabled and the
refactoring must be aborted until the problems have been corrected. If the
buttons are enabled, you can select whether to accept the problems and
continue, or to cancel the refactoring operation.
Selecting Next at this point displays a window showing what actions will be
performed during the refactoring (Figure 5-32).
After reviewing the changes that will be applied, you can again select whether to
Finish or to Cancel the refactoring operation. Clicking Finish will perform the
renaming operation of the class. If there are any problems detected, they will be
displayed after the operation has been completed. The type of problem shown
depends on the settings in the Refactoring preferences dialog (Figure 5-29 on
page 124).
A dialog opens to let you select which methods you want to create. Select the
methods and click OK (Figure 5-33).
Override methods
The override methods feature helps you to override methods from the
superclass. Select Source -> Override Methods from the menu or Override
Methods in the context menu of a selected type or on a text selection in a type.
The Override Methods dialog (Figure 5-34) displays all methods that can be
overridden from superclasses or implemented from interfaces. Abstract methods
or not yet implemented methods are selected by default.
When clicking OK, method stubs for all selected methods are created.
Smart compilation
The Java Builder in the Workbench incrementally compiles the Java code as it is
changed, unless you disable the automatic build feature. For more information
consult the section “Automatic builds” on page 27.
You can also specify the scope of the search. You can either search the
workspace, choose only the selected resources or create a working set, which
can be used for future searches as well.
Simply click the Search icon to open the search dialog. Figure 5-35
demonstrates how to search for the field dbtab within a working set.
Type in the search string, specify that you would like to search for a field, and
select Working Set as the scope of this search.
Click Choose to display a new dialog, where you can select an existing working
set or create a new one (Figure 5-36).
Click New to create a new working set. Select a Resource working set or a
Java working set and click Next.
The last page of the wizard is displayed. You have to name your new working
set and specify the working set content.
Click Finish to create the working set.
By confirming this dialog with OK, the new set will be used in our Java search.
Figure 5-37 shows the Java search dialog with the new working set. Click Search
to start the search operation.
The search results are displayed in the Search view (Figure 5-38).
Double-clicking the result entry in the Search view opens the source file where
the field has been found and the first match is highlighted. The yellow arrows on
the left hand side indicate the lines where a match has been found.
To set a bookmark in your code, right-click in the gray sidebar left of your code in
the Java editor and select Add Bookmark (Figure 5-39).
A dialog is displayed where you have to enter a name for the new bookmark
(Figure 5-40).
Tip: You can bookmark individual files in the Workbench to open them quickly
from the Bookmark’s view later. In the Navigator view, right-click the file that
you want to add to you list of bookmarks and select Add Bookmark from the
file’s pop-up menu.
You can remove a bookmark by using the bookmark’s context menu in the
Bookmarks view and select Delete.
Note: Bookmarks are not specific to Java code. They can be used in any file
to provide a quick way of navigating to a specific location.
Javadoc
Javadoc is a tool in the Java JDK to generate documentation about Java
packages, classes, and methods. The Javadoc documentation is based on
comments entered for each class and method, and the packaging of classes into
packages.
Preferences
The location of the javadoc.exe must be specified in the Javadoc preferences.
Refer to “Javadoc documentation” on page 40 for instructions.
Generating Javadoc
Application Developer provides a wizard to generate Javadoc for selected
packages or projects.
On the next page you can specify detailed options about the doclet
generation, including a title (Figure 5-42). Click Next.
Note that our source classes do not have many comments for good Javadoc!
To see the generated files in the Workbench, select the ItsoProGuideJava
project and Refresh (context).
In general you would not generate Javadoc into the Workbench but rather into
a documentation location. Either move the data to another location or delete
the doc folder from the project.
To regenerate the Javadoc, select the javadoc.xml file and Run Ant (context) and
click Finish in the pop-up dialog.
See Chapter 19, “Building applications with Ant” on page 633 for detailed
information about Ant.
Summary
In this chapter we described how to create a new Java project and how to work
with the programming assists of Application Developer by creating a simple Java
class.
While you are working with larger projects you will experience the benefits of the
programming assists and the Java development tools.
We also demonstrated how to prepare and implement a utility project and how to
generate Javadoc.
Figure 6-1 shows the basic components of JDBC access. The JDBC API sends
the SQL commands from the application through a connection to the vendor
specific driver that provides access to the database. Connections can be
established through a driver manager (JDBC 1.0) or a data source (JDBC 2.0).
Java Application
getConnection getConnection
Vendor supplied
JDBC Driver
Database
By using data source objects you have access to a pool of connections to a data
source. Using connection pooling gives you the following advantages:
It improves performance. Creating connections is expensive; a data source
object creates a pool of connections as soon as it is instantiated.
It simplifies resource allocation. Resources are only allocated from the data
source objects, and not at arbitrary places in the code.
If you use the Create database Web pages wizard, described in detail in
“Accessing databases from a Web application” on page 248, you have the option
of generating code to use either a driver manager connection or a data source
connection.
Data perspective
The Data perspective is used to work with databases, tables, and SQL
statements. See “Data perspective” on page 68 for an introduction.
The Data Definition view is a hierarchical view of the database objects and does
not display how these definitions are stored in actual files.
Navigator view
In the Navigator view (Figure 6-4) you can see the local descriptor files (.xmi
files) that represent the database objects. Each of the files has an editor
associated with it. Double-clicking the file brings up the appropriate editor for the
type of object that is described, which could be either a database, a schema, or a
table.
The DB Servers view allows you to filter the designs that are returned to only
show a subset of schemas or tables. You can also use the DB Servers view to
generate DDL files and XML schemas.
Important: The DB Servers view is read-only. Before you can edit any
database objects, you have to import them into an Application Developer
project.
Note: The examples in this section assume that you have created and
populated the DB2 tables as described in “Installing the EJBBANK database”
on page 811.
To view the definition of an existing database, you first have to create a JDBC
connection to the database. To create a new connection, first make sure you are
in the DB Servers view. Then right-click anywhere in the view and select New
Connection to display the Database Connection wizard (Figure 6-5).
You have to provide a unique name for the connection (Con1 in our example), a
user ID and password if required, and the type of database you are connecting
to. Also, you must specify which JDBC driver should be used. There are two
predefined JDBC drivers for DB2:
IBM DB2 APP DRIVER (COM.ibm.db2.jdbc.app.DB2Driver) for connections
to local databases or remote databases defined locally with the DB2 Client
Configuration Assistant.
IBM DB2 NET DRIVER (COM.ibm.db2.jdbc.net.DB2Driver) for connections
to remote DB2 databases.
See “DB2 JDBC drivers” on page 175 for more details on DB2 JDBC drivers.
The dialog has four pages to define filters for schemas, tables, stored
procedures, and user-defined functions. By default, one schema filter is
predefined (SCHEMA NOT LIKE SYS%) by the selection Exclude system schemas.
For our example we are limiting the selection to tables with names starting with
CU. To create the filter, select the Table tab and click Add Filter, and the Add
Filter dialog shown in Figure 6-7 opens.
Enter CU% in the entry field and click OK. You can modify the filter by clicking any
cell in the table and changing the value. Click OK to close the filter dialog.
After clicking Finish in the connection window, the connection is created and a
new database entry is added to the DB Servers view. You can expand the new
node to see the schemas and tables that are now available for use (Figure 6-8).
Figure 6-8 DB Servers view of EJBBANK database with table filter applied
Next we create another connection without filters. We will use this connection in
the next section to import database objects into our workspace.
Right-click inside the DB Servers view, and select New Connection from the
context menu. The new connection wizard opens, already containing the default
values for connection name (Con2) and database name (EJBBANK). By default, no
filters are entered. All you have to do is click Finish to create this connection.
Figure 6-9 shows the DB Servers view, which now contains the new connection
Con2. This new connection has no table filters, so it shows all the tables in the
EJBBANK database.
Simple project
We use a simple project to store the database definitions. A simple project is a
generic project that contains files and folders. To create the project select File ->
New -> Project. Then select Simple and Project from the New Project dialog and
click Next. Enter ItsoProGuideDatabase as the project name, and click Finish.
The Resource perspective opens. However, we will continue to work in the Data
perspective, so we close the Resource perspective.
Import database
We now import the EJBBANK database into the new project:
In the Data perspective, DB Servers view, select the connection Con2 Import
to Folder (context).
In the Import dialog (Figure 6-10) click Browse to locate the
ItsoProGuideDatabase project, then click Finish.
In the Data Definition view (Figure 6-11) expand the EJBBANK node. The same
database objects are shown, but you can now open editors on them to view and
modify their definitions.
In the Navigator view you will notice that a number of XMI files have been created
for the database objects. (XMI is an open information interchange model that
allows developers who work with object technology to exchange programming
data over the Internet in a standardized way.)
Figure 6-11 Imported database objects in Data Definition and Navigator views
If you double-click one of these files, the appropriate object editor opens. If you
want to see the XMI source, you can right-click any of the files and select Open
With -> Text Editor.
Enter the name of the folder where you want the generated .sql file to be stored,
select options for the generation and whether you want to open the SQL editor on
the generated file. If you elect not to open the editor, you will have to switch to the
Navigator view to see the generated file. The generated DDL file is shown in
Example 6-1.
XML schemas can be generated for tables. To generate an XML schema for a
table, you must already have imported it into a folder and be in the Data
Definition view.
Select the CUSTOMER table and Generate XML Schema from the context menu,
and the Create XML Schema dialog opens (Figure 6-13).
Click Finish and the schema file (with extension .xsd) is created and opened in
the XML schema editor. The content of the customer XSD file (visible in the
Source tab of the editor) is shown in Example 6-2.
<element name="CUSTOMER_TABLE">
<complexType>
<sequence>
<element ref="EJBBANKITSO:CUSTOMER" minOccurs="0"
maxOccurs="unbounded"/>
</sequence>
</complexType>
<key name="CUSTOMER_PRIMARYKEY">
<selector xpath="EJBBANKITSO:CUSTOMER"/>
<field xpath="CUSTOMERID"/>
</key>
</element>
<element name="CUSTOMER">
<complexType>
<sequence>
<element name="CUSTOMERID" type="integer"/>
<element name="TITLE">
Notice the Graph page of the XML schema editor (Figure 6-14). Expand the
boxes by clicking the + icon.
Study the Outline view as well. It shows the structure of the XML schema file.
If you want, you can make changes to the XML file and generate a new DDL file
by selecting Generate -> DDL (context).
Create database
To create a new database you have to have a project. If you have not already
done so, you should now create a new simple project called
ItsoProGuideDatabase.
To create database objects you have to switch to the Data perspective and open
the Data Definition view.
Here you specify the name of the new database and the vendor type. When you
later generate the database DDL it will conform to the database type that you
select. Click Finish to create the new database definition.
Select a name (ITSO) for the schema and click Finish to create it.
Expand the new schema in the Data Definition view and you will see the types of
objects that can be added to it.
Tables
Views
Aliases
Indexes
Triggers
Structured types
Stored procedures
User-defined functions
Create table
We will now look at how to create a new table in the schema. Application
Developer provides a wizard for defining table columns as well as primary and
foreign keys. To create a table, select the schema created in the previous step
Here you give the table a name and an optional comment. On the next page you
define the columns of the table (Figure 6-18).
In our case, in addition to the CUSTOMERID field, we add FIRSTNAME and LASTNAME.
These two additional fields are of type CHARACTER with string length 30 and For bit
data not checked (Figure 6-17).
The next page of the wizard lets you define the primary key of the table
(Figure 6-20).
You select the items you want from the Source Columns and add them to the
primary key by clicking >.
On the final page of the wizard you can define any foreign key constraints that
you want to apply. In our case, we do not have another table defined, so we do
not add a foreign key (Figure 6-21).
If you want, you can generate the DDL for the table you have just created. To do
so, select the table in the Data Definition view and Generate DDL and the
Generate SQL DDL dialog opens (Figure 6-22).
The options available are to create the DDL with or without the schema name,
whether to place delimiters around identifiers or not, whether or not to generate
DROP statements, and whether to open an editor on the generated file. The
generated DDL file is shown in Figure 6-23.
You can also execute the DDL on a database server. See “Define the database
schema in a database system” on page 163.
On the foreign keys page of the wizard (Figure 6-24), click Add Another to add a
foreign key.
Select the ITSOTEST object and Generate DDL (context). Note that the generated
file (ITSOTEST.sql) does not contain the DDL for the database object itself, only
the schema and the tables are defined.
Click Next. On the next page, set the commit option, for example, Commit
changes only upon success (Figure 6-27).
Both tools can be used to build an SQL statement. After using the SQL
Statement Wizard, you can use the SQL Query Builder to updates the SQL
statement.
For our example we are developing a SELECT statement against the sample
EJBBANK database. We would like to see a list of all credit transactions where the
last name of the customer contains the letter “o”. We like to see the transaction
ID, account ID, and the first and last name of the customer, as well as the
transaction amount.
To create some order in the project, select the ItsoProGuideDatabase project and
New -> Folder (Navigator view, context). Enter sql as the folder name.
On the first page, you select the type of statement you want to create and say
that you want to use the wizard: Be guided through creating an SQL statement.
There are two ways to specify the database model. You can either use an
existing one or import a new one. In this case we already have the database
model imported into the Workbench, so we select Use existing database model.
Click the Browse button to locate the EJBBANK model in the Workbench and enter
the name of the SQL statement.
You select the tables in the left pane and use the > button to include them. For
our example we have the CUSTACCT, CUSTOMER, and TRANSRECORD tables. On the
Columns tab you select the columns from these tables that should be included in
the query (Figure 6-30).
Tip: You can rearrange the tables by dragging them on the pane. You can
enlarge a table by dragging the sides. You can also select the columns in this
dialog step, or make changes to the selection from the previous step.
Select the Column, Operator, Value, And/Or, using the drop-down menu (visible
after you click in the field). Enter the value by typing in the field.
Using a variable
In a real-life situation you might not want to hardcode that the last name contains
the letter o, but instead leave it as a host variable. Therefore, do not enter '%o%'
in the Value column, rather enter a variable as :lastname. This is especially
useful later in “Accessing databases from a Web application” on page 248.
Tip: If you have to enter more than one condition, you must put in the AND or
the OR element before the next row in the table becomes editable.
On the next two tabs you can enter information regarding grouping (GROUP BY)
and sorting of rows (ORDER BY).
Once you have finished building the statement you can click Next to see the
generated SQL statement (Figure 6-33).
If you want, you can edit the statement directly. When you are finished editing,
you can click Parse to validate that the SQL statement is correct.
The SQL statement is opened in the SQL Query Builder editor. Close the editor.
The SQL statement appears as EJBBANK_CreditListing.sqx in the Navigator
view, and as CreditListing in the Data Definition view (under EJBBANK ->
Statements).
To start the SQL Query Builder, expand the database folder in the Data Definition
view. Select the Statements folder and New -> Select Statement. A dialog to
enter the name of the statement is displayed. Enter ListCredits and click OK.
The SQL Query Builder editor is displayed (Figure 6-35).
join
join
Next, select the columns from each table. To select a column, check the box
next to its name. For the CUSTOMER table, select all columns except ADDRESS.
For the TRANSRECORD table, select all columns. Do not select any columns of
the CUSTACCT table (they are duplicates anyway). As you select the columns,
the SELECT statement is updated in the top pane and the columns are added
in the bottom pane.
Next, join the tables together. To join the tables, select the CUSTOMERID
column in the CUSTOMER table and drag it across to the corresponding column
in the CUSTACCT table. Next, select the ACCID column in the CUSTACCT table and
drag it across to the corresponding column in the TRANSRECORD table. A link
Join
Conditions
Save the statement. You are prompted for the host variables; just click Cancel to
dismiss the dialog.
Enter 'C' as the value for the :type and '%o%' as the value for the :lastname
variables in the Host Variable Values window and click Finish to execute the
query. The matching rows from the database are shown in the DB Output view
(Figure 6-38).
Later on we will look at how you can use Application Developer to generate Web
pages and Java classes to quickly and easily build an application based on an
SQL statement that uses host variables.
We will use this SQL statement in “Accessing databases from a Web application”
on page 248.
Note: You do not have to create an instance of the driver or register it. This is
done automatically for you by the DriverManager class.
After loading the driver, you have to establish a connection. The class that
handles this is called DriverManager.
The URL string that is passed in to the getConnection method is again
dependent on which database system you are using. In the example above,
we are connecting to a DB2 database called EJBBANK. In this example we are
not passing a user ID and password, but if that was required, they would be
the second and third parameters of the getConnection call.
In our examples we use the DB2 app driver because we are talking to a local
database. If you are trying to connect to another database system, you should
consult the documentation to determine what driver name and URL to use.
stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM ITSO.CUSTOMER");
You create a statement using the connection obtained from the DriverManager
and then you execute the query passing the select statement. The result set from
the query is returned in a ResultSet variable.
Next, you have to process the result set from the query. The ResultSet class
provides a number of get methods for various data types as shown in
Figure 6-41.
while (rs.next()) {
String firstName = rs.getString("firstName");
String lastName = rs.getString("lastName");
String userID = rs.getString("userID");
System.out.println(firstName + " " + lastName + " " + userID);
}
Finally, JDBC objects must be closed to release the resources (Figure 6-42). The
best place is a finally clause that is executed even in case of exceptions.
} finally {
try {
if (rs != null) rs.close();
if (stmt != null) stmt.close();
if (con != null) con.close();
} catch (SQLException e) {}
}
Figure 6-43 shows the basic code sequence to get a connection through a data
source.
try {
javax.naming.InitialContext ctx = new javax.naming.InitialContext();
javax.sql.DataSource ds = (javax.sql.DataSource)
ctx.lookup("jdbc/ejbbank");
con = ds.getConnection();
} catch (javax.naming.NamingException e) {
System.err.println("Naming-Exception: " + e.getMessage());
} catch (java.sql.SQLException e) {
System.err.println("SQL-Exception: " + e.getMessage());
}
The data source is retrieved using a the lookup method of the InitialContext.
The data source must be registered in the JNDI server. In our example we use a
JNDI name of jdbc/ejbbank, which points to the EJBBANK database.
Retrieving the data source is expensive. Good coding practice for Web
applications is to retrieve the data source only once in the init method of a
servlet, and to get and release a connection in the doGet or doPost method for
each client request.
We use the Page Designer, CSS Designer, and wizards to create servlets and
JSPs. To experiment with the new J2EE 1.3 functions, we develop both a sample
filter and a listener.
Finally, we use the wizard to create a simple Web application from a JavaBean.
We will start off by introducing you to the sample application that will be used
throughout this chapter, and in later chapters as well. We will then proceed to
create a new Web project to hold our example application. Once the project is in
place, we are able to add both static and dynamic content to it, and to use tools
and wizards, such as Page Designer, CSS Designer, and creating Web pages
from a JavaBean.
Even though this chapter does not assume that you are always in the Web
perspective of Application Developer, you may find it easier to perform the tasks
described here using the Web perspective.
Note that the intent of this chapter is to introduce you to the Application
Developer’s tools that make the development of Web applications possible.
Together we will work only on a single HTML page, a single servlet, and a single
JSP page. The rest of the application has already been developed and is made
available to you so that you can explore it if you would like to.
The RedBank application was designed using the MVC architecture pattern,
which we will cover in more detail in Chapter 10, “Developing Struts applications”
on page 293.
Because the same example is used throughout the book, you will have the
opportunity to see how little it changes in the face of varying design constraints
and evolving techniques. This is in fact the most important characteristic of the
MVC pattern.
We are now going to introduce you to how the application implements each of the
MVC layers, so that you feel more comfortable with its design.
Model
The RedBank application’s business model (Figure 7-1) is described in “Banking
model” on page 111, and the code is imported into the ItsoProGuideJava project.
Account TransRecord
Controller
The control layer was implemented using two different strategies: one
straightforward; and the other a little bit more complex, but more realistic. We did
so to keep the discussion in the book simple, but still have a nice example.
Three of the servlets, including the ListAccounts servlet that you will implement,
fall into the first category. They work as sole controllers, without any external
collaboration. It is easier to implement and understand them this way.
The last of the four servlets, PerformTransaction, falls into the second category.
It acts as a front controller, simply receiving the HTTP request and passing it to
the appropriate control action object. These objects are responsible for carrying
out the control of the application. For a more thorough explanation of this
strategy, and the motivation behind it, please read Chapter 10, “Developing
Struts applications” on page 293.
Note: Action objects, or commands, are part of the command design pattern.
For more information, refer to Design Patterns: Elements of Reusable
Object-Oriented Software.
The home page allows you to type the customer ID to access the customer
services. There is no dynamic content in this page, so we use plain HTML. Note
that security issues (logon and password) are not covered in this book.
The second Web page (Figure 7-3) displays the customer’s accounts for
selection.
The customer’s name and the available accounts are processed dynamically, as
they depend on the given customer ID, so we implemented this page as a JSP.
The maintenance screen also shows the current account number and balance,
both dynamic values. A simple JavaScript code controls whether the amount and
destination account fields are available or not, depending on the option selected.
If the user chooses to list the logged transactions, the Web page shown in
Figure 7-5 is displayed.
Finally, if anything goes wrong in the regular flow of events, the exception page is
shown to inform the user (Figure 7-6).
The only dynamic content in this page is the message displayed to the user. In
the example shown in Figure 7-6, we entered an invalid customer ID.
Facade
We will use a copy of the facade in the Web application. It is better to have the
facade in the Web application to be able to access a different model that is
implemented in another project (for example as EJBs).
Application flow
The flow of the application is shown in Figure 7-7:
The view layer is comprised of one HTML file (index.html) and four JSPs.
You will implement the index.html and the listAccounts.jsp.
The control layer is comprised of four servlets and four action classes. The
PerformTransaction servlet passes control to one of the action classes.
You will implement the ListAccounts servlet.
The model layer is comprised of the facade and four model classes. All
interactions from the servlets and actions classes go through the facade, the
Banking class.
The model is available in the ItsoProGuideJava project, which will be a utility
project in the enterprise application.
showException
Invalidate
Session ListTransactions Deposit Withdraw Transfer
Facade Banking
MODEL
Bank - Customer - Account - TransRecord
Web projects can be static or dynamic. Static Web projects are comprised solely
of static resources, which can be served by a traditional HTTP server (HTML
files, images, and so forth), and are useful for when you do not have to program
any business logic. J2EE Web projects, on the other hand, may deliver dynamic
content as well, which gives them the ability to define Web applications.
Most of the time you will just have to set the project’s name and type. In our case,
we are creating a new J2EE Web project named ItsoProGuideBasicWeb.
Advanced users may also want to change the other options on the window:
Use default—Deselect the check box to change the project file location.
Web project features—Select one or more of the various options to add
additional features to your Web project. When you select a feature, a detailed
description is provided for you. For now, we will just use a default CSS file.
Later on you will be introduced to more advanced features.
J2EE Web modules, such as the project we are creating, run exclusively within
enterprise applications. For this reason, you have to either select an existing
enterprise application project, or let the wizard create a new one for you.
Type ItsoProGuide in the New project name field. Optionally you can set the
advanced options on this page, which are:
Context root—The context root defines the Web application. The context root
is the root part of the URI under which all the application resources are going
to be placed, and by which they will be later referenced. It is also the top level
directory for your Web application when it is deployed to an application server.
Context roots are case-sensitive, so are all the Java URLs. Many developers
like to make their context root all lowercase in order to facilitate the manual
entering of URLs. The context root you select must be unique among all Web
modules within the same application server cell. Application Developer’s
default is to use the project’s name as the context root.
J2EE level—You usually want to select the greatest J2EE level that your
target application server allows. For WebSphere Application Server Version 5,
Click Finish and the enterprise application and the Web project are created.
Project properties
The project properties dialog can be used at any time to change dependencies or
to change the context root, J2EE level, and other features.
For example, to change the context root, open the properties and select the Web
page (Figure 7-12).
Important: Any files not under Web Content are considered design time
resources (for example .java and .sql files) and will not be deployed when
the project is published. Make sure that you place everything that should
be published under the Web Content folder.
– Web Content\META-INF
This folder holds the MANIFEST.MF file, which describes the Web module’s
external dependencies.
– Web Content\theme
Contains cascading style sheets and other style-related objects.
– Web Content\WEB-INF
This directory holds the supporting Web resources for the Web module,
including the Web deployment descriptor (web.xml), IBM WebSphere
extensions’ descriptors (ibm-web-bnd.xmi and ibm-web-ext.xmi), and the
classes and lib directories.
– Web Content\WEB-INF\classes
Contains the project’s Java compiled code for regular classes, JavaBeans,
and servlets. These are the Java classes that will be published to the
application server and loaded in run-time. The class files are automatically
placed in this directory when the source files from the Java Source
directory are compiled. Any files placed manually in this directory will be
deleted by the Java compiler when it runs.
– Web Content\WEB-INF\lib
Contains utility JAR files that your Web module references. Any classes
contained in these JAR files will be available to your Web module.
As mentioned earlier, you will only develop a small part of our sample application.
The rest of the resources have been made available for you and have to be
imported now.
Select File -> Import to open the import wizard. Select WAR file and click Next
to proceed to the second page (Figure 7-14).
Note: As you can see, you could have created the enterprise application
project, the Web project, and imported the resources in just one step using
this wizard.
The Context Root and Enterprise application project fields are automatically
filled in for you. Select Overwrite existing resources without warning and click
Finish to import the resources.
Page Designer
Page Designer is the main Application Developer tool used by Web designers to
create HTML pages. It is a WYSIWYG editor that generates the underlying
HTML code and frees the Web designer to concentrate on the visual aspect of
the page rather than on the details of HTML syntax. Page Designer currently
supports the HTML 4.01 specification.
The Page Designer shows three views of an HTML page: design, source, and
preview.
In the Design view the work is done visually.
In the Source view you manually edit the HTML code. You can use the content
assist feature, the same as for editing Java files. Pressing Ctrl-Space will
bring up a pick list of context-appropriate selections to choose from.
The Preview view shows what the page will look like to the user, and thus is
read-only.
Syntax validation
When you save an HTML page, it will not be automatically validated for syntax
compliance by default. To manually validate the syntax of an HTML page, select
Tools -> Validate HTML Syntax .
To demonstrate the basic capabilities of Page Designer, we will walk you through
the building of a simple HTML page. In the next section, we discuss in more
detail how to use servlets and JSPs to provide dynamic content on our
application.
The other important information that you have to provide on this page is the file
name, in this case index. You may or may not type the file’s extension. If you do
not, the .html extension is added for you by the wizard.
The other field lets you specify the document’s markup language. In our case, it
should just be the default value of HTML, but other options would be HTML
Frameset, XHTML, or XHTML Frameset.
Finally, there is the model field, but it is not used in the creation of HTML files.
Click Next to advance to the next page on the wizard (Figure 7-16).
It also permits that you change the content and document types. Your options
depend very much on the markup language that you chose on the previous page.
If you chose HTML, for instance, then the content type is limited to text/html and
the document type should be one of the following:
HTML 4.01 Strict—This is a downsized version of HTML 4.01. It allows for the
writing of more portable documents, because it emphasizes structure over
presentation. Deprecated elements and attributes, frames, and link targets
are not allowed in HTML 4.01 Strict. This document type depends very much
on style sheets for presentation.
HTML 4.01 Transitional—Includes all elements and attributes of HTML 4.01
strict, plus presentational attributes, deprecated elements, and link targets. It
is a more common document type because it shows nice in browsers that
have limited or no support for style sheets.
HTML 4.0 Frameset—This is a variant of HTML 4.01 Transitional, used for
documents that contain frames.
Finally, you can associate style sheets with the new document. By default, the file
Master.css is assigned, but you can add and remove files as you see fit. Click
Finish to complete the wizard.
Start by deleting the default text paragraph that the wizard generated. To do that,
simply select the whole paragraph (or click Ctrl-A) and then click the Delete
button.
We will now set the page title and add the meta tags that will tell the Web client
not to cache the page. Most of the times static pages can and should be cached
to improve on performance. However, our static page is referenced not only
directly (by its file name) but also by a servlet (InvalidateSession). We do not
want the Web client to use the cached page when the servlet is called. We
instead want the servlet to receive the request again.
Tip: You may alternatively copy and paste the text above directly to the HTML
source through the Source view.
The new table is inserted, and the first cell selected. Both cells should be of the
same size and very small, because they are still empty.
We do not want the table to have visible borders. Select the table (or any of its
cells) and Attributes (context) or select Window -> Show View -> Attributes. Set
the border attribute to 0 (Figure 7-19).
Now let’s fill the table with content. Select the left cell and type RedBank. We want
this text to be formatted as a heading 1. To accomplish this, select it and then
click Format -> Paragraph -> Heading 1. We also want the first three characters
(Red) to be in red. Select them and then click Format -> Font. Type red on the
color field and click OK.
The second table cell should contain an image: itso.gif. It was imported along
with the rest of the resources and can be found in the Web Content\images folder.
Open the thumbnail view by selecting Window -> Show View -> Thumbnail and
then select the images folder in the J2EE Navigator view. You should now see the
thumbnail of the imported image, as shown in Figure 7-20. Simply drag and drop
it into the second table cell. Alternatively you can also expand the images folder
and drag/drop the itso.gif file into the second table cell.
Our next task is to place a second heading on the page, right after the table that
we have just created. Type the text Welcome to the ITSO Bank and format the
text as a heading 2.
After the heading comes a form, where the user can enter information that will be
sent back to the server. Click Insert -> Form and Input Fields -> Form. The form
should have a descriptive text that reads Please, enter your customer ID in the
field below:, a text field named customerNumber (Insert -> Form and Input Fields
-> Text Field) and a Submit button (Insert -> Form and Input Fields -> Submit
Button, set the label to Submit). The elements should be separated by a blank
line. The resulting form should look like Figure 7-21.
To save the page and validate your changes, select File -> Save index.html, or
alternatively press Ctrl-S. You may now close the editor window.
In addition, the WAP Forum standard WCSS 1.0 (WAP CSS 1.0) is also
supported.
Application Developer provides a special editor to modify CSS files: the CSS
Designer. CSS Designer shows the source of a CSS file, and enables you to edit
styles with the help of syntax highlighting, content assist, and preview function.
The modifications made in CSS Designer are immediately applied to the design
page of Page Designer if the HTML file has a link to the CSS file.
To access the CSS Designer, double-click the existing style sheet in your Web
project (Web Content\theme\Master.css). This will bring up the style sheet editor,
comprised of source and preview panes, and the styles view (Figure 7-23).
Styles View
If you prefer, you can instead use the CSS Designer dialogs to edit or add styles
(accessible through the styles view, or through the style menu). These dialogs
are context sensitive and will open up on the style that is currently selected in the
editor.
Finally, the preview pane shows you how the styles will look like when applied to
an HTML file. By default, a sample HTML file is used, but you can choose to
preview the style changes with any file on your Web project.
For our example, we will change the appearance of two HTML elements: H1 and
H2. The first one will be edited directly through the source pane. Find the H1
style definition and manually change the color attribute to black. After edited, the
style source should look like the following:
H1
{
COLOR: black;
FONT-FAMILY: 'Times New Roman';
TEXT-TRANSFORM: capitalize
}
The second style will be changed via the editor's dialog. Double-click the H2 style
in the styles view to bring up the style properties dialog (Figure 7-24).
Save your changes and close the style editor. Open up the index.html file and
verify its new look (Figure 7-25).
The Web development wizards help you quickly create forms, HTML pages,
JavaServer Pages (JSPs), and Java servlets, even if you are not an expert
programmer. These files can be used as is, or modified to fit your specific needs.
To start it, select File -> New -> Other. Select Web -> Servlet and click Next.
Alternatively, you can switch to the J2EE Navigator view, select the Java Source
folder in your Web project folder, and select New -> Servlet from its context
menu. The wizard starts with the dialog shown in Figure 7-26.
The wizard’s first page will require you to fill out the following information:
Folder The source folder of your Web project. In our case, it is
\ItsoProGuideBasicWeb\Java Source.
Java package The package in which the servlet class will be created. For our
example, it should be itso.basicweb.control.
Class Name The servlet’s class name. We will implement the ListAccounts
servlet.
Superclass Usually, and this is true to our example, you will select the
javax.servlet.http.HttpServlet as your servlet’s superclass.
Application Developer requires you to select a class that
implements the javax.servlet.Servlet interface.
Click Next to proceed to the wizard’s second page, shown in Figure 7-27.
This page lets you select the appropriate method stubs to be created in the
servlet code. These are the servlet’s life-cycle methods, along with its service
methods specific to the HTTP protocol (the methods that start with “do”).
Only one instance of a servlet is created in the application server. If you want to
perform any initialization when the servlet instance is created, select the init
method to be created. This method is invoked after the servlet instance has been
created and you can perform the initialization tasks.
Another check box lets you select whether or not you want to generate stubs for
the inherited abstract methods. You should select it if your servlet is concrete.
Because constructors are not inherited in Java, you may also want to generate
constructors that call their counterpart in the superclass.
Finally, the wizard lets you choose whether or not to add the new servlet to the
Web deployment descriptor. If you choose to do so, and we do for our sample
application, you can also define initialization parameters and their values, and the
URLs mapped to the servlet. We will stick to the default URL mapping suggested
by the wizard, which equals the servlet name.
You can now click Finish to complete the process. The servlet is generated and
added to the project. In the J2EE Hierarchy view you can see the servlet and its
mapping in the Web module. In the J2EE Navigator view you can see the servlet
file ListAccounts.java inside the itso.basicweb.control package. An editor is
opened, where you can view and edit the generated servlet source code.
Start by adding these import statements to the statements generated for you:
import javax.servlet.http.HttpSession;
import itso.bank.model.Customer;
import itso.bank.model.Account;
import itso.bank.facade.Banking;
Next, change the doGet and doPost methods’ body to look like this:
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
performTask(req, resp);
}
As you can see, both methods call a third method, called performTask. Because
both doGet and doPost are read methods, and the Java API for handling the
request parameters is the same no matter the request type, this works fine.
Finally, you need to code the performTask method (see Example 7-1).
if (customerNumber == null)
customerNumber =
(String) session.getAttribute("customerNumber");
else
session.setAttribute("customerNumber", customerNumber);
We could have written the presentation code in the servlet if we wanted to do so.
Instead, we chose to use JSPs, which were specially designed for that purpose.
Servlets do not make very good Web presentation renderers, because writing
HTML code in Java is cumbersome.
The form’s action should be the ListAccounts servlet. But you do not have to
type that in yourself. Instead, click ... -> Servlet and select the ListAccounts
servlet from the pop-up list. Remove the Web application context root:
From: /ItsoProGuideBasicWeb/ListAccounts <=== absolute URL
To: ListAccounts <=== relative URL
Finally, make sure that the Post method is selected. The Attributes view is shown
in Figure 7-28.
You could have added the link to the servlet in the Source view as the action
attribute of the form:
<FORM action="ListAccounts" method="post">
Links view
Select index.html file and the Links view. You should see the files (CSS file and
image) and links (servlet, URL) that are used by the HTML file (Figure 7-29).
servlet
JSP files are edited in Page Designer, the very same editor you used to edit the
HTML page. When working with a JSP page, though, Page Designer has
additional elements (JSP tags) that can be used, such as JavaBean references,
expressions, and scriptlets containing Java code.
Creating a JSP
To create a JSP file, select the Web Content folder and select New -> JSP File
to open the new JSP file wizard (Figure 7-30).
Because you had the Web Content folder selected when you started the
wizard, the folder field comes filled in for you. Type the file name
(listAccounts.jsp) into the appropriate field. You do not have to type the file
extension, as it will be automatically added for you.
We will be using HTML as the markup language, so leave it as is. The options
are the same as when you created a new HTML page.
If you select the Create as JSP Fragment check box, this file will be created
as a fragment that can be added to another JSP file. Other JSP files can
include JSP fragments using a JSP include directive. Creating a fragment
causes the resulting file to end in a .jspf or .jsf extension. You will not be
prompted for DOCTYPE information, because a fragment cannot stand alone
as a Web page, and it would invalidate any JSP file that included it.
We want the wizard to generate code without using any special models, so let
the model field be set to none. Your other option would be to generate a
Struts JSP page, but that will be left for Chapter 10, “Developing Struts
applications” on page 293.
Note: We will work with tag libraries in Chapter 10, “Developing Struts
applications” on page 293.
We will skip working with tag libraries for now, so just click Next to proceed to the
third page (Figure 7-32).
This page lets you supply page directive information for the JSP file:
It allows you to choose the scripting language (Java is the preferred language,
but you can also choose Javascript if you would like), set the imported types
and packages, and configure the set of directive attributes.
If you do not select an attribute’s check box, it means that it will be assigned
the default value, which you can tell by checking the disabled radio group.
First of all, add the packages java.util and itso.bank.model to the imports
list by clicking Import Package once for each package.
Then, because we do not need a session variable in our JSP page, check the
Create Session Variable box and set its value to false.
Note that the default for a session variable in a JSP is true.
The wizard’s fourth page lets you supply the JSP encoding, DOCTYPE, and style
sheet information, just like when we created our HTML page.
Leave the options to their default values and click Next to continue to the last
page (Figure 7-34).
This last page lets you select which JSP method stubs you would like the wizard
to generate, and whether or not to add deployment information to the Web
project's deployment descriptor file.
Because we do not need to add behavior to the life-cycle methods, leave both
init and destroy unchecked.
Finally, if you select the Add to web.xml check box, the JSP file, along with its
display name, and any URL mappings and initialization parameters
associated with the JSP file, will be automatically included in the Web
project’s deployment descriptor file. We do not want to do that because our
JSP’s client is the ListAccounts servlet, and not an external Web client.
Note: The File Name value provided in the first page of the wizard is
automatically mapped to the Servlet Name value on this page, as well the
URL Pattern mappings. These mappings are not updated if you go back and
change the original value in the File Name field.
Click Finish to complete the wizard and create the file. The JSP file is added to
the Web Content folder and opened for editing.
You can customize the recently created JSP file by adding your own static
content, just like you would to a regular HTML file. Along with that, you can use
the standard JSP declarations, scriptlets, expressions, and tags, or any other
custom tag that you might have retrieved from the Internet or developed yourself.
Switch to the Design view if you are not already at it. Clear the default text
paragraph that the wizard generated, just like you did with the HTML file. Then
set the page title to RedBank: Customer's Accounts.
Also, just like you did before, add the two column table to hold the bank’s logo.
The left column should contain the RedBank string (with the first three characters
in red). The logo image should be placed on the column to the right.
Insert an HTML form right after the heading 2. The form’s action should point to
the AccountDetails servlet, and should be an HTTP post. Configure these
attributes just like we did with the index page (“Linking an HTML page to a
servlet” on page 209).
We are telling the browser to call the cancel function (to be defined in a moment)
when the button notifies the click event.
Find the </HEAD> tag and place your cursor right before. Insert a line break so
that the source will look nice, and manually enter the following script:
<SCRIPT language="JavaScript">
function cancel()
{
window.navigate("InvalidateSession");
}
</SCRIPT>
</HEAD>
As it is the case with source code in other languages, you can also use the code
assist feature to suggest options or complete your JavaScript code.
Inserting a link
Finally, we will create the HTML link to the Redbooks Web site. Switch back to
the Design view and type For more information on ITSO and RedBooks, please
visit our Internet site at the very end of the document. Just like you did before,
select the string Internet site and select Insert -> Link. On the URL field, enter
http://www.redbooks.ibm.com.
The resulting page’s Design view should be looking like Figure 7-35.
Up to this point we have just inserted static content into the JSP page, nothing
different from what you did when you edited the index.html file. Now it is time for
us to insert the dynamic elements into the page.
First, we need to declare the two JavaBean parameters that will be sent by the
controller servlet (ListAccounts), so that we can use them later on the page.
Their IDs are customer and accounts (see Example 7-1 on page 208).
While in the Design view, place you cursor before the table, or press Ctrl-Home.
Select JSP -> Insert Bean. The dialog in Figure 7-36 is displayed.
The customer bean will be passed as a parameter to this page in the request
scope and not as a serialized bean from a file. Select Bean for the type and
Request for the scope.
We do not have to specify the bean’s class, because we do not want an object to
be created from scratch if it is not found in the specified scope. Leave the class
field blank and enter itso.bank.model.Customer in the type field. You can click
Browse to find the bean’s type instead of having to type it.
Click OK to complete the wizard. The following code is added to your JSP page,
right below the <BODY> tag:
<jsp:useBean id="customer" type="itso.bank.model.Customer"
scope="request">
</jsp:useBean>
Repeat the above process for the accounts bean. The resulting JSP tag should
be:
<jsp:useBean id="accounts" type="itso.bank.model.Account[]"
scope="request"></jsp:useBean>
The <useBean> tag for an array results in a warning. To remove the warning we
can declare the accounts variable directly. Replace the <useBean> tag with this
code:
<% Account[] accounts = (Account[])request.getAttribute("accounts"); %>
Now that both beans have been declared, we can use them to display dynamic
data to the user. We want to substitute the Someone string for the customer’s
name.
Select the string in the heading 2 paragraph and simply delete it. With the cursor
positioned right before the apostrophe, select JSP -> Insert Get Property and the
dialog shown in Figure 7-37 appears.
This dialog presents you with the list of all available beans to be used in the point
of insertion. Find the customer bean, expand it by clicking the plus sign, and
select the firstName property. The rest of the fields should automatically be filled
in for you. Click OK to close the dialog.
Now insert a blank space and repeat the above process for the customer’s last
name. The resulting JSP code added should look like this:
<H2><jsp:getProperty name="customer" property="firstName" />
<jsp:getProperty name="customer" property="lastName" />'s Accounts</H2>
Because this JSP displays a list of accounts for a customer (a customer may
have many accounts), it has to loop through the resulting collection of accounts.
To support this without using external taglibs, you have to insert a scriptlet with
Java code.
Note: Ideally, a JSP page would have no Java code at all, just JSP tags. The
intent of this scripting language is to enable Web designers that might not be
proficient in the Java language to write Web presentation to Java applications.
To a certain extent, this can be achieved without any further complications. So
far we have already used JSP tags but have written no Java code whatsoever.
In certain situations, though, as with loops, we cannot skip using Java
scriptlets unless we choose to use external taglibs, like the Java Standard Tag
Library (JSTL).
Note that the Java code has opened a loop block which but not closed it. We will
look into that in a short while. What we essentially did here was to get an iterator
for the accounts collection, previously declared, start a WHILE loop to iterate
through the account objects in that collection, and finally select the current
account object and assign it to the account variable.
We want this current account to show up as an option in the list box. After the
scriptlet but still within the select body, insert the following HTML tag:
<OPTION value="<%=account.getId()%>"><%=account.getId()%></OPTION>
Note that in the middle of the HTML code we put two identical JSP expressions.
These expressions will be substituted by the account ID at runtime, which is
essential what will be displayed to the user.
Finally, complete the loop by inserting another scriptlet with the loop’s closing
curly braces. The final code should look like this:
<SELECT size="2" name="accountList">
<%
for (int i=0; i < accounts.length; i++) {
Account account = accounts[i];
%>
<OPTION value="<%=account.getId()%>"><%=account.getId()%></OPTION>
<% } %>
</SELECT>
This completes the code for the JSP. You can test the visual aspects of it by
selecting the preview view Page Designer. Figure 7-38 shows the finished JSP
design and preview.
The JSP tags are shown as icon boxes. Double-click a JSP tag icon and view the
definition in the Attributes view, or view the content in the Source view.
You can see that the JSP tags are not displayed in the preview pane. Neither are
their results, of course. They can only be obtained by a J2EE application server,
at run time.
Make sure you are at either the design or the Source view and save your work.
Close the source editor.
While the server is starting, you can check its initialization message log on the
Console view. If the view is not visible, select Window -> Show View -> Console
from the menu bar. You will know that the server is ready when you read the
message “Server server1 open for e-business“.
Select the ItsoProGuideBasicWeb project and Run on Server (context). When you
run a Web project itself, instead of a single HTML file, then the welcome page is
displayed. Welcome pages are defined in the deployment descriptor (web.xml) on
the Pages page. Usually the index.html file is the first in the list.
The Web browser window opens and displays the index page (Figure 7-2 on
page 182). In the customer ID field, type any number from 101 to 106 and submit
the form. The resulting page (Figure 7-3 on page 182) should display the
selected customer’s account list.
Filters typically include logging filters, image conversion filters, encryption filters,
and MIME type filters. Although filters are not servlets, their life cycle is very
similar.
Web Container
Filter 1 Filter 2
doFilter doFilter Resource
Note: This is a simple example that uses a file for auditing. Such a design
should not be used in a real application.
To create a new filter in Application Developer, open the J2EE Navigator view of
the ItsoProGuideBasicWeb project.
Select the itso.basicweb.filter package and New -> Filter from the context
menu to start the New Filter wizard (Figure 7-42).
In the Filter Name field, type TransactionAuditingFilter. Our filter will audit
every transaction that is performed with the bank accounts, logging the
transaction type, time stamp, and parameters, as well as the client’s hostname
and IP address.
The wizard’s second page lets you select method stubs and deployment
descriptor information.
The filter has to be added to the Web deployment descriptor. Configure the
initialization parameter by clicking the respective Add. Enter pathname for the
parameter name and c:/transactionAudit.txt for its value.
Finally, we have to set with which servlets this filter should be associated. Click
the respective Add to open the Choose a Servlet dialog. Select
PerformTransaction and click OK.
The auditFile property holds a reference to the audit file. Generate its getter
and setter methods by selecting the field in the Outline view and Generate Getter
and Setter from its context menu. Change the generated method access
modifiers from public to private (Figure 7-44):
Figure 7-44 Getter and setter methods for the auditFile property
The audit file should be opened upon the filter initialization. Edit the init method
as shown in Figure 7-45.
After opening the file for both read and write access, we move the file pointer to
the end, so that the file can be appended instead of overwritten.
Because we opened the file in the init method, we have to close it in the
destroy method (Figure 7-46).
synchronized (getAuditFile()) {
getAuditFile().writeBytes(output);
}
System.out.println(output);
chain.doFilter(request, response);
}
Save your changes and close the editor. The next time you perform a transaction
with any of the accounts, the audit file c:\transactionAudit.txt is created and
populated. See Figure 7-54 on page 236 for sample output of the filter (and the
listener that we create next).
Listeners are available for life-cycle events and for attribute modification events.
The listener developer creates a class that implements the interface
corresponding to the desired listener functionality:
javax.servlet.ServletContextListener
Receives javax.servlet.ServletContextEvent events that notify that a
servlet context has just been created or is about to be destroyed.
javax.servlet.ServletContextAttributeListener
Receives javax.servlet.ServletContextAttributeEvent events that notify
that an attribute in the servlet context has been added, removed, or modified.
javax.servlet.http.HttpSessionListener
Receives javax.servlet.http.HttpSessionEvent events that notify that an
HTTP session object has just been created or is about to be destroyed.
javax.servlet.http.HttpSessionAttributeListener
Receives javax.servlet.http.HttpSessionBindingEvent events that notify
that an attribute in an HTTP session has been added, removed, or modified.
Note that the same listener may implement any combination of the above
interfaces. At application startup time, the container uses introspection to create
an instance of the listener class and registers it with the appropriate event
generators.
Select the itso.basicweb.listener package under the Java Source folder and
then select New -> Life-cycle Listener from the context menu to start the New
Life-cycle Listener wizard (Figure 7-48):
All the default values are suitable, just click Finish to complete the wizard. The
listener is created and added to the Web deployment descriptor. A Java editor is
also opened on the listener class Java file.
The first method we will enter calculates an object’s size when serialized. This
method is useful for determining how much space a session or one of its
attributes would take if they would be serialized to a database. Add the size
method as shown in Figure 7-50.
The next helper method that has to be created is called report. It handles the
printing of messages to the standard output (Figure 7-51).
To get rid of all the errors from undefined classes, select Source -> Organize
Imports and the required import statements are added to the code.
Save your changes and close the editor. Run the application to see the results of
your work. The listener’s messages should show up on the Console view.
Figure 7-54 contains an extract from the Console showing the output of both the
filter and the listener.
The JavaBean Web Pages Wizard supports the following activity models:
Set bean properties—Create an input form that collects input from users and
stores the resulting data within the properties of a Java bean.
Retrieve bean properties—Create a result form that displays a bean's current
property values.
Execute a bean's method(s)—Run any number of methods from a bean by
submitting an input form.
Execute a bean's method(s) with parameters—Create an input form that
collects data from users, and use this data as input to a bean's methods.
Display a method's result—Create a result page that displays the return value
of a method.
Combination—Create a set of pages that include any combination of the
above models.
For the sole purpose of demonstrating the wizard, we are going to redo the same
two pages and one servlet we did before (index.html, listAccounts.jsp and
ListAccounts). You will then be able to compare the two approaches.
To better organize your code, create a new folder under Web Content named jbwp
(as in JavaBean Web pages).
The Destination folder field should have come up already filled in, since you
had the folder selected. In the Java package field, type itso.jbwp. We do not
want the code mixed with the old application.
The model selection drop-down currently only has one entry: View Bean. This
code generation model uses view helpers, which are Java wrapper classes
that manage all the model interaction.
The rest of the dialog is simply informative. Selecting the Files field values
displays a description.
Figure 7-56 JavaBean Web pages wizard: select bean and methods
The second step consists of selecting the JavaBean that will act as the model
for the generated pages, and selecting which of its properties and methods
the pages should be created for.
Click Browse to bring up the Choose Java Bean dialog. Type Banking in the
Choose Java Bean field. The dialog presents you with the matching types,
but the list is probably going to be limited to just one occurrence. Select the
appropriate type (Banking) and package (itso.bank.facade) and click OK.
The wizard automatically introspects the bean and presents you with the list
of available properties and methods. You do not have to click Introspect
unless you type in the class name directly.
Select the getCustomer and getAccounts methods. We only want to retrieve
the customer and its accounts.
The third wizard’s page lets you select the style sheets you want associated
with the generated pages. By default, Web Content\theme\Master.css comes
selected, and that is enough for us. You may add, remove, or change the
priority of style sheets by clicking Add, Remove, and the arrow buttons,
respectively.
Here you may also select whether or not the wizard should link the given error
page to the generated pages. Note that the wizard will not generate the error
page. It will just declare it in the generated pages’ page directive for you. We
do not need that behavior.
The default setting for storing the results is Request, the option that you
should select for this example. Selecting Request means that the method
results will only be available for the duration of the HTTP request. If you want
the results to be preserved for the lifetime of the user session, choose the
Session option. If the results occupy too much memory, this may not be the
best approach.
You can then choose how you would like the wizard to generate control layer
code for you. You may want to generate a new controller servlet, to reuse an
existing one, or not to use a controller servlet at all (in which case the wizard
would generate view and control code in the JSPs). Select the Create a new
Front Controller option.
This page lets you see and configure how the generated input HTML file will look
like:
Select the getCustomer method and clear its Label property.
Select the customerID item under the getCustomer method and configure its
label to Enter a customer number:
Deselect the getAccounts method and customerID under it, we only want one
input field for the customer number.
Select the Page tab and set the Page Title field to RedBank.
Using this page you can determine and configure how the response JSP will
look:
Use the arrows to move getAccounts under getCustomer (if the sequence is
reversed).
Select the getCustomer method and clear its Label property.
Select the getCustomer result (right under the getCustomer method) and set
its Label property to Customer:.
Expand the getCustomer method and select both firstName and lastName
properties. Select each field and change the labels to First name: and Last
name:.
Expand the getAccounts method, select it, and clear its label.
Select the getAccounts under it and set its label to Accounts: and its layout
style to table (use the drop-down menu).
Open the ListAccountsResultsForm.jsp file and find the method calls. Change
the getAccounts call:
itso.bank.model.Customer methodResult0 = listAccountsBean.getCustomer
(new java.lang.String(request.getParameter
Rename
Note that if you rename the files, you have to configure the initialization
parameters of the controller servlet (ListAccountsController) in the web.xml
deployment descriptor.
Enter a customer number (102) and click Submit. The name of the customer and
the accounts are displayed. A sample run is shown in Figure 7-61.
We also used the JavaBean Web Pages Wizard to generate a Web application
from a JavaBean.
Which of these methods you choose depends on the nature of your application
and the complexity of your database access. From the perspective of separating
the layers of your application, using separate JavaBeans for the database access
may be more appropriate because you are not mixing presentation and database
logic in the JSP as you do when using DB Beans or JSP tags.
In the following sections we discuss the wizard that can be used to create a view
bean or a taglib application starting from an SQL statement. We then look a bit
more closely at the DB Beans classes and JSP tags.
To start the wizard, click File -> New -> Other. In the New wizard, select Web in
the left pane and Database Web Pages in the right pane, then click Next.
Figure 8-3 Create Database Web Pages wizard: select SQL statement
You have two choices: use an existing SQL statement, or build a new one:
If you already have an existing SQL statement in the statement folder of a
database project, you can select it here and use that to generate the Web
pages.
We select the ListCredits SQL statement that we built in “Using SQL Query
Builder” on page 171 and click Next.
Clicking Next displays the page where you decide how you want to access the
database when the generated application is run (Figure 8-4). You can choose to
use a direct connection or use a data source. For a discussion about these two
different ways of connecting, see “Data source versus direct connection” on
page 141.
In this case we use the data source connection. We specify the JNDI name of the
data source, which in our case is jdbc/ejbbank.
On the next three wizard pages you can view and change the pages that will be
generated by the wizard.
The first page is the View Bean Data Page, where you can specify the style
sheet, error page, whether to store results in the session or request object, and
whether or not to create a Front Controller, use an existing one, or not use one at
all (Figure 8-5).
The Store results option determines where the results from the query should be
stored. You can choose to store them in the session, in which case they will be
available to other pages for the life of the session, or in the request. You should
be aware of potential memory issues if you choose to store a large result set in
the session.
On the following page, you see the HTML input form (Figure 8-6).
Figure 8-6 Create Database Web Pages wizard: design input form
Here you can make some changes to page and field properties. Notice that the
two input fields are automatically generated. This is where the :type and
:lastname host variable values will come from.
Select each host variable and change the label to the desired text, for example,
Transaction type and Last name.
Once this and the following pages have been generated, you can make further
changes using Page Designer.
The next page shows the master result page. The default is to use a table to
display the result rows from the query (Figure 8-7).
Here you can change the heading of the columns and page properties. If you do
not want to show one or more of the fields retrieved from the query, you can
deselect them in the top left pane. Typically, you would only select a subset of
the fields for the master table.
To change the labels, select the item in the top left pane and make your changes
in the bottom left pane. Typically, you would change the headings of the table to
short descriptive names.
The next page shows the default form for showing details of a selected row in the
details view page (Figure 8-8). You can make the same type of changes here as
on the master table view page to improve the look of the page.
Finally, you can specify the default prefix for all generated objects (Figure 8-9).
Clicking Finish generates the Java classes and HTML/JSP pages.
These steps assume that a WebSphere v5.0 Test Environment server has
already been created, as explained in “Creating a server for testing” on
page 224.
Open the Server perspective and edit the server configuration of the ItsoServer:
Go to the Data source tab.
Under Server Settings, select the Default DB2 JDBC Provider from the JDBC
provider list and click Add next to the data source list. The Create a Data
Source dialog is displayed (Figure 8-10).
Select DB2 JDBC provider and make sure Version 5.0 data source is selected,
then click Next.
In the Modify Data Source window, as shown in Figure 8-11, enter EJBBANK as the
name and jdbc/ejbbank as the JNDI name. This name has to match the name
used in your application.
Deselect Use this data source in container managed persistence (CMP). For now
we do not have any EJBs.
Click Next to continue to the next page of the wizard, as shown in Figure 8-12.
On this page, modify the databaseName field to be EJBBANK.
Select databaseName in the Resource Properties list, then enter EJBBANK in the
Value field. This is the only required property.
The Data source page of the server configuration is shown in Figure 8-13. Note
that you have to select a driver in the JDBC provider list to see the data sources
defined for that driver.
The data source is now defined, so press Ctrl-S to save the server configuration.
If the server was running, it has to be restarted before running the application
that uses the data source.
The documentation for the classes in the package can be found in:
<wsadhome>\wstools\eclipse\plugins\com.ibm.etools.dbjars_5.0.1\jars\
dbbeans_javadoc.zip
A simple example of a JSP that executes an SQL statement using the DB Beans
classes is shown in Figure 8-15.
Note: This code was created using Page Designer by visually inserting beans
and scriptlets. To test the JSP, select Run on Server from its context menu.
There is a small number of classes in the DB Beans package, and they are
straightforward to use.
%>
</BODY>
</HTML>
The next section describes the JSP tags that have been built on top of the beans
to make it even easier to provide database access functionality to your Web
application.
Note: The code referred to in this section can be generated using the
Database Web Pages wizard and selecting the IBM Database Access Tag
Library - Select Statement model. Refer to “Generate Web pages from SQL
queries” on page 249.
If you decide to use the JSP tags, you should be aware that there are some
restrictions compared to using the beans directly:
For any of the JSP SQL actions that require a connection to the database, a
connection is opened when the tag is encountered, and closed after the tag
has been processed. Two actions cannot be performed within the same
transaction scope, or even using the same JDBC connection. The only
To use the JSP database tags, you have to import the following two JAR files to
the Java build path into the WEB-INF\lib folder of your project:
<wsadhome>\wstools\eclipse\plugins\com.ibm.etools.dbjars_5.0.1\jars\jspsql.jar
<wsadhome>\wstools\eclipse\plugins\com.ibm.etools.dbjars_5.0.1\jars\dbbeans.jar
Creating a JSP
We now create a TestTagLib.jsp file to use tag libraries. See “Working with
JSPs” on page 210 for details about creating a new JSP.
Open TestTagLib.jsp in Page Designer. You can use the JSP editor to insert the
database tags into your page when you are in the Design view. To be able to use
the custom tags from the database tag library, you first have to do two things:
Import the tag library into your Web application as described above.
Create the taglib directive in the JSP.
To insert the taglib directive, bring up the context menu on the page in the Design
view and select Page Properties. In the dialog shown select JSP Tags and JSP
Directive - taglib from the Tag Type drop-down menu (Figure 8-16).
Click Add to select the tag library to add, and the dialog shown in Figure 8-17 is
displayed.
Click Import to locate the jspsql.jar file to import. The Import a Tag Library
dialog opens (Figure 8-18). Click Browse to locate the JAR file:
<wsadhome>\wstools\eclipse\plugins\com.ibm.etools.dbjars_5.0.1\jars\jspsql.jar
Click OK to close the dialog. Now the tag library has been imported. Select the
jspsql check box to add it to the JSP (Figure 8-19).
Select OK twice to close the dialog. The following tag is inserted into your JSP:
<%@taglib uri="jspsql" prefix="dab"%>
First, we have to create the connection to the database. To do this we use the
<dab:dataSourceSpec> tag. Select dataSourceSpec in the left list, then click
Insert. Click Close, then go to the Source view of the JSP editor. The following
new code has been added:
<dab:dataSourceSpec dataSource="" id="" />
Figure 8-21 shows the correct parameters and values to use for the
<dab:dataSourceSpec> tag. Update the tag in your JSP.
All the parameters for the connection are retrieved from the data source defined
in the server.
Tip: In the Properties view (Window -> Show View) you can see the properties
of each tag when you place the cursor within the tag.
Once you have established a connection, you can execute the query. Click JSP
-> Insert Custom again, and this time choose select and click Insert. Update the
new select tag to be the same as in Figure 8-22.
Here you use the connection created previously to issue the SQL select
statement. The input parameter is specified using the <dab:parameter> tag.
Assuming that you have created an HTML table to display the result, you can
then use <dab:repeat> and <dab:getColumn> to loop through the result set and
display the values. You can either use the insert custom method to get you
started, or enter the code shown in Figure 8-23.
As you can see from the discussion above, both the DB Beans and the
corresponding JSP tags give you an easy and quick way to access relational
data directly from a JSP. As was mentioned earlier, you have to be aware of the
potential problems of combining presentation and business logic in one JSP.
Summary
In this chapter we used the wizards within Application Developer to create
dynamic Web pages using SQL queries. We showed how to access databases
from a Web application, both by using the database Web page wizard and by
creating your own JSPs using tag libraries.
Tip: When building stored procedures with DB2 be sure to use the DB2 app
JDBC driver. Using the BD2 net JDBC driver is unstable and may not work.
Note: The support for stored procedures varies between different data base
management systems. We are using DB2 stored procedures in the example.
In the SQL Statement window (Figure 9-3), you have several options for entering
an SQL statement:
We recommended that you use the SQL Statement Wizard by clicking SQL
Assist (see “Using the SQL Statement Wizard” on page 165).
You can enter the statement manually by typing the statement:
SELECT CUSTOMERID, TITLE, FIRSTNAME,
LASTNAME, USERID, PASSWORD
FROM
ITSO.CUSTOMER
WHERE
ITSO.CUSTOMER.CUSTOMERID = :customerID
This statement gets all fields from the customer table given a customer ID.
We use one SQL statement (you can click Add to enter multiple statements).
Click OK when done.
Figure 9-3 Specifying the SQL statement for the stored procedure
Click Next to go to the next page of the wizard, where you specify parameters for
the stored procedure (Figure 9-4):
If you used SQL Assist to create the SQL statement, the parameter is already
filled in.
If you typed the SQL statement, you have to create the parameter manually
by clicking Add and specifying In (as mode), customerID (as name), and
INTEGER (as SQL type).
Click Next, and a summary of the stored procedure is shown (Figure 9-6).
Click Finish to create the stored procedure. You can see the getCustomer stored
procedure in the Stored Procedures folder.
/**
* JDBC Stored Procedure ITSO.getCustomer
* @param customerID
*/
package itso.storedproc;
Here we see that the build was successful. The GetCustomer class is compiled
and placed into a JAR file, and the JAR file is installed in the target database.
Tip: You can see stored procedures in the DB2 database system by opening
the Control Center.
Tip: You can make changes to the stored procedure by selecting Properties
(context).
The ? is a place holder for a parameter. The second line sets 104 as the value for
the parameter. Following that, the stored procedure is executed and the results
are obtained from the result set.
Import the code into a new itso.storedproc.main package. A neat way to run
the main program in the Web application is by using the universal test client:
Start the ItsoServer.
Select the GetCustomerMain program and Launch Universal Test Client
(context).
A Web browser with the universal test client opens with an instance of
GetCustomerMain created (Figure 9-11).
Select the GetCustomerMain instance to expand.
Select the main method.
Click Expand to expand the String array the parameter.
Click Add to create an entry.
Enter a customer ID, for example, 104.
Click Invoke.
The result output is in the Console view.
The last page (Figure 9-15) is a confirmation page that shows the methods
that are generated. Click Finish.
A simple JSP to execute the JavaBean is shown in Figure 9-16. The code is
available in:
\sg246957\sampcode\dev-proc\RunGetCustomerBean.jsp
<BODY>
<H1>JSP -> JavaBean -> Stored Procedure</H1>
<jsp:useBean id="getCustomer"
class="itso.storedproc.bean.GetCustomerBean"></jsp:useBean>
Figure 9-16 Simple JSP to execute the JavaBean with the stored procedure
Tip: Restart the enterprise application in the server after making changes to
the Web application deployment information.
To make the tag library available for the Web application, we have to import the
JAR file into the lib directory and add the tag library to the deployment
descriptor:
Select the ItsoProGuideStroedProcWeb\Web Content\WEB-INF\lib folder and
Import (context). Select File system, then locate the directory:
<wsadhome>\wstools\eclipse\plugins\com.ibm.etools.dbjars_5.0.1\jars
Select only the jspsql.jar file and click Finish.
Open the deployment descriptors (web.xml). On the References page, select
the JSP tag libraries tab. Click Add and select the jspsql tag library. Save the
deployment descriptor.
Figure 9-17 shows a sample JSP that uses the tag library to execute the stored
procedure. The code is available in:
\sg246957\sampcode\dev-proc\RunStoredProcedure.jsp
This wizard is described in “Creating Web pages from a JavaBean” on page 237,
therefore we only provide short instructions here to run through the wizard:
Select New -> Other -> Web -> JavaBean Web Pages.
Select /ItsoProGuideStoredProcWeb/Web Content as destination and
itso.storedproc.web as package.
Select itso.storedproc.bean.GetCustomerBean as the bean. Click Introspect
if necessary.
Select the rows property (the result of the stored procedure) and the execute
method (to run the stored procedure).
Select Create a new front controller.
Tailor the input page with:
– Title: Execute Stored Procedure
– Prompt: Enter a customer ID:
Tailor the result page with:
– Title: Stored Procedure Results
– Label for rows property: Customer
– Expand rows, select the six properties (all except class), and set short
labels for all the properties (Title, Lastname, UserID, Password, ID,
Firstname)
Leave GetCustomerBean as prefix and click Finish to generate the code. You
get a servlet, an HTML input page, and a result JSP:
GetCustomerBeanController.java
GetCustomerBeanInputForm.html
GetCustomerBeanResultsForm.jsp
To test the generated application, restart the enterprise application (select the
ItsoServer and Restart Project -> ItsoProGuide) or restart the server.
You can skip the rest of the dialog and click Finish.
Test the procedure by selecting Run. Enter 106-6001, 106-6002, and 100.00 as
parameters. The DB Output view (Figure 9-22) shows the result value in the
Parameters tab.
Tip: The database is not updated by default. Select the transferMoney stored
procedure and Run Settings (context). On the Options tab you can select
Commit changes to the database.
Using a JSP
We provide the RunTranfer.jsp to execute the transferMoney stored procedure.
The core code is shown in Figure 9-23.
We also showed how stored procedures can be invoked through JavaBeans and
JSPs.
By using Struts you can get a clean separation between the presentation and
business logic layers of your application. Struts also speeds up Web application
development by providing an extensive JSP tag library, parsing and validation of
user input, error handling, and internationalization support.
The scope of this chapter is not to teach you the Struts framework in detail, but to
show how to use Application Developer’s Struts tools for building a Struts Web
application. To learn more about the Struts framework, please refer to the official
Jakarta project Struts home page and the official Struts user guide at:
http://jakarta.apache.org/struts
http://jakarta.apache.org/struts/userGuide/introduction.html
There is also a number of very good Struts tutorials available on the Internet.
Note: Application Developer 5.0 includes support for Struts Version 1.02 and
Version 1.1 beta 2. At the time of writing, the latest version of the Struts
framework is version 1.1 Release Candidate 1.
This separation can be achieved through the layering of the component into:
The model layer, responsible for implementing the business logic.
The view layers, each responsible for rendering the user interface (be it
graphical or not) to a specific client type and in a specific fashion.
With these two layers, we can implement the business logic and present it to the
user. That solves only half of the problem. We would also like to be able to
interact with the model. The implementation of this interaction is better left to a
third layer, called controller.
Model
The model layer manages the application domain’s concepts, both behavior and
state. It responds to requests for information about its state and responds to
instructions to change its state.
Just like any software component, the model should have a well-defined and an
as simple as possible public interface. This is usually achieved through the use of
a facade. The intent of facades is to provide a simple and unified interface to the
otherwise complex model that lies behind it. By doing so, we reduce the
dependencies between the model classes and its clients. Less dependencies
mean more freedom to adapt to new requirements.
Figure 10-1 shows the model layer with its encapsulated business domain
objects and the exposed facade object.
Model
Façade
Please note that the model does not have any dependences on views or
controllers.
View
The view layer implements a rendering of the model. The responsibility of the
view is to know what parts of the model’s state are relevant for the user, and to
query the model for that information. The view retrieves the data from the model
or receives it from the controller, and displays it to the user in a way the user
expects to see it.
Controller
The controller’s responsibility is to capture user events and to determine which
actions each of these events imply, depending on both the user’s and the
application’s state. This usually involves verifying pre- and post-conditions.
These actions can then be translated to messages to the model and view layers,
as appropriate.
A B <=> A depends on B
Controller View
Model
Action
: JSP
ActionServlet Action Model
: ActionForm
Action
configuration
Application file Action
Resources
Struts Support
Figure 10-4 shows the flow of information for an interaction in a Struts Web
application.
HTTP setXxx()
validate()
execute() getXxx()
setXxx()
"forward"
forward()
getXxx()
A request from a Web browser reaches the Struts ActionServlet. If the action
that will handle the request has a form bean associated with it, Struts creates the
form bean and populates it with the data from the input form. It then calls the
validate method of the form bean. If validation fails, the user is returned to the
input page to correct the input. If validation succeeds, Struts calls the action’s
execute method. The action retrieves the data from the form bean and performs
the appropriate logic. Actions often call session EJBs to perform the business
Note: In Struts version 1.0 the execute method of the Action class was called
perform.
The application is a banking application that allows a customer to enter his or her
customer number, select an account to work with, and then to perform four
different transactions: list the transactions for the selected account, deposit,
withdraw, and transfer money. The back-end of the application is, for sake of
simplicity, implemented as simple JavaBeans. We will implemented the back-end
using EJB technology in Chapter 12, “Developing EJB applications” on page 373.
Because the Struts framework provides us with the controller and view parts of a
Web application, but not the model, we will reuse the model from the RedBank
application and simply show you how to replace its controller and view with
Struts.
After having used the wizards to create some components (JSPs, form beans,
actions) you may be able to create new components even quicker by copying
and pasting from your existing components than by using all the wizards.
Alternatively you can create the itso.bank.facade package manually and import
the Banking class from the \sg246957\sampcode\dev-struts\initial\facade
directory.
Updating ApplicationResources.properties
The wizard created an empty ApplicationResources.properties file for us and
we have to update it with the texts and messages for our application.
While developing Struts applications, you will usually find yourself having this file
open, because you will typically add messages to it as you go along writing your
code. Figure 10-10 shows an extract of this file.
In the Web perspective, expand Java Source and then open the
itso.strutsweb.resources.ApplicationResources.properties file.
Replace then contents of the file with the contents in:
\sg246957\sampcode\dev-struts\initial\ApplicationResources.properties
Press Ctrl-S to save the file and then close the editor.
The icons on the right are to place new components into the empty diagram.
The icons are connections, actions, form beans, JavaBeans, JSPs,
sub-diagrams, and Struts modules.
Components in gray are not yet implemented, meaning they are only available in
the Web diagram and not as an underlying file such as a Java class or JSP.
Tip: You can select a component in the diagram and from the context menu
select:
Change Path to change the name of a JSP or action
Edit the forward name to change the name of a connection
Change Description to add descriptive text to any components
To improve the layout of the application flow, you can drag components to
another spot and you can rearrange connections by dragging their middle
point.
We choose to implement the form beans first to have full control over their
contents and structure.
On the third page of the wizard we can enter the fields we want our form bean
to hold. Click Add and add each of the following fields (Figure 10-15):
customerNumber String
customerName String (firstname lastname)
accountNumber String (after selection)
accountNumbers String[] (list retrieved from customer)
validateKey String (1 or 2, which action)
Click Next.
Note: Make sure you press Enter after entering the text in each field.
Otherwise, when you click Next, Application Developer may not include the
last field you updated.
The form bean wizard creates a new Java class extending the
org.apache.struts.action.ActionForm class and opens it up in the editor.
Replace the validate method (not the whole class) with the code shown in
Figure 10-17. The code is available in:
\sg246957\sampcode\dev-struts\initial\forms\CustomerInfoForm.txt
return errors;
}
if ("Transfer".equals(action)) {
if (destinationAccount == null
|| destinationAccount.trim().length() == 0)
errors.add(
ActionErrors.GLOBAL_ERROR,
new ActionError("error.missing.destinationAccount"));
}
}
return errors;
}
This method uses the action string to determine what fields should be
validated.
Press Ctrl-S to save this class and then close the Java editor.
Note: If deleting a component from the Web diagram, you are prompted
whether you also want to delete the underlying resource. Underlying resource
here refers to the mapping in the struts-config.xml file, not the implemented
component itself. This means that if you delete a form bean and also delete
the underlying resource, it will remove the form bean from the Web diagram
and its mapping from the struts-config.xml file. It will not, however, delete
the Java source or class file for the form bean. If you then add a new form
bean with the same name to the Web diagram and attempt to implement it, the
Finish button that you must click to create the component is deactivated in the
wizard. This is due to the fact that this class already exists, it was not deleted.
On the tag directive page, select Create Session Variable and true
(Figure 10-21). Click Next.
On the next dialog (see Figure 10-23) you can design the input form used on
the index.jsp page. Unfortunately this feature does not use the Struts tag
libraries to its fullest.
For example, if you enter customerNumber as the label for a field, what you
really would like in the JSP is <bean:message key="customerNumber"/>, so
that the corresponding text from the ApplicationResources.properties file is
displayed. The result produced by the wizard, however, is the exact text you
enter.
As you can see in the editor, the wizard has inserted the two Struts tag libraries
we requested:
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
The Struts <html:form> tag is used to generate the body of the input form. The
<html:text>, <html:submit>, and <html:reset> tags generate the fields and
buttons.
This is because the form’s action refers to the listAccounts action that we have
not yet developed. This error will be fixed when we implement listAccounts.
Note: If you do not see the errors in the tasks view, it may be due to your
filtering settings in the Tasks view.
Tip: You can use the JSP -> Insert Custom option to select any custom
tags from the Struts tag library. For example, for the heading:
Select the message tag in the bean library and click Insert.
Under the <BODY> tag, add the RedBank text and image in the same way as in
the index.html file in “Using the Page Designer” on page 196:
<TABLE border="0">
<TBODY>
<TR>
<TD>
<H1><FONT color="red">Red</FONT>Bank</H1>
</TD>
<TD><IMG border="0" src="images/itso.gif" width="50"
height="40"></TD>
</TR>
</TBODY>
</TABLE>
Add a heading 2 with:
<H2><bean:message key="text.welcome"/></H2>
After the header, you can display error messages by using the <html:errors>
tag:
<html:errors></html:errors>
This tag displays the error messages returned as an ActionErrors object by a
form bean’s validate method (or placed in the request scope by an action). In
the ApplicationResources.properties file we have defined the following
special keys that applies basic formatting for the error messages:
errors.header=<P><font color="#ff0000"><strong><ul>
errors.footer=</ul></strong></font></P>
If these two keys are present, the <html:errors> tag inserts their content just
before and after the actual error messages. This makes our errors appear as
an unordered list and in red color. In the ApplicationResources.properties
file we prefix each error message with <li> so they are displayed as a
bulleted list.
Application Developer Struts tools also provide real-time rendering of the Struts
tags. Switch to the Design view of the Page Designer to see what the JSP will
look like (Figure 10-24).
Note: The rendering of the Struts tags can be customized using the Window
-> Preferences -> Web tools -> Struts tools -> Page Designer Struts Support
dialog. The options available are self-explanatory so we do not cover them
here.
Note:
The sequence of the
attributes cannot be
changed using the
arrow buttons
The tool generates the tag for collections to iterate over the results in two of our
Web pages. For example:
<logic:iterate id="transactions_id" name="transactionForm"
property="transactions" indexId="index"
type="itso.bank.model.TransRecord">
When all JSPs are implemented you should have the Web diagram shown in
Figure 10-27.
To complete the application, we also need the three actions, as described in the
following sections.
The ListAccountsAction class opens in the Java editor. The Struts wizard
has provided us with skeleton code for normal action behavior. The main
method of a Struts action is the execute method. This is the method that
Struts calls to invoke this action and this is where we provide our logic.
} catch (Exception e) {
errors.add(ActionErrors.GLOBAL_ERROR,
new ActionError("error.genericException"));
}
if (!errors.empty()) {
saveErrors(request, errors);
forward = mapping.getInputForward();
} else {
forward = mapping.findForward("success");
}
// Finish with
return (forward);
}
This action class follows the normal sequence most action classes do:
It first creates ActionError and ActionForward objects to hold the keys for
any errors that may occur and the forward that will be returned to Struts at the
end of the method. The forward determines the page to be displayed next.
It then retrieves the form bean that Struts has populated before calling the
execute method. The form bean is populated with all properties that Struts
could retrieve from the input form and has a getter/setter on the form bean.
The action then performs similar business logic as the ListAccounts servlet
from the RedBank application (that is, retrieve the accounts for this customer).
After the business logic is performed, the action stores the information
necessary to display the resulting JSP in the form bean and then places this
form bean into the request or session scope, depending on what was
configured in the Struts configuration file. In our case we used the request
scope for this.
Should any exceptions occur (for example, the customer number entered
does not exist) a new ActionError object is created with the key
corresponding to the error message, and this ActionError is added to the
ActionErrors object. An ActionErrors object can therefore hold multiple
ActionError objects, each describing a specific error condition.
Finally, the method checks if any errors were added to the ActionErrors
object and, if so, saves the ActionErrors object to the request so the Struts
<html:errors> tag can find and display them. It also determines the forward
that control should be passed to. In case of an error we return to the input
Note: The two commented lines (in italic) can be used to pre-select the
account number in the selection list. This way we could make sure that an
account number would always be selected. We did not want to do this here, as
we wanted to show you how to use the validate method instead.
When you have implemented all the components on the Web diagram, there
should be no errors in the Task view.
Before we have a fully working application we need to add a few more forwards.
We will do that using the Struts configuration file editor.
We will use this editor to add a forward called cancel to the accountDetails and
performTransaction actions. This forward is used by the actions to determine
where to go in case the user clicks Cancel.
We also specify the input attribute for all our actions. This attribute specifies
which page should be displayed if the validate method of a form bean found
errors. Usually you want to display the input page where the user entered the
data so they can correct their entry.
Double-click the Web Content\WEB-INF\struts-config.xml file to open the
configuration file editor.
Note: The Redirect check box allows you to select if a redirect or forward
call should be made. A forward call keeps the same request with all
attributes it contains and just passes control over to the path specified. A
redirect call tells the browser to make a new HTTP request which creates a
new request object (and you lose any attributes set in the original request).
A forward call does not change the URL in the browser’s address field, as it
is unaware that the server has passed control to another component. With
a redirect call, however, the browser updates the URL in its address field to
reflect the requested address.
Note: You can redirect or forward also to other actions. It does not
necessarily have to be a JSP. The cancel forward can point to either
/listAccounts.do (the action) or /listAccounts.jsp (the JSP).
Going to the JSP may require that the form bean is in the session instead
of the request.
The Struts configuration editor does roundtrip editing, so if you edit something in
the XML view it is reflected in the other views.
The forwards we use are local to each action, meaning that only the action
associated with the forward can look it up. In the <global-forwards> section you
can also specify global forwards that are available for all actions in the
application. Normally you have a common error page to display any severe error
messages that may have occurred in your application and that prevents it from
continuing. Pages like these are good targets for global forwards and so are any
other commonly used forward. Local forwards override global forwards.
You can now close the configuration file editor.
As we have now added a few more forwards we should update the Web
diagram to show them as well. If the Web diagram is not open, open it by
double-clicking \Web Content\WEB-INF\strutsbank.gph. In the Web diagram
select the listAccounts action and Draw -> Draw Selected From its context
menu. Select “input” --> /index.jsp as shown in Figure 10-33 and click OK.
This draws a red line from the listAccounts action back to index.jsp,
indicating the input page.
For the accountDetails and performTransaction actions, draw both the input
and cancel paths. This draws a red line indicating the input page and a black
line indicating a normal forward for each of these two actions.
Select the lines and drag the small dot in the middle of the line to avoid the
lines from crossing over other components in the Web diagram.
We are now ready to test our application using the built-in WebSphere Test
Environment.
Summary
In this chapter we built a simple Web application using the Struts framework. We
reused the model from the Web application we built in Chapter 7, “Developing
Web applications” on page 179, but replaced the controller and view parts with
the Struts framework.
Note that some parts of this chapter have been taken from an existing IBM
Redbook:
The XML Files: Development of XML/XSL Applications Using WebSphere
Studio Version 5, SG24-6586.
XML documents follow strict syntax rules. For more information regarding XML
consult the W3C Web Site:
http://www.w3.org/XML
However, to create, read and update XML documents, you need an XML
processor or parser. At the heart of every XML application is an XML processor
that parses an XML document, so that the document elements can be retrieved
and transformed into a presentation understood by the target client. The other
responsibility of the parser is to check the syntax and structure of the XML
document.
Note: DTDs consists of elements such as text strings, text strings with other
child elements, and a set of child elements. DTDs offer limited support for
types and namespaces, and the syntax in DTDs is not XML.
XSL uses an XML notation and works on two principles: pattern matching and
templates. It operates on an XML source document and parses it into a source
tree, it applies the transformation of the source tree to a result tree, and then it
outputs the result tree to a specified format. In constructing the result tree, the
elements can be reordered or filtered, and also, other structures can be added.
The result tree can be completely different from the source tree.
XML namespaces
Namespaces are used when there is a need for elements and attributes of the
same name to take on a different meaning depending on the context in which
they are used. For instance, a tag called <TITLE> takes on a different meaning,
depending on whether it is applied to a person or a book.
If both entities (a person and a book) need to be defined in the same document,
for example, in a library entry which associates a book with its author, we need
some mechanism to distinguish between the two and apply the correct semantic
description to the <TITLE> tag whenever it is used in the document.
XPath
The XML path language (XPath) is used to address parts of an XML document.
An XPath expression can be used to search through an XML document, and
extract information from the nodes (any part of the document, such as an
element or attribute) in it. There are four different kinds of XPath expressions:
Boolean—Expression type with two possible values
Node set—Collection of nodes that match an expression's criteria, usually
derived with a location path
Number—Numeric value, useful for counting nodes and for performing
simple arithmetic
String—Text fragment that may come from the input tree, processed or
augmented with general text
Only some of these editors are described in these chapter. Refer to Application
Developer’s help manual for more detailed information regarding XML tools and
editors.
Note: We do not create a fully XML enabled application here. This chapter
only shows some XML capabilities of Application Developer where we create
and work with XML files.
Once this is done, we create a Java package and name it itso.xml (see
“Creating Java packages” on page 99 for more information).
We also create a new folder in the WEB-INF folder and name the folder xml where
we store an XML schema file. The new Web project skeleton displayed in the
J2EE Navigator view should now look like shown in Figure 11-1.
To create a new file from scratch, use the New XML wizard. Switch to the XML
perspective, select File -> New -> XML and select the Create XML file from
scratch option from the dialog and click Next (Figure 11-2).
In the next dialog, make sure that the project ItsoProGuideXmlWeb with the folder
Web Content\xml has been selected, type a name in the File name field (in this
example we use the default name NewFile.xml) and click Finish. The XML file is
created and the XML editor is automatically opened.
You can use the Source view to view and work with a file’s source code directly.
The Source view has many text editing features, such as:
Syntax highlighting
Unlimited undo and redo of changes
Content assist
User-defined macros
Node selection indicator
After you have created the new XML file, add some elements with values to the
XML file. Figure 11-4 shows the code of the file including the root element named
ACCOUNT and seven child elements.
Figure 11-5 shows the context menu of the document type declaration tag.
To add elements to the ACCOUNT element, select the element and Add Child ->
New Element. Add the seven child elements to the ACCOUNT element.
Once you have added all elements to the XML file, you can use the Design view
to add its values. Figure 11-7 shows the Design view with the highlighted ACCID
element. You can see that a value for this element has been entered in the
second column.
See also “Generate DDL and XML schema files” on page 151 for more
information about creating XML schema files for data objects.
The source editor opens the newly created schema file ACCOUNT.xsd
(Example 11-1).
Close the Data perspective and switch back to the XML perspective as we
continue with the sample using the XML features.
The Graph view is used for working with schema files and provides a graphical
way to browse and edit your schema. You can click the + or - signs to navigate
through the schema and learn more about its structure (Figure 11-8).
You can use the pop-up menu for each node to add content that is appropriate.
XML generators
Application Developer provides a number of XML generators. Using these tools,
you can generate XML schemas, XML files from other components (for example,
JavaBeans or an SQL statement), and also generate components from XML files
and XML schemas. Here is a list of XML generators:
Generating an XML schema from a DTD
Generating JavaBeans from a DTD
Generating an HTML form from a DTD
Generating an XML file from a DTD
Generating a DTD file from an XML schema
Generating JavaBeans from an XML schema
Generating XML/XSL from JavaBeans
Generating an XML file from an XML schema
Generating a relational table definition from an XML schema
Generating an XML schema from a relational table
Generating HTML documentation from XML schemas
Creating a DTD file from one or more XML files
Creating an XML schema file from an XML file
We use the new XSD file to generate a DTD. Having the ACCOUNT.xsd file, we can
generate the corresponding DTD file using the generator. To demonstrate how to
create a DTD file from an existing XSD file, follow these steps:
Select the file ACCOUNT.xsd.
Select Generate -> DTD from the context menu.
Select the folder to store the file. In this example we use the Web
Content\WEB-INF\xml folder in our project.
Click Finish.
The DTD file ACCOUNT.dtd is created and opened in editor. Based on a DTD file,
you can create XML, HTML, XML schema files, and also JavaBeans. Figure 11-9
shows the code of the DTD file ACCOUNT.dtd.
Validating files means that Application Developer determines whether the current
state of the file is semantically valid. Any errors will be displayed in the Tasks
You can start validating a file by opening its context menu and selecting Validate
<file type>, where <file type> is the currently selected file. If you want to validate
the ACCOUNT.xsd schema file, simply open the context menu and select Validate
XML Schema (Figure 11-11).
A new dialog box opens and informs you if the file is valid or not.
A new dialog comes up where you can change the location and the file name for
the XML file. Select the WEB-INF\xml folder and use the suggested name
ACCOUNT.xml and click Next to open the Create XML File dialog (Figure 11-12).
Select ACCOUNT_TABLE as the root element of the XML file and select Create
required and optional content to create optional information in addition to the
minimum amount of information.
The XML schema information section contains information about the target
namespace of the XML schema, its prefix, and the schema location.
Click Finish to create the XML file. The XML file is created and opened in the
editor. Figure 11-13 shows the source of the file.
The reason for this is that the default values added to the new XML file do not
match with the restrictions defined in the XML schema file ACCOUNT.xsd.
Change the values of the three elements as shown in Figure 11-14 and save the
file. The changed lines are highlighted in bold.
After you have generated an XML file you could, based on that file, generate an
XML application (for example an XML validation application by using the context
menu of the XML file and select Generate -> XML Application), a DTD or XML
schema file, and even data for an existing databases.
Note: Application Developer 5 also introduces the XML Signature wizard. You
can create a digital signature for your XML file using the XML Signature
wizard. You must either use an existing certificate or create a new certificate to
create a digital signature. To launch the XML Signature wizard, open the
context menu of an XML file and select XML Security -> Digital Signature.
Next we create a new XSL file from scratch and transform the XML document
ACCOUNT.xml by using the XSL style sheet to generate an HTML file.
Click Next to select an XML file and associate it with the XSL file. By
associating an XSL file explicitly with an XML file, you do not have to specify
the XML file every time you want to transform or debug the XML and XSL files
(Figure 11-16).
Click Finish to create the file. The new XSL file is opened in the XSL editor.
Figure 11-17 shows the skeleton of the file.
One way to add code to the XSL file is to type it directly into the source editor, but
you can also use the XSL wizards to add code to the XSL. These wizards can be
found by expanding the XSL menu in Application Developer as shown in
Figure 11-18.
To prepare the style sheet that can be used to generate a HTML file, we have to
add some HTML code. First we add an HTML template. This basically generates
an HTML code skeleton and add it to the XSL file.
To use the HTML Template wizard, place the cursor in a new line right after the
stylesheet tag (Figure 11-19) and select XSL -> HTML Template from the menu
bar. Note that Application Developer immediately adds the HTML code to the file
without bringing up a dialog.
A new code fragment has been added to the XSL file, as shown in Figure 11-20.
Next, delete the <xsl:apply-templates/> line from the code and place the cursor
in this line (Figure 11-21).
Note: As we have specified the corresponding XML file, when creating the
style sheet, Application Developer does not bring up the XML file selection
dialog. This would be the case if no XML file had been selected when creating
new style sheets.
Click Next to open the dialog where you can change the properties of the HTML
table. You can change properties like color, border, and width of the table. In this
example we are not doing this, and we click Finish to add the table to the XSL
file. Figure 11-23 shows the code which is added to the XSL file.
<table>
<tr>
<th>ACCID</th>
<th>BALANCE</th>
<th>INTEREST</th>
<th>ACCTYPE</th>
<th>DISCRIMINATOR</th>
<th>OVERDRAFT</th>
<th>MINAMOUNT</th>
</tr>
<xsl:for-each select="/EJBBANKITSO:ACCOUNT_TABLE/EJBBANKITSO:ACCOUNT">
<tr>
<td><xsl:value-of select="ACCID"/></td>
<td><xsl:value-of select="BALANCE"/></td>
<td><xsl:value-of select="INTEREST"/></td>
<td><xsl:value-of select="ACCTYPE"/></td>
<td><xsl:value-of select="DISCRIMINATOR"/></td>
<td><xsl:value-of select="OVERDRAFT"/></td>
<td><xsl:value-of select="MINAMOUNT"/></td>
</tr>
</xsl:for-each>
</table>
Note: As this is just a simple example of a style sheet, it has not been nicely
formatted. You can do this by changing the HTML tags in the Source view
appropriate to your needs.
Now we finished creating a simple XSL style sheet which is based on the
ACCOUNT.xml file. By applying this file to the XML file, a list of all accounts found in
the XML file is generated.
Note: You should only apply an XSL file to an XML file and attempt to create
an HTML file if the style sheet you are using is designed to provide HTML
output. Otherwise, an empty or incorrect HTML file will be created.
If you select only an XSL file or XML file, and select Apply XSL from the pop-up
menu, a wizard will open, prompting you to select an XML or XSL file from the
Workbench or from the Internet using HTTP.
If you select an XML or XSL from HTTP, you must specify its URI. Only an XSL
transformation will be run on the selected file. Because the file is not available in
the Workbench, the debugger cannot be opened. It can only be transformed and
the results displayed.
To apply an XSL file to an XML file and create a new HTML file, select an XML
and an XSL file (press the CTRL key to select both files) and Apply XSL -> As
XML (context).
Figure 11-24 shows the selected files and the context menu where you can
transform the file.
If you now go back to the XML perspective, you see that Application Developer
has created a new HTML file and named it ACCOUNT_Acount_transform.html.
When you open the HTML file in the Design tab it should look like Figure 11-25.
By changing the HTML tags in the style sheet, you can format this HTML file
more nicely.
Debugging XSL
Application Developer’s XSL debugging and transformation tool records the
transformation that is generated by the Xalan processor. The Xalan processor is
an XSLT processor that transforms XML files into HTML, text, or other XML file
types.
For more information on the Xalan processor, refer to the following Apache Web
site:
http://xml.apache.org/xalan-j/
The XSL debugging and transformation tool enables you to visually step through
an XSL transformation script. Figure 11-26 shows the XSL Debug perspective
with its views.
The Sessions view displays any sessions you have run (that is, any XSL files you
have applied to XML files). You can use the Sessions view to step through an
XSL transformation script, highlighting the transformation rules as they are fired.
You can click the Globe icon to view the result HTML file. Again, if you switch
back to the XML perspective you notice that a new file named, in this case,
named ACCOUNT_Account_transform.html has been created.
The Java root folder has to be specified in the Container field. In the Package
field we enter itso.xml as we would like to store the JavaBeans in this package.
In the Root element field select ACCOUNT and make sure the check box Generate
sample test program is selected. This generates a runnable JavaBean which
shows you how to use the beans you have created.
Click Finish to generate the JavaBeans. The following files are created in the
itso.xml package:
ACCOUNT_TABLE.java—represents the complex type <ACCOUNT_TABLE>.
ACCOUNTFactory.java—provides methods for creating Java beans for
elements in the XML document.
ACCOUNT.java—represents the complex type <ACCOUNT>.
Sample.java—creates and saves an XML document, loads the XML
document and prints its content in the Console view
Next, switch to the Java perspective and modify the createACCOUNT method of the
Sample.java file and change the parameter of the setACCID, setACCTYPE, and
setDISCRIMINATOR statements as shown in Figure 11-28.
void createACCOUNT()
{
iACCOUNT.setACCID("101-1001");
iACCOUNT.setBALANCE("0.0");
iACCOUNT.setINTEREST(0);
iACCOUNT.setACCTYPE("Checking");
iACCOUNT.setDISCRIMINATOR("C");
iACCOUNT.setOVERDRAFT("0.0");
iACCOUNT.setMINAMOUNT("0.0");
}
Now you can run the sample class. See “Running your programs” on page 103
for more information about how to run a Java application.
Note that after running the sample application a new file, ACCOUNTSample.xml, is
created in the Web Content\WEB-INF\xml folder. This file contains the element
values specified in the createACCOUNT method of the sample Java file.
Tip: You have to select the xml folder and Refresh (context) to see the
generated file.
Summary
In this chapter we have explained and demonstrated some XML tools of
Application Developer. As the XML topic is to complex to be covered in only one
chapter, we could not demonstrate everything Application Developer provides.
We have shown how to create a new XML file, a new XSL style sheet, and how to
generate an XML schema based on a relational database table.
More information
In the IBM Redbook The XML Files: Development of XML/XSL Applications
Using WebSphere Studio Version 5, SG24-6586, more detailed information is
provided regarding developing XML/XSL applications using Application
Developer. It also contains examples using Application Developer Version 5.
In this chapter we develop a few entity beans, relationships between the entity
beans, a session bean, and a front-end Web application.
This chapter provides only a condensed description of the EJB architecture and
a few examples. For complete coverage of EJBs, refer to the IBM Redbook, EJB
2.0 Development with WebSphere Studio Application Developer, SG24-6819.
Since its introduction a few years ago, the technology has gained momentum
among platform providers and enterprise development teams. This is because
the EJB component model simplifies the development of business components
that are:
Secure—Certain types of applications have security restrictions that have
previously made them difficult to implement in Java. For example, certain
insurance applications must restrict access to patient data in order to meet
regulatory guidelines. Until the advent of enterprise beans, there was no way
to restrict access to an object or method by a particular user. Previously,
restricting access at the database level, and then catching errors thrown at
the JDBC level, or by restricting access at the application level by custom
security code, would have been the only implementation options.
However, enterprise beans now allow method-level security on any enterprise
bean or method. Users and user groups can be created which can be granted
or denied execution rights to any EJB or method. In WebSphere, these same
user groups can be granted or denied access to Web resources (servlets,
JSPs and HTML pages), and the user IDs can be in a seamless way passed
from the Web resources to the EJBs by the underlying security framework.
Not only that, but the authenticated credentials may also be forwarded to
other systems, possibly legacy systems (compatible LTPA clients).
Distributed—Enterprise JavaBeans automatically provide distribution
capabilities to your application, allowing for the building of enterprise-scale
systems. In short, this means that your system’s modules can be deployed to
many different physical machines and many separate OS processes to
achieve your performance, scalability, and availability requirements. Better
yet, you may start small with just a single process and grow to as many
different machines as you want without ever having to touch your code.
Persistent—Making an object persistent means preserving its state (the
values of its variables) even after the termination of the system that created
that object.
In most cases, the state of a persistent object is stored in a relational
database. Unfortunately, the OO and relational paradigms differ a lot from
each other. Relational models have limited modeling capabilities, for they
have no way to represent behavior, encapsulation, or complex relationships
like inheritance. Additionally, SQL data types do not exactly match Java data
types, leading to conversion problems. All these problems may be
automatically solved when using EJBs.
Remote
Client
Remote View
EJB EJB
Home Object
EJB
Local
Home
Local EJB Component
Client EISs
EJB
Local
Object Container
The EJB server provides the implementation for the services common to all
EJBs. The EJB server’s responsibility is to hide the complexities of these
services from the component requiring them. The EJB specification outlines
seven services that must be provided by an EJB server:
Naming
Transaction
Security
Persistence
Concurrency
Life cycle
Messaging
Bear in mind that the EJB container and the EJB server are not very clearly
separated constructs from the component point of view. EJBs do not interact
directly with the EJB server (there is no standard API to do so), but rather do so
through the EJB container. So, from the EJBs’ perspective, it appears as if the
EJB container is in fact providing those services, when in fact it might not. The
specification defines a bean-container contract, but not a container-server
contract, so determining who actually does what is a little ambiguous and
platform dependent.
EJB container
The EJB container functions as a run-time environment for enterprise beans by
managing and applying the primary services that are needed for bean
management at run time. In addition to being an intermediary to the services
provided by the EJB server, the EJB container will also provide for EJB instance
life cycle management and EJB instance identification. EJB containers create
bean instances, manage pools of instances, and destroy them.
Containers are transparent to the client — there is no client API to manipulate the
container, and there is no way for a client to tell in which container an enterprise
bean is deployed.
One of the container’s primary responsibilities is to provide the means for remote
clients to access components that live within them. Remote accessibility enables
remote invocation of a native component by converting it into a network
component. EJB containers use the Java RMI interfaces to specify remote
accessibility to clients of the EJBs.
EJB components
EJB components run inside an EJB container, the run-time environment. The
container offers life-cycle services to these components, and provides them with
an interface to the EJB server. It also manages the connections to the enterprise
information systems (EISs), including databases and legacy systems.
Interfaces
For client objects to send messages to an EJB component, the component must
provide a view. A view is a client interface to the bean, and may be local or
remote. A local view can be used only by local clients (that reside in the same
JVM as the server component) to access the EJB. A remote view, on the other
hand, allows any client (possibly distributed) to access the component.
The idea of local interfaces is new to EJB 2.0, and is motivated by the fact that
remote calls are more expensive than local calls. Which one to use is influenced
by how the bean itself is to be used by its client, because local and remote depict
the client’s view of the bean. An EJB client may be an external (remote) client,
such as a servlet running on another process, or may be an internal (local) client,
such as another EJB.
On the other hand, remote interfaces have the advantage of being location
independent. The same method can be called by a client that is inside or
outside of the container.
Which interfaces to use, classes to extend, and other rules of bean construction
are governed by the type of bean you choose to develop. A quick introduction to
the types of enterprise beans and their uses is presented here.
EJB types
There are three main types of EJBs: entity beans, session beans, and
message-driven beans (Figure 12-2).
EJB
Synchronous Asynchronous
Although the classifications above (CMP versus BMP, and stateful versus
stateless) are often referred to as types of EJBs, they are not really different
types in the sense that there are no new classes or interfaces to represent these
types. They are still just entity or session beans. Rather, how the container
manages these beans is what makes them different. All information regarding the
way the container has to handle these different bean flavors is managed in the
deployment descriptor.
Entity and session beans are accessed synchronously through a remote or local
EJB interface method invocation. This is referred to as synchronous invocation,
because there is a request, and a (blocking) wait for the return. Clients of EJBs
invoke methods on session and entity beans. An EJB client may be an external
construct like a servlet (remote) or an another EJB within the same JVM (local).
Relationships
Container-managed relationships (CMRs) are among the most significant new
features added by the EJB 2.0 specification. Associations are a key component
of object-oriented software development and non-trivial object models can form
complex networks with these relationships. The EJB 2.0 specification adds
associations to the EJB programming model and requires that the container be
responsible for their maintenance.
The container automatically manages the state of CMP entity beans. This
management includes synchronizing the state of the bean with the underlying
database when necessary and also managing any CMRs with other entity beans.
The bean developer is relieved of writing any database specific code and,
instead, can focus on business logic.
Component-level inheritance is still not in the EJB 2.0 specification, even though
it is planned for future releases. In the meantime, WebSphere Application Server
V5 and Application Developer V5 support it in a non-standard way.
EJB QL queries are defined in the deployment descriptor and the EJB provider
generates the SQL statements for actual database access from the EJB QL. As
an example, this query retrieves customers that have accounts with a large
balance:
select object(c) from Customer c, in(c.accounts) a where a.balance > ?1
EJB QL can be used for custom finder methods that return one or multiple EJB
objects (remote or local). In addition, EJB QL can be used for so called select
methods, which are internal to the implementation and not visible to clients.
Select methods can be used to accumulate data and return either EJB objects or
CMP or CMR fields or collections of any of those.
In Figure 12-3 you can see the model layer’s updated design.
Business Model
Customer
1:m
Account TransRecord
Facade
If you compare this model to the Web application model shown in Figure 5-21 on
page 111, you can see that the coordinator (Bank) has been replaced with a
session EJB (BankEJB). This EJB has a remote interface and uses container
demarcated transactions. Without any extra code, we are able to count on
transaction management for our operations.
On the other hand, this also implies that the control and view layers will not be
able to reference these entities directly, because they may be placed in a
different JVM. This time around, only the session bean (BankEJB) will be able to
access the business entities through their local home interfaces.
You may be asking yourself, then why we do not expose a remote interface for
our entity beans as well? The problem with doing that is twofold. First, in such a
design, clients would probably make many remote calls to the model in order to
resolve each client request. This is not a recommended practice because remote
calls are much more expensive than local ones. Finally, allowing clients to see
into the model breaks the layer’s encapsulation, promoting unwanted
dependencies and coupling.
Figure 12-4 shows the application component model and the flow of events, so
that you can see the big picture.
HTTP RMI/IIOP
Web Client 1 Control Facade 2 Facade
3
4 Entity
5
7 Model
Web Container
Application Server
Please note that the intent of this chapter is to introduce you to the Application
Developer’s tools that make the development of EJBs and enterprise applications
possible. Together we will work only on a single session bean and three entity
beans. The rest of the application has already been developed and will be made
available to you, so that you can dig into it if you would like to.
In this chapter we develop three entity beans, two relationships, and a session
bean. We require a J2EE EJB project to support our tasks. To create an EJB
project, select File -> New -> EJB Project. The dialog in Figure 12-5 is displayed.
The wizard’s first page asks you to supply the version of the EJB specification
you want to use in your project. Since this is a brand new project, we want the
latest version available. Select the Create 2.0 EJB Project option and click Next
to continue to the second page (Figure 12-6).
Business Model
Customer
BankEJB m:m
1:m
Facade Account TransRecord
Note: If you select the ItsoProGuideEJB project and New -> Enterprise Bean
(context), the project is prefilled.
The three entity beans that we are creating have container-managed persistence
fields and comply with the EJB 2.0 specification. Select the Entity bean with
container-managed persistence (CMP) fields and CMP 2.0 Bean options.
Type the bean name (Customer), leave the source folder to the default value
(ejbModule), and enter the default package (itso.ejb.model.entity). Click Next
to continue (Figure 12-11):
This page lets you select the supertype (allowing you to define the inheritance
structures, not covered any further in this book), type names, binding name
(the name through which the bean is going to be referenced by its clients),
which views you would like to create, and finally the key class and CMP
attributes.
Most of the time the suggested values for the binding name and the type
names (derived from the bean name) are good, so you do not have to worry
about them.
According to our design, entity beans should have only local interfaces, so
make sure not to select the Remote client view check box. Application
Developer knows about this good practice, so it will only select Local client
view by default.
If the attribute is an array, select the Array check box and specify the number of
the dimensions for it.
By selecting the Key field check box, you indicate that the new field should be
part of the entity’s unique identifier. You may declare as many attributes as you
want to perform this role. Application Developer is very smart here. If you specify
just one key attribute of an object type, it will declare that type as the key class in
Figure 12-11). If you select an attribute of a non-object type (like int or double),
or if you select more than one key attribute, the environment will automatically
create a new key class for you, implement all its methods (including equals and
hashCode), and declare it as the key class.
Note: If you do not define at least one key CMP attribute, errors will exist for
the new enterprise bean. You can correct them later by adding CMP key
attributes.
The two last check boxes let you indicate if you want to promote the new attribute
(through its getter and setter) to either the remote or the local interfaces, or to
both. The availability of these options depends on which client views you
selected.
For the Customer bean, add the fields stated in Table 12-1. If you click Apply, the
attribute will be added and the dialog will stay open.
Click Close only after adding the last attribute and clicking Apply. You are brought
back to the wizard, which should look like Figure 12-13.
Note the check box Use the single key attribute type for the key class. If you have
one key attribute and it is a normal Java type, such as String, Integer, Float,
BigDecimal, and so forth, then a separate key class is not required.
Key wrapper classes are required for the simple data types (int, float, char), for
JavaBeans, and if there is more than one key attribute.
In this page you can specify the superclass to the bean class, and declare which
interfaces should the remote and local interfaces extend.
Note: The bean superclass has nothing to do with the EJB inheritance
mechanism supported by Application Developer and WebSphere Application
Server. It is simply a way to declare regular Java inheritance for the bean
class.
balance java.math.BigDecimal No No
type String No No
Our transaction record objects do not have a natural primary key. As you know,
we must come up with an artificial unique identifier in order to be able to store
such objects in a relational database. For simplicity, we chose to create a new
java.util.Date object and set it as the primary key when transaction record
objects are created. The approach works just fine in our sample environment, but
could fail in the real world. If the application is deployed to two servers in a
cluster, for instance, both can try to create a new transaction record at the very
same time. This would lead to an error due to duplicate primary keys.
Note: It is common to find entities that do not have a natural unique identifier.
The EJB 2.0 specification touches this problem when it introduces the
unknown primary key class for CMP entity beans (10.8.3). The problem is that
WebSphere Application Server Version 5 does not implement this part of the
specification—you have to roll your own solution.
There are basically two approaches to the problem. The first is to have the
backend database generate the unique identifiers. This is feasible because
even though you may have as many application servers as you may like, the
data pertinent to a single entity will hopefully be stored in just one database.
The downside to this approach is that every time an entity is created, a
database table must be locked in order to generate the ID, and thus becomes
a bottleneck of the process.
attribute
home interface
component interface
bean class
key class
As you can see, for each entity bean, we have a primary key attribute (there
could be more than one), regular attributes, a home and a component interface
(both local), the bean class, and a key class.
For each bean three or four classes were created: the bean class, the home
interface, the local component interface, and (only for the Customer) a key class.
While in the J2EE Hierarchy view, double-click the AccountBean class. Application
Developer will open the Java editor and focus the Outline view (Figure 12-16) on
the class:
Life-cycle methods are the callback method used by the EJB container at
predefined events.
Business methods manipulate the CMP attributes.
business methods
Application Developer should tell you that you code has errors, because it cannot
find the InsufficientFundsException class. You can either type in the import
statement yourself (import itso.ejb.exception.InsufficientFundsException),
or let Application Developer fix the problem for you. For the later option, select
Source -> Organize Imports or click Ctrl-Shift-O.
Open the AccountLocal interface to check the methods you have just promoted.
Then delete or comment the setBalance method (only deposit and withdraw are
allowed). The local interface is shown in Figure 12-18:
package itso.ejb.model.entity;
import itso.ejb.exception.InsufficientFundsException;
Tip: Accessors for the key attribute are not promoted automatically to the
component interface. You have to promote the getter method manually. Do not
promote the setter method, the key cannot be changed.
Even though the AccountBean class has more methods than the ones listed
above, the methods in Figure 12-18 are the only ones a client may call, because
they are declared on the component interface.
The last one of the three is the TransRecord bean. All transaction records should
be read-only (they cannot be altered once they are created), therefore we have to
remove the setter methods from the interface.
Promote the getTimeStamp method from the bean and the interface should look
like Figure 12-19.
package itso.ejb.model.entity;
Transaction records should only be created if the client supplies both the
transaction type and amount. To enforce this, edit the TransRecordLocalHome
interface and change the signature of the create method (Figure 12-20).
Make sure that the old create method is deleted. Save your changes and close
the editor.
When you save your changes, Application Developer displays a warning on the
Tasks view, letting you know that an ejbCreate method should exist for the
create method you have just declared. Actually, a pair of ejbCreate and
ejbPostCreate methods with the same set of parameters must exist for every
create declared in the component interfaces. When we changed the create
signature on the TransRecordLocal interface, that ceased to be true.
Open the TransRecordBean class and change the ejbCreate and ejbPostCreate
methods (Figure 12-21). Make sure that the old methods are deleted.
Business Model
Customer
BankEJB m:m
1:m
Facade Account TransRecord
Figure 12-23 Defining relationships with the EJB deployment descriptor editor
Click Add to create a new relationship for the Account bean. The Add
Relationship wizard opens (Figure 12-24).
The wizard opens with the Account bean already selected on the left hand list
box. Select the TransRecord bean on the other list box. The wizard should
automatically fill in the Relationship name field. Click Next to continue to the
second page (Figure 12-25).
The second wizard page shows a UML view of the relationship and a
specification view.
As part of defining a relationship, you assign a role to each bean relative to the
other bean, and you give that role a name. These names are used to derive
method names in the generated code and become part of the enterprise bean's
component interface.
For the Account bean (left hand group in Figure 12-25), assign transRecords
as the role of the TransRecord bean. The attribute is in plural because of the
relationship multiplicity (one account may be associated with many
transaction records).
For the TransRecord bean (right hand group in Figure 12-25), assign Many for
the Multiplicity field and select the Cascade delete check box.
Tip: There are some alternative ways to open the EJB deployment descriptor.
On the J2EE Navigator view, you can double-click the EJB Deployment
Descriptor item right under the ItsoProGuideEJB project, or open the
ejb-jar.xml file under the ItsoProGuideEJB\ejbModule\META-INF folder. Also,
you can have the EJB deployment descriptor editor focus automatically on an
EJB by double-clicking directly on the bean in the J2EE Hierarchy view.
Figure 12-27 shows the EJB deployment descriptor with the Account bean
selected.
You may now inspect the changes the wizard made to your EJBs. In the J2EE
Hierarchy view, double-click the AccountLocal interface to open it with the Java
editor. The following methods should have been added:
public java.util.Collection getTransRecords();
public void setTransRecords(java.util.Collection aTransRecords);
public java.util.Collection getCustomers();
public void setCustomers(java.util.Collection aCustomers);
Note that the only change was the additional AccountLocal parameter. Save your
changes and close the editor.
Because we changed the create method on the home interface, we also have to
change the ejbCreate and ejbPostCreate methods in the TransRecordBean
class. Open the class and perform the changes described in Figure 12-28.
Note: The setAccount method was added when we created the association
relationship between the Account and the TransRecord beans. This method
cannot be called from the ejbCreate method. According to the specification,
during ejbCreate the instance cannot acquire a reference to the associated
entity object, and that reference is required by the setAccount method.
In the ejbPostCreate method, on the other hand, the instance may reference
the associated entity object. Thus, a call to setAccount can be made.
We do not require any custom finders for our RedBank example. But we will add
one nonetheless so that you know how you would do it on your own projects. Our
finder will look for all accounts that have a balance greater than a given value.
Open the EJB deployment descriptor, switch to the Beans page, and select the
Account bean from the list. Scroll down to the Queries section (Figure 12-29).
Figure 12-29 Defining queries with the EJB deployment descriptor editor
Click Add to open the Add Finder Descriptor wizard (Figure 12-30):
Here you have the option to define the query descriptor to either a new finder
method or to one previously declared in the bean’s home interface. Select
New, as the only finder we have in our AccountLocalHome interface is the
default findByPrimaryKey. Application Developer will take care of updating the
home interface for you by adding the declaration of the new finder method.
The Method Type field lets you select whether you want to create a descriptor
for a finder method or for an ejbSelect method. Select the find method
option. The difference between the two is that finder methods get promoted to
the bean's home interface, whereas ejbSelect methods do not. The latest are
useful as internal helper methods, as they cannot be called by clients.
The Type field would let you select to which home interface, either local or
remote, you would like the finder method promoted. You do not get an option
in this case because our Account bean only exposes a local view.
In the Name field, type findGoldAccounts as the name of the finder method.
Click Add to define a BigDecimal parameter.
Select java.util.Collection in the Return type field. Finder and ejbSelect
methods may return either a collection of objects, or just one instance of the
object’s component interface types.
Click Next to proceed to the final page (Figure 12-31):
The last wizard page lets you type a description to the query and the query
statement. You may optionally select a sample query as a starting point, for
example, FindByPrimaryKey.
Complete the query:
select object(o) from Account o where o.balance > ?1
Click Finish to end the dialog.
The EJB deployment descriptor with the query is shown in Figure 12-32.
Hiding the knowledge is not really the primary reason for having an abstraction
such as this, where the definition and development of the bean and its mappings
is separate from the dynamic run-time bindings of the bean. The goal, rather, is
to enable the developer to work with object views of the domain data instead of
data views and writing SQL. But another subtle benefit is also achieved. By
having a separation of these development and persistence concerns, one is free
to focus on the business logic. The CMP can be developed largely independently
of the data source, and allows a clear separation of business and data access
logic. This is one of the fundamental axioms of aspect oriented programming,
where the aspect of persistence can be removed from the development process,
and applied later, in this case, at deployment time.
Application Developer offers three different mapping strategies: top down, meet
in the middle, and bottom up:
Top down is when you start from an object oriented model and let the
environment generate the data model automatically for you, including the
object-relational mapping and the DDL that you would use to create the tables
in the database.
Note: This strategy is preferred when the data backend does not exist and
will be created from scratch.
Meet in the middle is the compromise strategy, in which you keep both your
existing object oriented and data models, creating a mapping between the
two. The mapping process is usually started by Application Developer, based
on cues like attribute names and types, and completed manually by you.
For now we will use the meet in the middle strategy because we do have an
existing database for application data.
In the EJB to RDB Mapping panel, select Create a new backend folder and click
Next. Application Developer enables us to map an entity bean to multiple
backend stores, for example, different relational database systems
(Figure 12-33).
Click Next to open the Selective Database Import panel. Select the four tables
that are required for our model (Figure 12-35).
Click Next and select Match by Name (Figure 12-36). This option should match
entities and attributes to tables and columns with the same name, thus
minimizing your manual work.
Click Finish to complete the database schema import and to open the mapping
editor (Figure 12-37):
As you can see, matching by name has already mapped the beans to the
correct tables, and some fields to the correct columns. The mapped items
carry a little triangle as an indicator and they are listed in the bottom pane.
Some fields have not been matched automatically. We can perform the
manual mapping by dragging and dropping attributes in the left pane to
relational columns on the right, or vice-versa. A bean must be mapped to a
table before you can map the attributes of the bean to the columns.
Relationships can be mapped as if they were regular fields.
Note: You can alternatively select an item in the left pane and one in the right
pane and select Create Mapping from the context menu. This is the same as
drag and drop.
The Outline view of the mapping editor summarizes our mapping activities
(Figure 12-38).
Business Model
Customer
BankEJB m:m
1:m
Facade Account TransRecord
Select the Session bean option and type BankEJB in the Bean name field. Type
itso.ejb.model.facade in the Default package field and click Next to continue
(Figure 12-41):
Make sure that you have the correct selections Stateless and Container.
Note that this time around, Application Developer suggests that you create a
remote client view instead of a local client view. This is because the
environment knows that session beans are normally used to implement the
model’s facade and, as such, need remote interfaces as opposed to local
ones.
The next wizard’s page is just like the one shown in Figure 12-14 on page 394
and need not be altered as well.
You may as well click Finish to complete the creation of your session bean.
If you open the J2EE Hierarchy view, you will be able to see the newly created
session bean (Figure 12-42).
The link between the logical name and the real bean is defined in the EJB
deployment descriptor and does not involve changing the code. At deployment,
the EJB reference is bound to the enterprise bean's home in the target
operational environment. The container makes the application's EJB references
available in a JNDI naming context.
In Application Developer, EJB references are edited using the EJB deployment
descriptor editor (Figure 12-43).
logical name
As you can see, some references have already been defined for you. Application
Developer automatically does that when you create relationships among entity
beans. We now have to add references to the BankEJB facade, so that it can
access the entity beans without having to use the complete JNDI name.
EJBs may reference other EJBs either through a remote or local interface. They
may also reference resources and security roles. Since our entity beans are all
local to the session bean, select EJB local reference and click Next to continue.
The next dialog (Figure 12-46) lets you specify the information of the referenced
local EJB:
You do not have to fill in all the fields, because Application Developer knows
all the information if only you let it know which EJB you would like to
reference.
Locate the Link field, but instead of typing the information, click Browse to
open the Link Selection dialog.
Select the Customer bean from the drop-down combo box and click OK.
Click Finish to create the reference.
Repeat the same process for the Account and the TransRecord bean. When you
are done, the References page of the EJB deployment descriptor should look like
Figure 12-46.
Note: The EJB methods can throw additional exceptions, for example,
CreateException is thrown if the create of a TransRecord fails.
They will hold, respectively, cached references to the initial naming context and
the homes of the entity beans.
Change all three methods from public to private, and then perform changes to
the code as shown in Figure 12-47.
All three properties will be lazy-initialized when the getters are called for the first
time. Add the appropriate imports to the javax.naming.InitialContext and
javax.naming.NamingException types.
Note: The get methods to retrieve the local homes of the entity beans invoke
the lookup helper method with the name of the EJB reference that we defined
for the session bean, for example, ejb/Account.
Notes:
The lookup method uses the context with the java:comp/env/ejbreference
argument to retrieve a home object.
We do not require a getTransRecordLocal method. Transaction records are
only created (using the home) or retrieved from an account through the
relationship.
Again, you might have to organize the import statements to correct the errors.
Notes:
As you can see by the code that you just typed in, the session facade
cannot return references of the entity beans. What it does is build data
transfer objects based on the entity data and return these objects instead.
There are many reasons for this, among which are the facts that these
entity beans do not expose a remote view, and that even if they did, it
would be terrible practice to have the control and view layers make multiple
remote calls to the model to carry on their responsibilities.
The building process of the transfer objects is inlined in the session bean
code, making it a little bit cluttered. We did it this way for simplicity. An
alternative would have been to use builder objects.
The getAccounts and getTransactions methods use the generated
relationship methods to retrieve a collection of related objects. The
collection is iterated and converted into an array of transfer objects. This is
done using a SortedSet to produce the result array in ascending order of
account IDs or transaction IDs.
To use a SortedSet both Account and TransRecord transfer objects
implement the compareTo method of the Comparable interface.
The name comes from the fact that this step is normally done at deploy time,
when all the definitions are complete, such as:
Life-cycle and finder method(s) defined and promoted to the home interface
Business logic methods defined and promoted to the component interface(s)
Object-relational mapping completed for CMP entity beans.
Before you can successfully run your enterprise beans on either the test
environment or production server, you need to generate deployed code for the
beans.
If your EJB project contains CMP beans that have not been mapped, a default
top-down mapping is created when you generate the deployment code.
To generate deploy code for our sample EJB project, switch to the J2EE
Hierarchy view and select the EJB module (ItsoProGuideEJB). Now select
Generate > Deploy and RMIC code from the context menu. The Generate Deploy
and RMIC Code wizard appears (Figure 12-49).
If there is a problem with the generation of RMIC code, a window appears where
you can read any error messages that are associated with the problem. You
should not see any error messages during the deployment process if your Tasks
view does not show any errors.
In the Overview page (Figure 12-50) add two values for the CMP Factory
Connection Binding:
For the JNDI name enter jdbc/ejbbank. This is the JNDI name we used for
the data source definition during the setup of the WebSphere Test
Environment (see “Defining a data source in the server” on page 256).
For the Container authorization type select Per_Connection_Factory. This
results in authorization by enterprise application. The other choice, Container,
results in authorization by the EJB container.
The Console view opens and you should see that the data source is allocated,
the Web and EJB modules are loaded, and the message Server server1 open
for e-business is displayed. That means that the server is now ready to serve
client requests.
Select the ItsoProGuideEJB EJB module and select Run on Server from the
selection’s context menu. If the Server Selection dialog appears, make sure that
the existing ItsoServer is selected. Select Set this server as project default (do
not prompt) and click Finish. The universal test client launches and we can test
our EJBs.
Home page
Figure 12-51 shows the home page of the test client as it appears in a browser
window after selecting an EJB project and Run on Server :
The test client can also be started from the Servers view by selecting a server
and then Run universal test client from the server’s context menu.
The two main pages to work with are the JNDI Explorer and the Bean page. The
JNDI Explorer is used to locate EJBs and the Bean page is used to work with
EJBs and JavaBeans.
JNDI Explorer
The JNDI Explorer allows you to browse or search for distributed objects (like
EJBs and data sources) deployed in the server. If a distributed object cannot be
found through the JNDI Explorer, it is because it was not deployed to the server
successfully.
Click JNDI Explorer to display the JNDI Explorer page (Figure 12-52).
After expanding the [Local EJB beans], ejb and jdbc groups all the way you can
see:
AccountLocalHome, CustomerLocalHome, and TransRecordLocalHome—The
local home interfaces to our entity beans.
BankEJBHome—The remote home interface to our session bean.
jdbc/ejbbank—The data source to the EJBBANK database.
To work with the Customer EJB, we click the CustomerLocalHome link, which
brings us to the Beans page.
Beans page
The Beans page shows EJB references (homes and components), object
references (any objects that are used and kept during the session), class
references (classes that are loaded explicitly), and utilities (which provides
various functions, such as the ability to load a class and cast an instance).
The create and findByPrimaryKey methods of the home interface are visible
under the CustomerLocal home. In addition, findCustomerByAccountsKey_Local
and remove methods are visible as well. The finder method was automatically
generated to support the customer-account relationship.
Click Method Visibility and you can see from which superclasses and interfaces
methods are inherited, and which ones are selected to be displayed for the
customer home.
To find an EJB instance by its primary key, select the findByPrimaryKey method.
Note that, in this case, the method parameter type is an object type, and a
non-literal one. This means that we first have to create an instance of that type to
be able to call the finder method.
We have to select values for two different list boxes. The first one lets you specify
whether you want to pass an object as a parameter, or just a null reference
instead. Select Objects. The second list then lets you select which constructor to
use. Select CustomerKey(int).
After you do that, expand the CustomerKey tree and enter a customer ID (for
example, 102) and click Invoke.
A CustomerLocal object is retrieved. Click Work with Object to add the result to
the EJB references (Figure 12-55).
To remove unwanted objects from the universal test client pane, click the scissor
icon that is displayed next to the object name.
Tip: If you know which EJB you would like to test and want to skip having to
browse for the bean using the JNDI Explorer, you can select the bean in the
EJB module and select Run on Server from its context menu. The UTC will
automatically switch to the Bean page, where a home reference to the
selected bean is instantiated.
A session bean must be created first. Expand the home reference, select the
create method and click Invoke. Click Work with Object to add a session bean
reference.
Select the withdraw method, enter 102-2001 as account number and 375.26 as
amount. Click Invoke (Figure 12-57).
Select the getAccount method, enter 102-2002 as account number, click Invoke,
then click Work with Object. An object reference of type Account is added.
Remember, getAccount returns a data transfer object. Note that the account data
is displayed because Account has a toString method.
Expand the Account object and run some of the getter methods.
Figure 12-59 Universal test Client: working wit a result array (1)
Expand the TransRecord[2] array and select Inspect Fields. The array is added
to the Parameters pane. Select one of the objects and click the icon on its
right side to add the object as a result. Click Work with Object to add the result
object to the references, from where you can run its methods (Figure 12-60).
Figure 12-60 Universal test Client: working wit a result array (2)
When you are done, close the browser and stop the server in the Servers view.
We can now replace the Banking facade with a new facade that interacts with our
EJB implementation. We provide the new facade in:
\sg246957\sampcode\dev-ejb\facade\Banking.java
Import the new facade into both Web projects, ItsoProGuideBasicWeb and
ItsoProGuideStrutsWeb:
Select the itso.bank.facade package in the J2EE Navigator view and Import
(context).
Select File system and click Next.
Click Browse and navigate to the \sg246957\sampcode\dev-ejb\facade
directory.
Select Overwrite existing resources with warning and click Finish.
getBankEJB:
getBankEJBHome().create();
As you know, some resources in the Web project reference other resources in
the EJB project, for the control layer resides in the Web module and the model
layer now resides in the EJB module (Figure 12-4 on page 385).
The model layer does not know about the control layer, but the control layer must
be able to reference the model layer. For that to work, we have to add the EJB
project to the Web project’s classpath.
Select the ItsoProGuideBasicWeb project and Properties from its context menu.
Select the Java JAR Dependencies group and add the ItsoProGuideEJB project
as a dependency (Figure 12-61).
EJB references
Web projects access an EJB either through the global JNDI name of the bean, or
through an EJB reference. The second approach is better because it makes the
Web application coding independent of the JNDI name.
Persistence: In the first implementation, every time you started the Web
application you got the same data because it was created in memory. Now we
are running with EJBs accessing the underlying EJBBANK database. All our
updates are persistent. The updated balance is stored in the database and the
transaction records accumulate for each account.
The use of the MVC architecture we could reuse the Web projects and connect
them to the EJB backend implementation.
As you can see, it paid off to have applied the MVC architectural pattern. We only
has to replace one class, the Banking facade, in the Web projects and they run
with a persistent back end.
Tip: You can reset the data in the EJBBANK database by rerunning the
loadbank.bat file in the _setup directory of the sample code.
For complete coverage of EJBs, refer to the IBM Redbook EJB 2.0 Development
with WebSphere Studio Application Developer, SG24-6819.
For more information about Web services, please refer to IBM Redbook
WebSphere Version 5 Web Services Handbook, SG24-6891.
Legacy
system
2
1
Service Internet Service
Requestor Provider
3
Service
Broker
1. The service provider creates a Web service and possibly publishes its
interface and access information to the service registry.
Each provider must decide which services to expose, how to make trade-offs
between security and easy availability, how to price the services (or, if they
are free, how to exploit them for other value). The provider also has to decide
what category the service should be listed in for a given broker service and
what sort of trading partner agreements are required to use the service.
2. The service broker (also known as service registry) is responsible for making
the Web service interface and implementation access information available to
any potential service requestor.
The implementers of a broker have to decide about the scope of the broker:
Public brokers are available all over the Internet, while private brokers are
only accessible to a limited audience, for example, users of a company-wide
These services can be new applications or just wrapped around existing legacy
systems to make them network-enabled. Services can rely on other services to
achieve their goals.
Figure 13-2 shows a first glance at the relationship between the core elements of
the SOA.
UDDI
(Broker)
HTTP
Runtime
transports
SOAP other
Requestor Provider
SOA Runtime
J2EE other
Implementation
Figure 13-2 Main building blocks in a SOA approach based on Web services
All elements use XML, including XML namespaces and XML schemas.
Service requestor and provider communicate with each other.
WSDL is one alternative to make service interfaces and implementations
available in the UDDI registry.
WSDL is the base for SOAP server deployment and SOAP client generation.
The imported application contains the Banking JavaBean that can be used to get
details about a particular Account, and to deposit, withdraw, and transfer funds. It
acts as a facade, hiding the database access. Behind the facade is another
JavaBean, AccountDB, that accesses the EJBBANK database. Two helper classes
Using a facade allows us to change the way the application accesses the
database, for example using EJBs instead of JavaBeans, without affecting the
remainder of the application.
You should already have created and configured the ItsoServer with an EJBBANK
data source.
We will describe how to use WebSphere Studio wizard to create a Web service
that returns information from the Banking service. The wizard guides us through
generating the WSDL document from the JavaBean, creating a proxy bean, and
testing the Web service in a Web browser using the generated test JSPs.
Select File -> New -> Other. Select Web Services to display the various Web
service wizards. Select Web Service and click Next to start the Web Service
wizard.
We go through all the pages of the wizard. Click Next on each page to get to the
next dialog.
From the Web service type drop-down menu select Java bean Web service.
Ensure that Start Web service in Web project is selected (this will start the
server). Select all the following check boxes:
Generate a proxy (for testing)
Test the generated proxy
Overwrite files without warning
Create folders when necessary
From the Client proxy type drop down menu, ensure that Java proxy is selected.
Figure 13-3 shows the dialog after making these selections.
Note: A Java proxy provides a remote procedure call interface to the Web
service. It is used by other Java classes to access the Web service.
Deployment Settings
The Web Service Deployment Settings page allows you to select from supported
run-time protocols and deployment servers. Select Use Defaults and make sure
that ItsoProGuideWebServ is selected as the Web project.
When you select a method, the input and output encoding are displayed. The
encoding style defines how the Java types in the client and server are mapped to
the XML types in the SOAP message:
The current page of the wizard shows the language mapping from Java types to
XML types (Figure 13-6).
Note that the proxy is generated into a separate Web project named
ItsoProGuideWebServClient. You could change the default project name if you
wanted. The name of the proxy defaults to proxy.soap.BankingProxy. Select the
Show mappings check box.
Test
In the Web Service Test page (Figure 13-9), you decide which facility to use to
test the Web service. The choices are:
Web service sample JSPs—Generates a set of four JSPs into the folder
sample/Banking in the client Web project (select this option).
Web tools Java bean JSPs—Generates an HTML page, a result JSP, and a
ViewBean class into the client Web project (does not function with the
BigDecimal class).
Universal Test Client—The universal test client is started and the proxy
bean is instantiated. You can always use the universal test client even if you
generate a sample.
Publication
In the Web Service Publication page you can publish the Web service to a UDDI
registry. For now, leave the boxes unchecked and click Finish.
Finish
The Web service is deployed in the Web project and the Web project is deployed
to a WebSphere test server:
An existing server is updated (WebSphere v5.0 Test Environment).
The enterprise application is added to the configuration.
The sample JSP test client is launched to test the Web service.
If you have problems creating the Web service, consult the online documentation
and the d:\workspace\.metadata\.log file.
Generated files
Before we test the Web service, let’s look at the generated files (Figure 13-10).
JavaBean
Starting point
Helper
Admin Proxy
application
Test
sample
ISD file
SOAP runtime
XSD files
Client project
WSDL files
deployment
descriptor
Server project
Figure 13-10 J2EE Navigator view after the generation of the Web service
The Web service is installed in the ItsoProGuideWebServ project and the proxy
and sample test client are in the ItsoProGuideWebServClient project.
Tip: The Banking.xsd file will show errors if you are not connected to the
Internet because the import statements cannot be resolved. You can ignore
the errors, the WSDL files are not used at runtime.
package itso.webserv.model;
import ....;
......
if(getURL() == null) {
throw new SOAPException(Constants.FAULT_CODE_CLIENT,
"A URL must be specified via BankingProxy.setEndPoint(URL).");
}
call.setMethodName("getAccount");
call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
call.setTargetObjectURI(targetObjectURI);
Vector params = new Vector();
Parameter accountIdParam = new Parameter("accountId", java.lang.String.class,
accountId, Constants.NS_URI_SOAP_ENC);
params.addElement(accountIdParam);
call.setParams(params);
Response resp = call.invoke(getURL(), SOAPActionURI); <==== Web Service Call
Figure 13-13 shows the sample test client in the internal browser. You can also
type the URL into an external browser.
Select a method (for example getAccount, enter the parameter, click Invoke, and
the result is displayed.
The sample test client was created in the new ItsoProGuideWebServClient Web
project called. If the browser does not launch automatically, follow these steps:
Select the TestClient.jsp in sample/Banking then select Run on Server from
the context menu.
In the Select Server dialog, select Use an existing server and select the
ItsoServer. Also select Set server as project default, then click Finish.
An instance of the proxy class is instantiated and you can run its methods
(Figure 13-14).
Click Work with Object to add the result Account object to the object references.
Expand the Account object to run its getter methods.
We use the WSDL file generated by the Web service wizard in “Creating a Web
service from a JavaBean” on page 446.
To simulate the activities of a real client, we copy the WSDL files from the server
Web project to the client Web project:
Copy the wsdl folder and all its subfolders:
From: ItsoProGuideWebServ/Web Content
To: ItsoProGuideWebServClient/Web Content
Select the wsdl folder and Copy (context), then select the target Web Content
folder and Paste (context).
For this exercise, imagine that the server Web project is on another server
somewhere in the Internet. All you have available is the description of the Web
service in the form of the WSDL files.
From the WSDL files, we generate a client proxy and a test sample and verify
that the Web service works.
Both the client and the service actually run on the same machine.
Click Next to start the Web service client wizard. We go through all the pages of
the wizard. Click Next on each page to get to the next dialog.
In the first page of the wizard, select the Test the generated proxy check box, as
shown in Figure 13-15. This causes the wizard to create sample JSP files that we
will use later to verify that the proxy works properly.
In the Web Services WSDL File Selection page, the BankingService.wsdl file
that you selected earlier is entered in the WSDL file name or URL text box, as
shown in Figure 13-16. Here you could enter the URL to a WSDL file on the
Internet, or click Browse to select a different file that exists in your workspace.
The panels that follow are the same as when we created the Web service. We
will only make a few changes to create different classes and JSPs
(Figure 13-17):
For the proxy we change the name to proxy.soap.ClientBankingProxy.
For the sample test application we use sample/ClientBanking as output
folder.
After the files are generated, an internal Web browser opens the
TestClient.jsp, as explained in “Testing the Web service” on page 459.
Note that you have now two proxy classes and two folders with a sample test
application. The code of both is identical.
Application Developer provides an easy way to create a client Java application for
a Web service. The Web Service Client wizard generates the Java proxy and,
optionally, a sample Web application that gets you started quickly in using Web
services in your Web applications.
The code is generated and the test client opens (Figure 13-18).
Summary
In this chapter, we introduced Web services. We then showed an example of
using Application Developer to generate a Web service from an existing
JavaBean. Finally, we showed how easy it was to create a Web service client
using the built-in wizard.
More information
The 2003 IBM Redbook WebSphere Version 5 Web Services Handbook,
SG24-6891, goes into thorough detail about the concept of SOA as well as Web
Services for WebSphere Version 5. It also contains examples using Application
Developer Version 5.
Additional information about using and creating Web Services is available from
the online help included in Application Developer.
In this chapter we introduce you to the Visual Editor and develop a sample GUI,
which lists the content of a table in a DB2 database and has an action that writes
the selected value back to a text field. This GUI is runnable as a JavaBean and
as a Java application.
The Visual Editor allows you to compose class files visually. Using the Visual
Editor, you can drag beans from different palettes, manipulate them in the Design
view, and edit their properties in the Properties view. The Visual Editor also
includes a Source view where you can both see and modify the generated Java
code. You can make changes in either the Source view or in the Design view.
The new Visual Editor provides similar function as the earlier VisualAge for Java
Visual Composition Editor. Unlike VisualAge for Java, the Visual Editor is a code
centric editor, so you have to use its embedded Java editor to write event
handling logic.
Sample GUI
The sample GUI we develop in this chapter is shown in Figure 14-1. The sample
GUI displays a list with the last names of customers that are stored in the sample
EJBBANK database. The GUI also provides a push button action that retrieves the
corresponding first name of the customer and writes the first name to a text field
in the GUI.
JTextField bean
By creating the sample GUI, you should learn how to work with the new Visual
Editor and how to compose and add visual components, change their properties,
add event handling code, and run the GUI.
Once this is done, we create a Java package named itso.gui. “Creating Java
packages” on page 99 provides information regarding this issue. Our new project
skeleton is shown in Figure 14-2.
You also have to update the Java build path for this project. You do this by
selecting the ItsoProGuideGUI project and Properties from the context menu.
Then you select the Java Build Path entry and the Libraries tab (Figure 14-3).
Click Add Variable, select DB2JAVA and confirm both dialogs with OK.
After having created the project, we create a new class and launch the Visual
Editor.
In this example we create a visual class as described in the first step above
(“Creating Java classes” on page 100 provides more information about how to
create a new Java class).
Note: The .java file that you open in the Visual Editor must be stored in a
Java project.
Enter CustomerGUI in the Name field, make sure the package is set to itso.gui,
select Panel from the extension list, select Swing—our sample class will inherit
from the javax.swing.JPanel class—and select to have a main method created
(Figure 14-4).
Table 14-1 shows a brief description of the user interface classes that can be
selected in the New Java Class dialog.
Other Any superclass, probably inheriting from Choose your own superclass.
one of the Swing or AWT classes
Clicking Finish creates the new CustomerGUI class and opens the Visual Editor.
Figure 14-5 shows the new class CustomerGUI in the Visual Editor.
Note: The big dot in front of the Visual Editor menu item of the context menu
indicates that the last editor used was the Visual Editor.
When the Visual Editor is launched, some additional views open automatically:
The Java Beans view, in the bottom left corner of the workspace, displays the
structure of the JavaBeans in a tree view.
The Properties view lets you view and modify attribute settings. The
Properties view is opened in the same pane where the Outline view is
located, by default, on the right-hand side of the workspace.
Tip: Clicking the Overview button, which is located at the bottom right corner
of the Design view, brings up a new subpane where you can navigate to a
specific section on you GUI. This is practical when you work with larger GUIs.
Figure 14-8 shows the default Workbench of the Visual Editor, including the Java
Beans view and the Properties view.
If you click the down arrow located in the center right of the separator between
the Design view and the Source view, the Design view will be maximized to allow
you to work with a large area for the JavaBeans (Figure 14-9).
Maximize
the Design
view or
maximize
the Source
view
Hide the
bean
palette
You can hide the bean palette by clicking the left arrow button on the separator to
the right of the palette.
You can also change the default appearance of the Visual Editor by modifying its
preferences. If you prefer to have more space to work in, you can choose to stack
the Design and Source views rather than tiling them. You can also choose to
show or hide the bean palettes by default.
Click Window -> Preferences, open the Java tree and select Visual Editor. This
will bring up the Visual Editor preferences (Figure 14-10).
The section Show the Visual Editor and Source Editor allows you to choose if you
want to stack the Visual Editor and the Source Editor or to split them. If you
choose to stack the Design and Source views, you can switch between them by
clicking the Design and Source tabs that now appear in the editor area
(Figure 14-11).
The check box with palette in editor part indicates if the Palette view with the
JavaBeans will be displayed in the Visual Editor or not.
The Generate try{}catch{} block check box will generate, if enabled, a try{}
catch{} statement in your source code when modelling JavaBeans.
The Source Synchronization Delay settings can be changed to change the delay
time that is used to make updates from the Java Beans model to the source code
from its initial value of 500 milliseconds. Making updates from the source code to
the Java Beans is initially set to a larger factor. See “Code synchronization” on
page 483 for more information according the synchronization between the
source model and the JavaBeans model.
You have to close and reopen an existing Visual Editor to see the changes.
By default, when you create a new Java class, the Java editor opens. When you
open an existing .java file, the editor that you last used for editing that file opens.
To change the default editor that opens for .java files, click Window ->
Preferences, expand the Workbench category and select File Associations
(Figure 14-12). Select .java from the File types list and select the editor that you
want to set as default, then click Default.
In the next section we show how to work with the Visual Editor and its
JavaBeans.
package itso.gui;
import javax.swing.JPanel;
/**
* @author IBM Itso
*
* ......
*/
public class CustomerGUI extends JPanel {
The canvas lets you select Java beans. To resize the JPanel, select the panel
(the little square) and use the mouse to move and resize it.
To make the JPanel larger, move the cursor over its bottom right edge so that it
becomes a southeast arrow, then left-click and move the cursor to the desired
size, and finally release it. After performing this action your JPanel should look
like Figure 14-14.
Once you have resized the panel, Visual Editor synchronized the changes with
the source editor. A constructor and an initialize method have been added to
the sample class including the line of code that sets the new size for the panel.
The initialize method is called from the CustomerGUI constructor.
package itso.gui;
import javax.swing.JPanel;
/** ...... */
public class CustomerGUI extends JPanel {
/**
* This method initializes
*
*/
public CustomerGUI() {
super();
initialize();
}
public static void main(String[] args) {
}
/**
* This method initializes this
*
* @return void
*/
private void initialize() {
this.setSize(310, 180);
}
} // @jve:visual-info decl-index=0 visual-constraint="0,0"
Code synchronization
When you are working with the Design and the Source views, this forces Visual
Editor to maintain both internal modules:
The representation of the JavaBeans, used in the Design view, the Properties
view, and the Java Beans view
The source that represents the code
To show that the models are not synchronized, the status label changes from
In Sync to Out of Sync (Figure 14-17).
After a period of inactivity, for example when you have stopped typing code in the
editor, synchronization will occur. While synchronization is taking place the
flashing arrow will show the direction the update is occurring. For example, the
up arrow represents changes from the source to the Java beans model, and the
down arrow vice versa.
You can also disable synchronization by pressing the pause button between the
two arrows. This is a good idea when you wish to make a number of large
changes to the source without incurring the overhead of the synchronizer.
Note: While the synchronizer is paused, you can make changes to the source
without any overhead of parsing source, but you can no longer make changes
to the JavaBeans model. All changes in the Design view, the Java Beans
view, or the Properties view will not be applied.
While the source code is being parsed and analyzed, the synchronizer may
determine that the source contains errors, and rather than trying to update the
JavaBeans model, it will wait for the errors to be corrected. If this occurs the
button will become pressed automatically and the graphic will be changed to this
symbol:
Move the mouse pointer to the Design view and somewhere over the gray
panel and click the mouse button again to drop the bean (Figure 14-19).
The Design view should now look like shown in Figure 14-20. The additional
JPanel has been placed on the top of the main panel.
Now we want to add a second JPanel to our GUI. This time we use another
technique:
Select the JPanel item from the Swing containers selection in the Palette
view.
Drop the panel on the this object in the Java Beans view (the top element of
the tree). Figure 14-21 shows where to point the mouse cursor to drop the
panel.
A more detailed description about the Java Beans view and how to work with this
view is provided in the next section “Working with the Java Beans view” on
page 490.
So far we have shown that there are two ways to add a component to the GUI:
Select a component and drop it on the Design view
Select a component and drop it on the Java Beans view
The properties list of the resized JPanel—which is actually root object in the Java
Beans view—are shown in Figure 14-23.
To select the JPanel and display its properties, simply left-click somewhere in the
gray pane of the Design view.
The Properties view allows you to view and edit their values. When you change a
value in the Properties view, the Design and Source views are updated. For
example, you can change the size values and see the panel adjust in the Design
view.
Some properties have a restricted set of enumerated values, which means that
you cannot change the value in the text field of the Properties pane, but instead
pick a value from a list.
In our sample GUI, we want to change the layout property of our JPanel from its
initial value FlowLayout to the value GridLayout. Therefore, click in the cell which
contains the value FlowLayout and click the drop-down button to open the value
list and select GridLayout. Figure 14-24 shows the list of the layout property.
Note: Some properties, for example the GridLayout value for the layout
property shown above, are themselves JavaBeans. This means that you can
expand these beans to view and change their properties. This also applies if
the nested properties are JavaBeans as well.
Tip: The right angle bracket > in front of a property item in the Properties view
indicates that the property has been changed from its default value.
By clicking the drop-down arrow located right to the Properties view title—as
shown in Figure 14-25—a menu opens where you can filter the Properties you
want to be displayed in the Properties view.
Tip: The Java Beans view provides an easy way to select and move an object
in the Visual Editor. As you start laying components in the Visual Editor, it may
be hard to drop a component in the target container in the Design view. Using
the Java Beans view helps you also to see what visual components contain
other visual components.
The selection between the entries in the Java Beans view and those in the
Design view is synchronized both ways, so if you select an item or multiple items
in the Design view, then they are also selected in the Java Beans view.
Also, in the Java Beans view, the icon shown for the entry is the same icon that is
used in the palette to represent the bean type.
Now we want to rename both JPanels we have created in the previous step. To
do this, we open the context menu of the jPanel component as shown in
Figure 14-26 and select Rename Field.
Note: The context menu item Delete allows you to delete the selected
JavaBean. By deleting a bean, the Design view and the Source view will be
updated and synchronized appropriately.
If we have not saved our file yet, the dialog shown in Figure 14-27 comes up.
Click OK to save the file CustomerGUI.java and close the dialog.
The Refactoring dialog comes up next. The section “Refactoring” on page 122
provides a detailed description of the refactoring process in Application
Developer.
Enter jPanelLeft in the new name field (Figure 14-28), leave the other default
values in the refactoring dialog as they are, and click Finish.
The Design view and Source view will be synchronized by Application Developer
and the code will be changed appropriately.
Repeat the refactoring step for the bean jPanel1 and rename it to jPanelRight.
The Java Beans view should now look as shown in Figure 14-29.
Tip: Moving a JavaBean by using the Java Beans view is very simple. Select
a bean, move it to the appropriate spot in the tree, and drop it there. When
moving a bean, a horizontal line is displayed. This line helps you locate the
exact position where you want to drop the bean.
To add the label, select the JLabel bean from the Swing components of the
Palette view and drop it onto the jPanelLeft (Figure 14-31). Alternatively, you
can drop the label into the left panel in the Design view.
Rename the jLabel to jLabelCustomerList and change the Text property from
JLabel to Customer List (Figure 14-32). Modifying the text property changes the
text of the label which is displayed on the GUI.
Change the name of the list from jList to jListCustomers and change its gridy
property (you have to expand constraint) from -1 to 1 (Figure 14-33).
Changing the gridy property aligns the JList below the JLabel within the
jPanelLeft bean.
Tip: The gridy property is used to set the vertical position of objects, where
the topmost cell has gridy=0.
You also have to change the property selectionMode from its initial value
MULTIPLE_INTERVAL to SINGLE. This prevents us from selecting multiple
elements from the list bean.
In case our list contains many entries, it is a good idea to have a scroll bar added
to the list bean.
To do this, you need to select the JScrollPane bean from the Swing containers
and add it to the jPanelLeft bean. Rename the new scroll pane to
jScrollPaneForCustomersList and change its gridy property from -1 to 1.
To associate the scrollpane with the jListCustomers bean, you can add a line of
code to the getJScrollPaneForCustomersList method:
jScrollPaneForCustomersList.setViewportView(getJListCustomers());
Even simpler: Select the jListCustomers bean in the Java Beans view and drop
it onto the scroll pane. This makes the list a component of the scroll pane and
adds the required line of code to the getJScrollPaneForCustomersList method:
The complete code of the scroll pane is shown in Figure 14-35. If you click the
jScrollPaneForCustomersList bean in the Java Beans view, the Visual Editor
automatically navigates to this code in the Source view.
Once the JLabel has been added, we add a JTextField to the jPanelRight
bean. Also rename the JTextField from its initial value jTextField to
jTextFieldCustomerSelection and change the gridy property from -1 to 1, to
align the bean appropriate within this GridBagLayout panel.
We also want to change the background color and the disabled text color
properties of the text field. By doing this, we demonstrate that we can also
overwrite the default properties of a JavaBean by using the source editor.
This statement will change the background color of the text field to the same as
the jPanelRight panel uses as its background color. To resolve the Color class,
select Color and Source -> Organize Imports (context). Application Developer
also adds automatically the following import statement to the class:
import java.awt.Color;
The last JavaBean we want to add to our sample GUI is the JButton. Add the
JButton bean to the jPanelRight, rename from jButton to jButtonGetFirstName
and also set the text property to Get First Name. The gridy property should also
be changed from -1 to 2.
To improve the layout of our sample GUI, we now change the insets property for
all beans mentioned above. Figure 14-36 shows the insets property of a
GridBagLayout component.
Now we have finished designing the sample GUI. Figure 14-37 shows the Java
Bean view of our sample GUI.
We want to reuse most of the code of this class in our ItsoProGuideGui project,
modify some statements, and fill the jListCustomer bean with the last names of
all records provided in the CUSTOMER table of the sample DB2 database.
Note: This sample provides a simple guide showing how to create a small GUI
with some logic behind it. For simplicity, this code does not follow any
architectural practices or rules.
There are two ways to add the CustomerListing class to this project:
Create the class from scratch, place it in the itso.gui package, and add the
code.
Copy—if it exists—the class CustomerListing from the itso.java package of
the ItsoProGuideJava project to the iso.gui package of this project and
adapt the code.
Figure 14-39 shows the sample class, where bold statements differ from the
original Java class. The code is provided in:
\sg246957\sampcode\dev-visual\initial\CustomerListing.txt
The setListData method of the JList object adds the allCustomers vector to the
list.
If you would run the GUI now, then the last names of the customers would be
displayed.
To do this, we first add a new method to the CustomerListing class. This method
is called by a new method of the CustomerGUI class that has not been
implemented yet.
Figure 14-41 shows the code of the new method. By a given key—in this
example the last name—this method returns the corresponding first name.
Next we add a new method to the CustomerGUI class. This method is called by
the jButtonGetFirstName bean and returns the first name of the customer
selected in the jListCustomers.
The method checks if an entry in the jListCustomers bean has been selected.
If so, the method calls the getFirstNameByKey method, which returns the
corresponding first name of the selected entry. If nothing has been selected in
the list, the method returns a string which says: No customer selected .
if (getJListCustomers().getSelectedIndex() == -1) {
// Nothing has been selected in the list
result = "No customer selected.";
} else {
// An item has been selected in the list
String selectedItem =
getJListCustomers().getSelectedValue().toString();
CustomerListing customerList = new CustomerListing();
result = new String(customerList.getFirstNameByKey(selectedItem));
}
return result;
}
We have to implement the action listener to trigger an action when the button in
our GUI has been clicked.
The Visual Composition Editor of Visual Age for Java allowed you to generate
program logic by making connections between JavaBeans. Visual Age for Java
generated the appropriate code to attach the listener to the source JavaBean,
and then executed the desired action on the target.
The new Visual Editor in Application Developer does not implement the concept
of creating connections graphically between JavaBeans. Such program logic is
specified by writing code directly in the Java editor. To help developers write the
event handling code, Visual Editor provides several content assist templates.
Usually, each template has the same name as the method it is designed to work
with. The template for adding an action listener to a JavaBean is named
addActionListener.
After you write the beginning of the line of code, for example,
jButtongetFirstName.addA, you can invoke code assist by pressing Ctrl-Space
on your keyboard. The template will appear at the bottom of the content assist
list, as shown in Figure 14-43.
Note: If the template for the event you wish to add is not present in the
available code assist list, then you might be able to import it into Application
Developer. The import file is named allTemplates.xml and is located in the
Application Developer’s folder:
wstools\eclipse\plugins\com.ibm.etools.jbcf.codegen_5.0.1\Examples\
Templates\java\awt\event
See “Code assist” on page 118 for more information regarding templates.
The code skeleton as shown in Figure 14-44 is created automatically, after the
addActionListener template has been added.
jButtonGetFirstName.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
}
});
This statement calls the getFirstName method and writes the return value to the
jTextFieldCustomerSelection bean.
jButtonGetFirstName
.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
getJTextFieldCustomerSelection().setText(getFirstName());
}
});
}
return jButtonGetFirstName;
}
By now, we have finished designing our sample GUI, including an event handler,
and are able to run and test it.
In this section we show how to run the sample as a JavaBean and as a Java
application. Additional information about running a Java class is provided in the
section “Running your programs” on page 103.
However, when you write a JavaBean using the Visual Editor, it will not typically
have a main method. Rather than having to add a main method, to allow you to
test JavaBeans classes, there is an additional option available from the Run
menu called JavaBean that invokes a JavaBean launcher.
Click New to create a new launch configuration for the class CustomerGUI.
Other tab views let you specify the JRE, program, and VM arguments, classpath
information, and additional settings. Besides using the JavaBean launcher to run
your JavaBeans, you can also select Debug -> Debug As -> Java Bean to run
JavaBeans using the debugger.
Figure 14-47 shows the new launch configuration with the JavaBean tab. Leave
the default values and click Run.
The GUI should be launched now, and Figure 14-48 shows what the launched
sample GUI looks like.
Also, in the launch configuration dialog, you can change the Swing look-and-feel,
which controls the appearance of visual components in the GUI. As the default
If you change the launch configuration and launch the sample GUI with the
Windows look-and-feel, our GUI looks as shown in Figure 14-49 on page 507.
Figure 14-50 shows the main method including the additional code. As we use a
JPanel, we have to put this panel first in a frame, to make it runnable as a Java
application.
Finally, we have to set the frame object visible, and our sample GUI is now also
runnable as a Java application.
frame.setSize(330, 150);
frame.getContentPane().add(customerGUI);
frame.setVisible(true);
}
Note that we set the vertical size of the frame to 150, not big enough to hold all
the last names. In this case the scroll bar appears so that we can scroll through
the names (Figure 14-51).
JScrollPane
bean
You can also resize the GUI and see the GUI ‘s behavior. If you for example
reduce the size of the GUI as shown in Figure 14-51, the implemented scroll
pane of the list becomes visible. Also,the beans align automatically.
Another difference with respect to the Visual Composition Editor from Visual Age
for Java is that the new Visual Editor directly reads and writes source code and
has no additional metadata files associated with a visual class.
We also implemented event handling code to the GUI and showed how to run
and test such a visual bean.
This chapter describes how to use the Server perspective to set up and use
servers and server configurations to test applications.
The server tools feature uses servers and server configurations to test and
deploy your projects. Servers identify server instances where you can run your
projects and server configurations contain setup information for the servers. You
can have multiple server configurations with different settings and then select
which configuration a particular server should use. This allows you to easily
switch between different setups of memory configurations, data sources, trace
settings, class loading policies, and so forth. Servers and server configurations
are kept in server projects.
If you do not have any servers or server configurations set up, you can have the
server tools create them for you automatically. However, doing it manually using
the server tools wizards gives you more control over what is being set up.
The server tools feature allows you to create servers and server configurations
that can run resources from the following types of projects:
Web projects—containing servlets, JSPs, HTML files, and Java beans.
Web projects can also contain Web services to be tested.
EJB projects—containing EJB beans.
Enterprise application projects—containing Java Archive (JAR) files, Web
and EJB projects.
Using the Server perspective, you can manage the servers and server
configurations and start, stop, or restart them.
When running the Application Developer built-in test environments, the server is
running against the resources in your workspace. This allows you to add,
change, or remove resources from your enterprise application, and the server is
able to pick up these changes without having to be restarted.
The IBM Agent Controller is not required when using the Application Developer
built-in test environments or when using Apache Tomcat, unless you want to
perform profiling (see Chapter 20, “Profiling applications” on page 655).
There is also a new server type called the J2EE Publishing Server. This feature
allows you to deploy J2EE applications developed in Application Developer to
remote J2EE compliant servers that require minimal configuration (for example,
Tomcat/JBoss), and then test the client applications from the Application
Developer Workbench. We do not cover this server type in this book, but if you
are interested in learning more about it, you can take a look at the following
WebSphere Developer Technical Journal tutorial:
http://www7b.software.ibm.com/wsdd/techjournal/0302_koo/koo.html
The server options available to you in Figure 15-2 depend on what servers you
installed with Application Developer.
If you also select the Set server as default (do not prompt) you will not be
prompted for which server to run this project on when using the Run on Server
option in the future. This setting is available in the project’s properties if you want
to change it later.
Note: Before you run the application for the first time, make sure that no
servers or server configurations exist, otherwise you will not see the same
dialogs as shown here.
The server tools feature automatically does the following for you:
Opens the Server perspective
Creates a server project called Servers
Creates the server you selected and gives it a default name (for example,
WebSphere v5.0 Test Environment)
Note: If you select Run on Server from the context menu of an Enterprise
Application project, Application Developer will not open a Web browser for
you. If you select a Web project, however, it will open the Web browser and go
to the URL of the Web project’s context root. If you select an EJB project, the
universal test client is started.
Using a built-in server: See “Creating a server for testing” on page 224 for
instructions to define a built-in server and server configuration (ItsoServer).
Before proceeding, you should make sure that the following products are
installed on the remote machine:
WebSphere Application Server 5.0
IBM Agent Controller
Also make sure that only the IBM Agent Controller is started (this will control the
starting and stopping of the remote WebSphere Application Server).
From the File menu, select New -> Project and then Server -> Server Project.
The Create a New Server Project wizard opens (see Figure 15-4). Enter
ItsoProGuideServer as the project name and then click Finish.
If you are creating a server on a remote machine and want to use the copy
mechanism you must have the drive where the server (only WebSphere
Application Server is supported for remote testing) is installed on the remote
machine mapped to a local drive letter on the Application Developer machine.
To use the FTP mechanism, you must have an FTP server active on the remote
machine. We will not explain how to set this up, as that depends on the FTP
server chosen. We will, however, explain how to set up Application Developer to
use both copy and FTP file transfers.
On the WebSphere Remote Server Settings page (see Figure 15-6) enter the
IP address or hostname of the remote machine running the WebSphere
Application Server 5.0 product. Then click Next.
Once Application Developer has connected to the remote IBM Agent Controller,
the window shown in Figure 15-7 is displayed.
The WebSphere installation directory is prefilled with the information the IBM
Agent Controller collected on the remote machine.
If you select the Use default WebSphere deployment directory it means that
Application Developer will publish the enterprise application and server
configuration to the directory where the remote WebSphere Application Server
installation keeps its information, overwriting the information there. Deselecting
this check box allows you to enter another directory (that should exist on the
remote machine) where the information should be published instead.
When publishing to the remote server, the Enterprise Application and server
configuration will be published to the installedApps, config, and properties
directories under the remote deployment directory.
If you want to run DB2-based applications, you must define the DB2 driver
location. If you forget to specify the driver location, you can open the
configuration editor later and specify the location on the Server page (see
Figure 15-30 on page 544).
Click Next.
On the page shown in Figure 15-8, you can define a new remote file transfer
instance or reuse an existing one, if one exists. A remote file transfer instance
contains information on how to transfer the Enterprise application and server
configuration to the remote server when publishing. Select Copy file transfer
mechanism and then click Next.
In the Project folder field, enter the name of the project folder in your
workspace where the remote file transfer instance should be created. In our
example we place it in the ItsoProGuideServer project folder.
In the Remote file transfer name field, enter a name for the remote file
transfer instance. We choose the name vertex-copy.
In the Remote target directory field, type the name of the directory on the
remote machine where you want your Enterprise application and server
configuration to be published. The remote target directory is the one as seen
by the local machine (where Application Developer is running). In our case we
have mapped our W: drive to C:\ of the remote machine, so we enter
W:/WebSphere/AppServer. If setting up a local server, the remote target
directory would have been the same as the WebSphere deployment directory
in Figure 15-7.
Note: Make sure you have both read and write permissions on the remote
resource.
Click Finish.
In the Project folder field, enter the name of the project folder in your
workspace where the remote file transfer instance should be created. In our
example we place it in the ItsoProGuideServer project folder.
In the Remote file transfer name field, enter a name for the remote file
transfer instance. We choose the name vertex-ftp.
In the Remote target directory field, type the name of the directory on the
remote machine where you want your Enterprise application and server
configuration to be published. The remote target directory points to the
WebSphere deployment directory that is seen from the Application Developer
machine, being the FTP client. In our case the WebSphere deployment
directory on the remote machine is c:\WebSphere\AppServer and when
logging on to the FTP server we are placed in the /c:/ directory, so our remote
target is /c:/WebSphere/AppServer.
In the Host name field, enter the IP address or hostname of the remote
machine.
In the User login and User password fields, enter the FTP user ID and
password that will be used to access the machine.
If you need to use passive FTP mode or need to go through a firewall, select
the appropriate check boxes. If you click the Firewall Settings button, you can
specify the type of firewall used and the information required to connect
through it.
Click Finish.
Note: Depending on what configuration type you select, the Next button,
allowing you to specify the details of the server configuration, may or may not
be enabled. In the case of a WebSphere version 5.0 configuration, it is
enabled.
The window in Figure 15-13 allows you to set the port number for the
WebSphere Application Server 5.0 built-in HTTP server. You can use the
same port number for multiple server configurations as long as they are not
run simultaneously. Keep the default value of 9080 and click Finish.
Note: To test using the IBM HTTP Server (Apache server) in the remote
machine, you must customize the server configuration so that the IBM HTTP
Server plug-in configuration is updated in the remote machine. See
“Customizing server configurations” on page 544 for information on how to do
this. The HTTP port number in Figure 15-13 should still be 9080.
Note: Clicking the (Menu) down-arrow in the Server Configuration view allows
you to switch it to advanced display mode. In advanced mode, the servers and
server configurations are displayed in separate trees, giving you a better
overview.
In the next dialog (see Figure 15-13 on page 529) enter a port number for the
server. Keep the default of 9080 and click Finish.
This creates a new server and a default server configuration for you and assigns
the server configuration to the server.
This means that your application can actually be associated with multiple servers
at the same time. If you launch your application by using the Run on Server
From our first example (see “Creating server and server configuration
automatically” on page 516) where we automatically created a server project, a
server and a server configuration, we already have the ItsoProGuide Enterprise
Application project assigned to the WebSphere v5.0 Test Environment server
(which is a built-in test environment).
We will now also add this project to the new server configuration we have
created. From the Server perspective, Server Configuration view select the
WebSphere v5.0 on vertex (Copy) server and select Add -> ItsoProGuide from
its context menu as shown in Figure 15-17.
The project is now associated also with the WebSphere v5.0 on vertex (Copy)
server.
Note: You can only assign enterprise applications to a server. This action
assigns all contained modules (for example, Web and EJB) to the server.
Open the configuration editor for the WebSphere v5.0 on vertex (Copy) server in
the Server Configuration view.
Be sure to select Use this data source in container managed persistence for the
EJB-based applications to work (see Figure 8-11 on page 257).
On the Data source page, open the EJBBANK data source and set the
authentication alias (Figure 15-20). Save the configuration.
To start a server manually, select the WebSphere v5.0 on vertex (Copy) server in
the Server Configuration view or in the Servers view (Figure 15-21):
In the Server Configuration view, select Control -> Start (context)
In the Servers view, select Start (context).
You will see the output from the remote server stdout log file in the Console
window (lower right part of Figure 15-23).
When the Console window shows the application is started, you can start a Web
browser by clicking the icon in the toolbar. This brings up the Web browser
and you can enter the URL for the applications.
You can run most of the applications we developed without any changes, for
example:
http://vertex:9080/ItsoProGuideBasicWeb/
http://vertex:9080/ItsoProGuideStrutsWeb/
http://vertex:9080/ItsoProGuideWebServClient/sample/Banking/TestClient.jsp
http://vertex:9080/ItsoProGuideWebServClient/TestBankingWebService.jsp
When running the Struts Web application, your Application Developer window
should look like Figure 15-23.
Tip: If you select a project or an HTML/JSP file and Run on Server, the
enterprise application is published again to the server. This can be time
consuming for larger applications. It is faster to start a browser and enter the
URL. You can also use an external browser instead of the internal browser of
Application Developer.
Notes:
If you start the remote WebSphere Application Server instance before you
start the IBM Agent Controller, you will receive an error message. Make
sure the IBM Agent Controller is started first so it can keep track of the
state of the WebSphere Application Server instance.
Do not stop the IBM Agent Controller when it is in control of a server. Doing
so may cause it to lose track of the state of the server, and you may have
to manually terminate the server process in the remote machine using the
Windows Task Manager.
Using the Control option in the server’s context menu in the Server Configuration
view or the context menu of the server in the Servers view are the best ways for
controlling servers.
ItsoProGuideDatabaseWeb
The TestDBBeans.jsp requires a user ID and password for the remote server:
<% Connect.setDriverName("COM.ibm.db2.jdbc.app.DB2Driver");
Connect.setUrl("jdbc:db2:EJBBANK");
Connect.setUsername("db2admin"); // authoized user ID
Connect.setPassword("xxxxxxxx"); // authorized password
SelectStatement.setConnectionSpec(Connect);
SelectStatement.setCommand("SELECT * FROM ITSO.CUSTOMER");
SelectStatement.execute();
out.println("Row count is: " + SelectStatement.getRowCount());
%>
xxxxxxxx
Figure 15-25
ItsoProGuideStoredProcWeb
To run the stored procedures you have to redefine the stored procedures in the
remote server DB2 system. You can use the DB2 net JDBC driver to connect to
the database on the remote server and import the table definitions. Then you
would have to recreate and build the stored procedures for the remote DB2
server.
Note: Building DB2 stored procedures using the net driver is very unstable.
One solution is to define the remote database locally and use the app driver.
Another solution is to build the procedures on the remote system.
Apache Tomcat
Application Developer 5.0 ships with support for Apache Tomcat 3.2, 4.0 and 4.1.
However, it does not ship with the Apache Tomcat product itself. To use Apache
Tomcat, you must therefore first download and install it on the machine running
Application Developer.
Once this is done, you can create a server and a server configuration as
described in “Creating a server and server configuration together” on page 530,
and select the appropriate version of Tomcat as the server type.
Note: Apache Tomcat can only be run as a built-in and local server, not as a
remote server.
TCP/IP Monitor
The TCP/IP Monitor is a simple server that monitors all the requests and the
responses between a Web browser and an application server. By default, when
the TCP/IP Monitor is started, it listens for requests on port 9081 and then it
forwards these requests to the application server on port 9080. For responses
from the application server, the TCP/IP Monitor forwards them back.
This creates a monitoring server that listens to port 9080, which is the default
for a WebSphere v5.0 test environment. If you would like to monitor a
WebSphere v4.0 test environment, select Monitor on port 8080 as the
template instead.
By selecting an HTTP request in the top pane, you can see both the request
from the browser and the response returned by the HTTP server.
Tip: You can use the TCP/IP Monitor to watch HTTP traffic as well as Web
services traffic. By default the generated proxy classes route the SOAP
requests to port 9080, but you can easily change that port to 9081 and watch
the SOAP messages in the TCP/IP Monitor.
You can either change the Java code of the proxy or dynamically change the
target address using the getEndpoint and setEndpoint methods.
Figure 15-30 shows the window for our WebSphere 5.0 on vertex (Copy) server
using a WebSphere Application Server 5.0 configuration. We double-clicked the
server, thus the extra Server tab is shown.
We will not explain all the options available in this server configuration, only
highlight some of the less obvious ones. If you make any changes, be sure to
press Ctrl-S to save them before starting a server using the configuration.
Server page
On the Server page (Figure 15-30) you can select if you want to generate the
HTTP server plug-in configuration. Doing so re-generates and publishes the
plugin-cfg.xml file allowing you to test using the IBM HTTP Server on the
remote machine (and not only the application server’s built-in HTTP server). The
plugin-cfg.xml file will be published to the config directory under the
WebSphere remote deployment directory (Figure 15-7 on page 523).
You can also change the Application class loader policy for the server, which
controls the isolation between the applications (EARs) deployed to the server.
The application class loader is the class loader that loads the EJB JARs, utility
JARs and RARs (resource archives) contained in an EAR:
SINGLE policy means that there is only one such class loader in the server.
This means that there is no isolation between the EARs in the server and that
classes in an EAR can see classes in the other EARs.
MULTIPLE policy, on the other hand, gives each EAR its own application
class loader which then isolates the EARs from each other. This is the
recommended setting and follows the J2EE 1.3 class loading specification.
Applications page
On the Applications page (Figure 15-32) you can also change the application
class loader mode. This determines how the application class loader should
delegate the loading of classes.
The Applications tab also allows you to change the WAR class loader policy,
which affects the isolation between the Web modules in an EAR:
When using MODULE policy, each Web module gets its own class loader and
the Web modules are isolated from each other. This is the default and
recommended setting.
When using APPLICATION policy, the classes in all Web modules in the EAR
are loaded by the application class loader and there is no isolation between
the Web modules.
By default the IBM Java Virtual Machine used by Application Developer sets
its maximum heap size to half the amount of RAM installed in the machine.
For a machine with 512MB of RAM, this means that the JVM of Application
Developer has a maximum heap size of 256MB.
When a built-in server environment is started, Application Developer starts a
new JVM for the server. By default, this JVM also has a maximum heap size
setting of half the amount of RAM installed in the machine, so on a 512MB
machine this JVM also uses a maximum heap size of 256MB.
When the heaps in these two JVMs reach their maximum size, they have in
total consumed 512MB of RAM, equal to the total amount of RAM installed in
the machine.
As the JVM processes themselves require more RAM than just their heap and
the operating system and other processes on the machine also require RAM,
this can lead to excessive swapping, slowing the whole machine down.
By adding the -Xms and -Xmx options (Figure 15-33) to set the initial and
maximum heap sizes of the built-in test server JVM you can limit the amount
of ram this process will consume. Lowering this setting, however, leads to
more frequent garbage collection, but it can improve performance anyway
since swapping to disk is really slow.
These settings can be tuned together with the -Xms and -Xmx settings for the
JVM of Application Developer (see “Memory consideration” on page 25) to
achieve a system that performs well even in a memory constrained
environment.
On a 512 MB machine, we have been able to find a sweet spot for our
environment by using the following values:
Application Developer JVM: -Xms128M -Xmx128M
Built-in test server JVM: -Xms96M -Xmx96M
Using these values, we have been able to keep our Windows 2000 installation
with Application Developer 5.0 and some applications running within the 512MB
limit without too much swapping.
Administrative console
If you enable the administration console (Figure 15-30 on page 544) and start a
server using the configuration you can launch the administration console for the
server by selecting the server in the Servers view and then select Run
administrative console from its context menu (Figure 15-34).
This brings up the administrative console for the server (Figure 15-35), allowing
you to perform administrative tasks and change settings not available in the
server configuration.
The trick to applying the Application Server Fix Packs to Application Developer is
first to get the right Fix Pack, and then to know where to install it.
Application Developer 5.0 comes with support for the following Application
Server built-in test environments:
WebSphere Application Server 5.0
WebSphere Application Server 5.0 Express
WebSphere Application Server 4.0 Advanced Edition Single Server
The Fix Pack to download must therefore be for one of these products.
Once the Fix Pack is downloaded, you must to know where to install it.
WebSphere Application Server’s default installation directory is C:\Program
Files\WebSphere\AppServer. However, in Application Developer the run-times
are located in the following directories:
WebSphere Application Server 5.0:
<wsad_home>\runtimes\base_v5
WebSphere Application Server 5.0 Express:
<wsad_home>\runtimes\express_v5
WebSphere Application Server 4.0 Advanced Edition Single Server:
<wsad_home>\runtimes\aes_v4
When prompted for the Application Server Home directory during fixpack
installation, you should enter the corresponding directory above.
At the time of writing, there are no Fix Packs available for Application Server 5.0,
so in this example we update the Version 4.0 test environment to Fix Pack 5
(4.0.5).
When the Fix Pack is applied, you can start the server in Application Developer
and verify that it was successfully updated. When starting our server the
following message was displayed, indicating a successful update:
*** Starting the server ***
IBM WebSphere Application Server, Release 4.0.5
Advanced Single Server Edition for Multiplatforms
Copyright IBM Corp., 1997-2001
Summary
In this chapter we have shown you how to use the server tools feature of
Application Developer to test Web and EJB applications. We set up both a
built-in test environment and a remote WebSphere Application Server, and we
published and tested an application.
We examined the server configurations and gave you some tips on how to
improve performance.
The TCP/IP Monitor server was also covered. Finally, we showed you how to
update the internal test environment by applying WebSphere Fix Packs.
The Enable Hit Count property, when set, causes the breakpoint to be triggered
only when the lines has been executed as many times as the hit count specified.
Once triggered, the breakpoint is disabled.
The other property of interest here is Enable Condition. If set, then the breakpoint
is reached only when the condition specified in the entry field evaluates to true.
This condition is a Java expression. In our case, select Enable Condition and
enter customerNumber.equals("104"); as the condition. The breakpoint will only
be reached when you enter 104 as the customer ID.
The Restrict to Selected Thread(s) list is only filled if a server is running in debug
mode already, otherwise the list in empty.
Open the listAccounts.jsp that will be called from the ListAccounts servlet. Set
a breakpoint as shown in Figure 16-3.
You could also set a breakpoint in the lines with <jsp.getProperty> tags.
Sometimes reformatting the source code to have only one statement per line is
better for debugging.
Note: The server used for testing, for example ItsoServer, must be either
stopped or started in debug mode. Otherwise, an error message will be
displayed.
Tip: To debug a non-Web Java application, select Run -> Debug As -> Java
Application to start the debugger. This is the only difference between
debugging a Web application and debugging a Java application.
In the Debug perspective, you should now see index.html displayed in the Web
Browser view, as shown in Figure 16-5. Enter 104 as the customer ID.
Select the Skip radio button, then check the Disable step-by-step mode check
box, and click OK (Figure 16-6).
After step-by-step has been disabled, the servlet is executed. As soon as the
breakpoint in ListAccounts.java is reached, execution stops and the
ListAccounts.java source file is displayed with the line containing the break
point highlighted. The thread is suspended in debug, but other threads might still
be running (Figure 16-7).
When a thread suspends, the top stack frame is automatically selected. If you
select another stack frame, all visible variables in that frame are shown in the
Variables view.
Debug functions
From the Debug view, which should now be displayed in the top left pane, you
can use the functions available from its icon bar to control the execution of the
application. The following icons are available:
Resume: Runs the application to the next breakpoint
Suspend: Suspends a running thread
Terminate: Terminates a process
Disconnect: Disconnects from the target when debugging remotely
Remove All Terminated Launches: Removes terminated executions
In the upper right pane you can see the various debugging views that are
available.
Breakpoints view
The Breakpoints view displays all the breakpoints set in the Workbench.
(Figure 16-9).
You can use the breakpoints view to display and manipulate the breakpoints that
are currently set. You can open the properties (for example to set the hit count),
remove the breakpoint, or open its source file.
Watching variables
The Variables view displays the current values of the variables in the selected
stack frame. Follow these steps to see how you can track the state of a variable.
Click the Step Over icon to execute the current statement. Note that a new
variable banking has been added to the Variables view.
Click Step Over again and the customer variable is added. The plus sign (+) next
to a variable indicates that it is an object. Expand the customer to reveal the
values of its attributes (Figure 16-10).
If you want to test the code with some other value for any of these instance
variables, you can change one of them by selecting Change Variable Value from
its context menu. An entry field opens where you can change the value; for
example, you can change the last name to upper case (Figure 16-11).
Inspecting variables
To view more details about a variable, select a variable and Inspect from the
context menu. The result opens in expressions view (Figure 16-12).
Both the Variables and Expressions view can be split into two panes by selecting
Show Detail Pane from the context menu.
Evaluating an expression
To evaluate an expression in the context of the currently suspended thread, use
the Display view. Enter the expression customer.getFirstName(), then highlight
the expression and select Display from the context menu.
The results of the Java expression can also be inspected by selecting Inspect
from the context menu.
You can also highlight any expression in the source code and select Display or
Inspect (context). The result is shown either in the Display or Expressions view.
Select Remove from the context menu to remove expressions or variables from
the Expressions views. In the Display view just select the text and delete it.
Watch the array of accounts in the Variables view. You can expand accounts and
see their attributes (Figure 16-15).
Debugging a JSP
Step through the servlet code or click the Resume icon to progress to the
breakpoint in the JSP.
Figure 16-16 shows the Debug view with the JSP opened.
Note: If you have two JSPs in different Web applications, the wrong JSP
source may be displayed. Open the correct JSP to see its source code.
Watch the JSP variables in the Variables view. The same functions as for servlets
are available for JSP debugging. A JSP is compiled into a servlet. The difference
is that the debugger shows the JSP source code and not the generated Java
code.
When you step through JSP code, the debugger only stops at Java code; HTML
statements are skipped.
Resume execution to see the next Web page, then close the Debug perspective
and stop the server.
Important: This section assumes that you have already deployed the
ItsoProGuide enterprise application containing the ItsoProGuideBasicWeb
project to a remote Application Server. For details on deploying to a remote
server, see Chapter 18, “Deploying enterprise applications” on page 607
Enter WebSphere version 5.0 remote server attach as the server name, and
select WebSphere version 5.0 -> Remote Server Attach as the server type. Click
Next to proceed to the next page of the wizard.
On the next page, enter the host name of the remote host where WebSphere
Application Server Version 5 is installed (Figure 16-18). This can be your own
machine (localhost) or another machine (such as vertex used for remote
testing).
Figure 16-18 Specify the host for the remote server attach
Click Next to go to the next page of the wizard. There, you enter the port
numbers for JVM debug and for HTTP (Figure 16-19). The JVM debug port is the
port that Application Developer will use to communicate with the remote
application server during debugging. The HTTP port is the port used to send
HTTP commands through the Web browser.
By default, the JVM debug port is set to 7777 in both the wizard and in the
Application Server. In this example, we are connecting to a remote application
server that uses port 9080 for HTTP (the internal HTTP server). If the external
HTTP Server is started as well, we can use port 80.
Click Finish to create the remote server attach. In the servers view, this new
server is now listed (Figure 16-20).
You are taken to the debug perspective, and the remote server is connected
(Figure 16-21). You may now debug applications on the remote server.
Note: The project should already be published on the remote server. Here we
are just configuring this in Application Developer to allow us to debug.
Next, we debug the application on the remotely attached server. Select the
ItsoProGuideBasicWeb in the Navigator view and Debug on Server. If you are
prompted to select the server to debug the application on, select WebSphere
version 5.0 remote server attach.
Tip: Make sure that the server preference of the project properties is set to
prompt; otherwise the preferred server is started!
The index.html page of the Web application opens. You may now debug the
application in the same way you did in “Debugging a Web application” on
page 554. The only difference is that the application is running on a remote
server.
3
1
4
2
With the source code attached, you can debug the classes by stepping through
the code. Debugging on a remote server is basically the same as debugging on
the internal server.
Note: You may find response time quite slow. The more applications you have
deployed on the remote server, the slower is execution.
Communication with the remote server is terminated, and all threads in the
remote VM are resumed. Although the remote VM continues to execute, the
debug session is now terminated.
Summary
In this chapter we described the process of debugging Web applications on the
built-in server and on a remote WebSphere Application Server.
Tip: You can make your programs easier to debug by avoiding having multiple
statements on one line, and by attaching the source code to JAR files.
A good starting point for finding information about JUnit on the Web is the JUnit
Web site:
http://www.junit.org/
This site contains documentation and links, as well as a free download that
includes both the JUnit source and compiled code.
Unit testing
Unit tests are informal tests that are generally executed by the developers of the
application code. They are often quite low-level in nature, and test the behavior of
individual software components such as individual Java classes, servlets, or
EJBs.
Because unit tests are usually written and performed by the application
developer, they tend to be white-box in nature, that is to say they are written
using knowledge about the implementation details and test specific code paths.
This is not to say all unit tests have to be written this way; one common practice
is to write the unit tests for a component based on the component specification
before developing the component itself. Both approaches are valid and you may
want to make use of both when defining your own unit testing policy.
Perhaps it is more useful to look at the question from the opposite perspective,
that is to say, why do developers not perform unit tests? In general the simple
answer is because it is too hard, and because nobody forces them to. Writing an
effective set of unit tests for a component is not a trivial undertaking. Given the
pressure to deliver that many developers find themselves subjected to, the
temptation to postpone the creation and execution of unit tests in favor of
delivering code fixes or new functionality is often overwhelming.
We recommend that you take the time to define a unit testing strategy for your
own development projects. A simple set of guidelines, and a framework that
makes it easy to develop and execute tests, pays for itself surprisingly quickly.
Tests are easier to write, because a lot of the infrastructure code that you require
to support every test is already available. A testing framework also provides a
facility that makes it easier to run and re-run tests, perhaps via a GUI. The more
often a developer runs tests, the quicker problems can be located and fixed,
because the difference between the code that last passed a unit test, and the
code that fails the test, is smaller.
Note: An assertion is a statement that allows you to test the validity of any
assumptions made in your code.
This simple test case tests the result count of database query:
//Test method
public void testGetAccount(){
//instantiate
Banking banking = new Banking();
//invoke a method
Account account = banking.getAccount("104-4001");
//verify an assertion
assertEquals(account.getAccountId(),"104-4001");
}
/**
* Constructor for BankingTest.
* @param arg0
*/
public BankingTest(String arg0) {
super(arg0);
}
All test cases must have a constructor with a string parameter. This is used as a
test case name to display in the log.
Tests are executed using a test runner. To run this test, use TestRunner as
follows.
public static void main (String[] args) {
junit.textui.TestRunner.run (BankingTest);
}
TestSuite class
Test cases can be organized into test suites, managed by the
junit.framework.TestSuite class. JUnit provides tools that allow every test in a
suite to be run in turn and to report on the results.
TestSuite can extract the tests to be run automatically. To do so, you pass the
class of your TestCase class to the TestSuite constructor.
TestSuite suite = new TestSuite(BankingTest.class);
This constructor creates a suite containing all methods starting with test and that
take no arguments.
Alternatively, you can add new test cases using the addTest method of
TestSuite:
TestSuite suite = new TestSuite();
suite.addTest(new BankingTest("testBankingConnection"));
suite.addTest(new BankingTest("testBanking"));
In our example, we use a Java project called ItsoProGuideJUnit. Create the Java
project (New -> Project -> Java -> Java Project). Enter its name and click Next.
Select the ItsoProGuideJUnit project and Import (context). Select ZIP file, click
Next, locate the \sg246957\sampcode\dev-java\BankingModel.jar file, and click
Finish.
Figure 17-3 shows the next page of the wizard, where you enter details about the
new test case:
Set the source folder to ItsoProGuideJUnit (where we want to store the test
case).
Enter itso.junit as package name.
Select public static void main(String[] args) and Add TestRunner statement for
and select text ui in the combo box. The creates a main method in the test
case, and adds a line of code that executes the TestRunner to run the test
methods and output the results.
Select setUp() to create a stub for this method in the generated file.
We leave the default values for all other fields on this page. The other options on
this page are:
Test case—The name of the new test case class is generated as the name of
the source class we want to test, with Test as a suffix.
Test class—The Java class that this new test case is testing.
Superclass—By default the JUnit TestCase class, but can be changed if you
extend the JUnit package yourself.
Method stubs—Which method stubs do you want to generate:
– main is the method that is executed to start the JUnit test case as a Java
application. This is not required, as within Application Developer, we can
run Java classes as JUnit test cases.
– The check box, Add TestRunner statement for:, has three options: text ui,
swing ui, awt ui. These options add a single line of code to the main
method to run the test case and output the results in three different user
interfaces. Text is plain text, while swing and awt are graphical outputs.
– setUp is a method that is executed before the tests.
– tearDown is a method that is executed after the tests.
Click Next to proceed to the next page of the wizard. Figure 17-4 shows the
available methods for which stubs should be created. We select the deposit
method.
Think of the stub methods as just a suggestion for a few scenarios to test in your
test case. You can add as many methods to the generated file as you would like,
and the naming conventions are up to you. This page of the wizard gets you
started.
In our new BankingTestTest test case, we must add the following private object
that will be instantiated before starting the test:
//Banking facade
private itso.bank.facade.BankingTest banking;
In the setUp method, add the following code to create an instance of the Banking
facade:
public void setUp(){
super.setUp();
banking = new itso.bank.facade.BankingTest();
}
Test methods
Next we update the stub testDeposit method by adding the code shown in
Figure 17-5.
This method retrieves an account balance, then deposit funds into that account.
Then it retrieves the account balance again and verifies that the balance before
plus the deposit amount is equal to the balance after the deposit was made.
After entering the code, select Source -> Organize Imports from the context
menu to fix any unresolved errors. Make sure that you import
java.math.BigDecimal when prompted.
Note: We first tested the balance by retrieving the Account object before and
after the deposit. This logic fails because, with the in-memory model of the
ItsoProGuideJava project, the same Account object is retrieved. This does
work if new objects are created by the model.
/**
* Method to test making a deposit to an invalid account number
*/
public void testDepositInvalidAccount() {
try {
// test getting an invalid account
banking.deposit("AAAA", new BigDecimal(1));
fail("Got account even though used invalid account id");
} catch (AccountDoesNotExistException accex) {
assertTrue(true);
} catch (Exception ex) {
fail(ex.getMessage());
}
}
JUnit provides a number of methods that can be used to assert conditions and
fail a test if the condition is not met. These methods are inherited from the class
junit.framework.Assert (see Table 17-1).
Table 17-1 JUnit assert methods
Method name Description
assertEquals Assert that two objects or primitives are equal. Compares objects
using equals, and compares primitives using ==.
assertSame Assert that two objects refer to the same object. Compares using ==.
All of these methods include an optional String parameter that allows the writer of
a test to provide a brief explanation of why the test failed—this message is
reported along with the failure when the test is executed, for example:
assertEquals(String message, object expected, object actual);).
Creating a TestSuite
A TestSuite is used to run one or more test cases at once.
Application Developer contains a simple wizard to create a test suite. Select the
itso.junit package and New -> Other -> JUnit -> TestSuite. Alternatively select
the project folder and package after you start the wizard.
The test classes window shows all test cases in the specified package, selected
by default. In our case, BankingTestTest is shown and selected. The first page of
the wizard is shown in Figure 17-7.
By default, the test suite is called AllTests. If you had multiple test classes, you
could include them in one suite. In our case, we have only one test class. The
check boxes to create a method stub for the main method does just that, and we
select that here as well as the check box to add a TestRunner statement.
The generated AllTests Java source opens, and requires a small modification.
You must change the TestRunner statement to the following:
public static void main(String[] args) {
junit.textui.TestRunner.run( suite() );
}
This code uses the text-based test runner tool in the JUnit framework, which runs
the tests and reports the results.
In our case, using a TestSuite is not required. However, as you add more and
more test cases, a TestSuite is more practical.
Select the BankingTestTest class and Run -> Run As -> JUnit Test from the
menu bar. Application Developer opens a JUnit View with the results of the run
(Figure 17-8).
Tip: To run just one test case, select the test case class and Run -> Run As ->
JUnit Test. To run all the test cases, run the test suite class.
The JUnit view is more interesting when an error or failure occurs. Update
BankingTestTest so that the testDepositInvalidAccount method causes an
error by changing the account ID to a valid one:
banking.deposit("104-4001", new BigDecimal(1));
Figure 17-9 shows the JUnit view when the test case is run as a JUnit test again.
This time, an error occurs and its details are output in the Failures list.
Figure 17-10 shows the output from the Banking test case, containing the same
update noted above, run as a Java application. We can see that there was one
success and one failure. The failure occurred when running
testDepositInvalidAccount.
Figure 17-10 Output from running BankingTest as Java Application, with failure
Once we have corrected the error, the output in Figure 17-11 is shown.
Figure 17-11 Output from running the test case as Java Application, no failures
However, you cannot easily run the test cases when the Web application uses
the EJB back-end. Test cases are run as Java applications, and you cannot
access EJBs from a Java project.
Possible alternatives:
You can test the Banking class in the Web projects if you change the flag to
use the in-memory objects:
boolean ejb = true;
You create a J2EE client project as part of the enterprise application for the
test cases. J2EE clients can access EJBs when run in a client container.
You create test case classes as servlets in the Web project.
Component testing
The Component Test perspective provides a framework for defining and
executing test cases. The basic framework supports three sorts of test case,
based on their different scheduler: manual, Java, and HTTP. You can also create
report generators to work with the data returned by an executed test case.
In order to use component tests, you must have a host with the Agent Controller
installed and running. The Agent Controller is not installed by default when
Here we will define Java test cases, which implement the JUnit framework
described earlier in the chapter. We will use the project ItsoProGuideJUnit
explained in “Preparing for JUnit” on page 578.
You have now created the BankingTestCase test case. You now see
BankingTestCase listed in the Testcases folder of the Definition view.
Next, we create a task within the test case that translates into a method in a JUnit
test class. In the Outline view, select Main Block. Select New -> Task -> Java
from the context menu.
In the editor view for BankingTestCase, change the name of the task from T1 to
testGetAccount (Figure 17-14).
You can also add a description for this task in the Description field, if desired.
Save the changes. We have now outlined the tasks to be performed in this Java
test case. Now we prepare the test case, thus generating a JUnit test class.
In the Definition view, select the BankingTestCase and Prepare (context). The
prepare test case wizard opens (Figure 17-15).
Click Next, then click New Host and the new host dialog opens (Figure 17-16).
Note: The ItsoProGuideJUnit project has been modified extensively with new
library files. However, the reference to the ItsoProGuideJava project was
removed. Open the project properties and select the ItsoProGuideJava project
in the Java Build Path Projects page.
You have to add import statements for Banking and Account in your test class.
This can be done by right-clicking in the text editor and selecting Source ->
Organize Imports. Save the file.
Note: If you have the automatic build preference turned off, you must build
your project before executing it. To build the project, press CTRL-B.
Finally, return to the Component Test perspective, where we will run the
component test.
Note: For testing of any applications that use database access, make sure
that a user name and password to connect to the database is specified within
the application’s code. If not, during component testing, the user SYSTEM is
used by default. If this user name is not defined or does not have the proper
security properties, your tests may fail inexplicably.
The run test case wizard opens, as shown in Figure 17-18. Here you give a name
to this execution.
Click Next, then you select the host to run the tests on, as shown in Figure 17-19.
In our case, we will use the localhost. You could, however, execute tests on any
server that has the IBM Agent Controller installed. New hosts can be defined by
clicking New Host.
Click Next, and you are taken to the final page of the wizard, which allows you to
describe the execution. After you have done that, click Finish to begin executing
the test case.
When the execution is running, you will see next to the execution in the
execution view. After it has completed, the running man disappears.
Select the Open browser check box and make sure the Open editor check box is
not selected. If you select both, the new report will open twice.
Click Next to proceed to the next page of the wizard, where you select the output
location of the report (Figure 17-22). In a larger application, you could organize
reports into folders of a project. In our case, we will simply generate the report in
the root folder of the ItsoProGuideJUnit project.
Figure 17-23 shows the report in the Web browser. The top of the report shows
the execution statistics. The remainder of the report shows the details of each
step of the test execution in the info field, including:
Starting the test case
Connecting to the local host
Verifying that an agent is available to connect to
Connecting to the agent
Starting the JUnit test cases
Completing the JUnit test cases
Reporting the results
Completing the test.
You can create HTTP tasks directly in the Component Test perspective, or you
can import a record of HTTP interactions in XML format.
We will now create a simple HTTP test case and create our own HTTP task to
call a servlet.
Note: This section assumes that you have an existing WebSphere Application
Server started and running on port 9080. Note that this is the default port for
test servers within Application Developer.
In the Component Test perspective, select Testcases in the Definition view and
select New -> Testcase from the context menu. In the new test case window,
select ItsoProGuideJUnit as the location and enter HTTPTestCase as the name of
the new test case (Figure 17-24).
The new test case has now been created and is open in the editor, as shown in
Figure 17-26.
In outline view, right-click Main Block and select New -> Task -> HTTP from the
context menu. A new task has now been created for the test case.
Select Design in the left column, then in the right part of the editor, specify the
following options:
Request Method: GET
Host Name: localhost
Port: 9080
Absolute Path: /
You will see a small message below the Execute request button:
Response: 404 - Content Type:html/text - Bytes:142
The first response (404) is the typical file not found message, the second
message indicates success.
Change the path back to / and save the test case. We want to see a failure.
Select the HTTPTestCase and Prepare from the context menu in the Definition
view. This generates the Java code for the test case. This wizard is explained in
detail in “Preparing a Java test case” on page 591.
Running an HTTP test case is done in the same way as running a Java test case,
except that the generated Java test case code does not need to be updated. For
more details about running the test case, see “Running a Java test case” on
page 594. The difference here is in the name of the test case.
Finally, reporting results from an HTTP test case is the same as a Java test case.
For more details, see “Report test case results” on page 595. The actual report is
slightly different, as shown in Figure 17-29.
Rerun the test case as execution2 and generate the report again.
As you can see, there was a softFail due to a 404 error reported from the HTTP
server because no file existed at the root of the server. HTTP test cases read the
header of the HTTP response to determine whether tests pass or fail. In our
case, there was no file at the root of the localhost. If there had been, then the test
would have passed.
This concludes our introduction of HTTP test cases. This is a new and useful
feature of Application Developer that can be used to automate testing and
reporting of HTTP requests.
For detailed information about WebSphere Application Server, see the IBM
Redbook, IBM WebSphere Application Server Version 5.0 Handbook,
SG24-6195.
For detailed information about EJB development and deployment, see the IBM
Redbook, EJB 2.0 Development with WebSphere Studio Application Developer,
SG24-6819.
Although Application Developer 5.0 has excellent support for testing applications
in its built-in test environment, it is always good practice to export your
application and deploy and test it on the target environment as early as possible
in the development cycle. More than one project has had unpleasant surprises
when developing large applications by only using the built-in test environment for
testing, and then attempted to deploy it to the target environment—only to find
out, too late, that it failed there.
This enterprise application has an EJB module, several Web modules, and a
utility JAR (a Java project).
You can use your own ItsoProGuide project, or import the EAR file from the
sample code associated with this redbook (see Appendix C, “Additional material”
on page 809).
Before exporting the EAR file, we verify that the database mapping deployment
information for the EJBs in our project is correct:
Open the deployment descriptor editor for the ItsoProGuideEJB project by
expanding the EJB Modules in the J2EE Perspective, J2EE Hierarchy view
and double-clicking the ItsoProGuideEJB module. This brings up the window
shown in Figure 18-1.
Select the Overview tab and scroll to the bottom of the page as shown in
Figure 18-2.
We will not use any of the EJB security functions in our examples.
Before exporting the EAR file, we verify that the deployment information is
suitable for a production system.
Open the Web deployment descriptor editor by expanding the Web Modules
in the J2EE Hierarchy view and double-clicking the ItsoProGuideBasicWeb
module (Figure 18-3).
The difference in the application client module is that we use a data source to
connect to the database:
protected static Connection connect() {
Connection con = null;
try {
javax.naming.InitialContext ctx = new javax.naming.InitialContext();
javax.sql.DataSource ds =
(javax.sql.DataSource)ctx.lookup("java:comp/env/jdbc/mybank");
con = ds.getConnection();
} catch (javax.naming.NamingException e) {
System.err.println("Naming-Exception: " + e.getMessage());
} catch (java.sql.SQLException e) {
System.err.println("SQL-Exception: " + e.getMessage());
}
return con;
}
Here are some short instructions on how we built the application client module:
Create a new project of type J2EE -> Application Client Project. Enter a name
of ItsoProGuideJavaClient and use the existing ItsoProGuide enterprise
application.
Create the class itso.javadb.CustomerListingDS and use the source in:
\sg246957\sampcode\deploy-app\client\CustomerListingDS
Open the deployment descriptor and on the References page define a
resource environment reference named java:comp/env/jdbc/mybank,
pointing to our jdbc/ejbbank data source (as shown in Figure 18-5).
DB2JAVA
When you run the program, you can see the start of the client container and
the binding of the JDBC reference in the Console view. The database records
are displayed as the result of the program execution.
Note: You may want to make the changes to the applications as noted in
“Changing the applications to run on a remote server” on page 538 before
exporting.
After the deployment descriptors have been customized for our environment, the
enterprise application can be exported to an EAR file:
In the J2EE Perspective, J2EE Hierarchy view expand Enterprise Applications
and select the ItsoProGuide project. Then select Export EAR File from its
context menu. The EAR Export dialog shown in Figure 18-8 is displayed.
Enter the EAR filename to export the resources to. A possible location is the
installableApps directory of the WebSphere Application Server, but you can
export to anywhere in the file system.
Make sure that the three options are unchecked. Because the EAR file will be
used in a production system we do not want to include the source files or the
Application Developer meta-data.
Click Finish to export the EAR file.
Data source
Under Additional Properties select Data Sources.
– Click New (Figure 18-12).
– Enter EJBBANK as name and jdbc/ejbbank as JNDI name (to match what
we defined in the EJB deployment descriptor).
Figure 18-12 Defining the data source for the EJBBANK database
Go back to the data source (select EJBBANK at the top of the page):
– For component- and container-managed authentication alias, select the
{node}/DB2user from the pull-down and click OK (Figure 18-14).
Note: Due to Web browser caching, the alias may not appear in the pull-down
list. If this happens, refresh your Web browser by pressing F5 and then
navigate to this entry again.
If you select Security (left side) and JAAS Configuration you can find the new
alias by selecting J2C Authentication Data.
c:\ItsoProGuide.ear
On the panel, Preparing for the application installation, all the defaults should
be fine:
– You do not want to overwrite existing bindings, everything was configured
in Application Developer
– You can choose the virtual host (instead of default_host)
Click Next.
Unless otherwise noted, review the options and then click Next for each step.
Because we configured all the deployment information in Application Developer
there is almost no need to change the options.
– You may want to select Pre-compile JSP (although we set this in our Web
applications it is not picked up as a default).
– Do not select Deploy EJBs; deployment code was generated in
Application Developer.
2. Provide JNDI Names for Beans (Figure 18-17).
All the JDNI names for our entity and sessions beans have been set.
3. Provide default data source mapping for modules containing EJB 2.0 entity
beans (Figure 18-18).
We configured the jdbc/ejbbank data source previously.
4. Map data sources for all EJB 2.0 CMP beans (Figure 18-19).
8. Ensure that all unprotected EJB 2.0 methods have the correct level of
protection (Figure 18-23).
If you want to start the application, you must first save changes to the
master configuration.
This may work, dependent on the modifications you made to the configuration.
Sometimes it is necessary to stop and start the server:
Use the startServer.bat and stopServer.bat scripts in
c:\WebSphere\AppServer\bin
Use the icons in the program folder or in First Steps
http://localhost:9080/ItsoProGuideStrutsWeb
http://localhost:9080/ItsoProGuideDataBaseWeb/ListCreditsInputForm.html
enter type: C or D, and a partial last name: %i%
http://localhost:9080/ItsoProGuideDataBaseWeb/TestDBBeans.jsp
http://localhost:9080/ItsoProGuideStoredProcWeb/RunStoredProcedure.jsp
http://localhost:9080/ItsoProGuideStoredProcWeb/RunGetCustomerBean.jsp
http://localhost:9080/ItsoProGuideStoredProcWeb/RunTransfer.jsp
Note: the stored procedures must be installed on the server machine
http://localhost:9080/ItsoProGuideWebServ/RunBanking.jsp
http://localhost:9080/ItsoProGuideWebServClient/TestBankingWebService.jsp
If you have regenerated the Web server plugin, start the HTTP server and you
can test the applications using URLs without the 9080 port:
http://hostname/ItsoProGuideBasicWeb
launchClient.bat d:\WebSphere\AppServer\installableapps\ItsoProGuide.ear
-CCclasspath=d:\SQLLIB\java\db2java.zip
To run the application on another machine you must have the WebSphere client
installed. The command would be:
launchClient.bat d:\WebSphere\AppServer\installableapps\ItsoProGuide.ear
-CCclasspath=d:\SQLLIB\java\db2java.zip
-CCBootstrapHost=hostname
Note that you must provide the DB2 JDBC classes in the classpath.
We only cover a small subset of the tools; those which seem useful to an
application developer and tester. For a complete discussion of the tools, refer to
the WebSphere documentation.
Batch commands
Here is a list of some of the commands:
assembly—runs the Application Assembly Tool (AAT)
clientConfig— runs the Application Client Configuration Tool
backupConfig—creates a ZIP file of all the configuration information
restoreConfig—restores a configuration from a backup file
dumpNameSpace—lists all the JNDI names from the name server
ejbDeploy—generates deployed code for an EJB JAR file
firstSteps—launches the First Steps menu
GenPluginCfg—generates the HTTP plugin
launchClient—run an application client module
JspBatchCompiler—compiles the JSPs for an application server
startServer—starts a server
stopServer—stops a server
serverStatus—report if a server is running
setupCmdLine—sets the classpath for most of the other tools
wsadmin—starts the administration scripting tool
Wsadmin can be run with a single command, or you can interact with the tool:
Single command example:
wsadmin -c "$AdminApp list"
A single command is passed to wsadmin using the -c option. The $AdminApp
list command lists all the installed applications.
To start wsadmin in interactive mode, enter wsadmin:
D:\WebSphere\AppServer\bin>wsadmin
WASX7209I: Connected to process "server1" on node a23wph18 using SOAP
connector; The type of process is: UnManagedProcess
WASX7029I: For help, enter: "$Help help"
wsadmin>
Example commands
Once the interactive mode has started, you can enter commands, such as:
$AdminApp list
$AdminApp install c:/ItsoProGuide.ear
$AdminConfig save
Some commands work with objects that you have to retrieve first. For example, to
regenerate the HTTP server plugin:
set pluginGen [$AdminControl completeObjectName type=PluginCfgGenerator,*]
===> output:
WebSphere:platform=common,cell=a23wph18,version=5.0,name=PluginCfgGenera
tor,mbeanIdentifier=PluginCfgGenerator,type=PluginCfgGenerator,
node=a23wph18,process=server1
===> no output
The sample script in Figure 18-25 can be found in the Information Center. It lists
all the applications running on all the servers on all the nodes.
For example, if you create a Web service from an SQL statement (we did not do
this in this document, but it is possible), then the Web Services Object Runtime
Framework (WORF) is used at runtime. In this case you have to add the WORF
runtime classes to the classpath. You can find the worf.jar file in:
<wsadhome>\wstools\eclipse\plugins\com.ibm.etools.webservice_5.0.1\runtime
Summary
In this chapter we described the basic steps for setting the deployment
descriptors and exporting an application from Application Developer and then
installing it in WebSphere Application Server, including the configuration that is
required in the server.
Note that WebSphere Application Server has many performance and tuning
options that we do not cover in this redbook.
To control what operations Ant should perform during your build, you supply it an
XML-based script file. This file not only defines what operations to perform but
also in which order they should be performed and any dependencies between
them.
Ant comes with a large number of built-in tasks sufficient to perform many
common build operations. However, if the tasks included are not sufficient, you
also have the ability to extend Ant’s functionality by using Java to develop your
own specialized tasks. These tasks can then be plugged into Ant.
Not only can Ant be used to build your applications, but it can also be used for
many other operations such as retrieving source files from a version control
system, storing the result back in the version control system, transferring the
build output to other machines, deploying the applications, generating Javadoc,
and sending messages, for example, when a build is finished.
To find out more about Ant, visit the Ant Web site at:
http://ant.apache.org/
This chapter provides a basic outline of the features and capabilities of Ant. For
complete information you should consult the Ant documentation included in the
Ant distribution or available on the Internet at:
http://ant.apache.org/manual/index.html
We created a new Java project for this that we called ItsoProGuideAnt. In this
project we created a Java package called itso.ant.hello and a class called
HelloAnt. Since these steps are basic Application Developer tasks and the
application does nothing but a simple System.out.println("Hello Ant") we do
not show them here. The source code is available in:
\sg246957\sampcode\deploy-ant\simple
Each Ant build file may have a default target. This target is executed if Ant is
invoked on a build file and no target is supplied as a parameter. In our case the
default target is dist. The dependencies between the targets are illustrated in
Figure 19-1.
depends on
compile
init
Figure 19-1 Ant example: dependencies
<target name="init">
<!-- Create the time stamp -->
<tstamp/>
<!-- Create the build directory structure used by compile -->
<mkdir dir="${build}"/>
</target>
<!-- Put everything in ${build} into the output JAR file -->
<!-- Add a timestamp to the output filename as well -->
<jar jarfile="${distribute}/lib/${outFile}-${DSTAMP}.jar" basedir="${build}"/>
</target>
<target name="clean">
<!-- Delete the ${build} and ${distribute} directory trees -->
<delete dir="${build}"/>
<delete dir="${distribute}"/>
</target>
</project>
We will now walk you through the different sections of this file, explaining each of
them.
Project definition
The project tag in the build.xml file defines the project name and the default
target. The project name is an arbitrary name, it is not related to any project
name in your Application Developer workspace.
Global properties
Properties that will be referenced throughout the whole script file can be placed
at the beginning of the Ant script. Here we define the property build.compiler
that tells the javac command what compiler to use. We will tell it to use the
Eclipse compiler.
We also define the names for the source directory, the build directory, and the
distribute directory. The source directory is where the Java source files reside.
The build directory is where the class files end up, and the distribute directory is
where the resulting JAR file is placed:
We define the source property as ".", which means it is the same directory as
the base directory specified in the project definition above.
The build and distribute directories will be created as build and dist
directories.
Properties can be set as shown below, but Ant can also read properties from
standard Java properties files or use parameters passed as arguments on the
command line:
<!-- set global properties for this build -->
<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>
<property name="source" value="."/>
<property name="build" value="build"/>
<property name="distribute" value="dist"/>
<property name="outFile" value="helloant"/>
Build targets
The build file contains four build targets: init, compile, dist and clean.
Initialization target
The first target we describe is the init target. All other targets (except clean) in
the build file depend upon this target. In the init target we execute the tstamp
task to set up properties that include timestamp information. These properties
are then available throughout the whole build. We also create a build directory
defined by the build property.
Compilation target
The compile target compiles the Java source files in the source directory and
places the resulting class files in the build directory.
<target name="compile" depends="init">
<!-- Compile the java code from ${source} into ${build} -->
<javac srcdir="${source}" destdir="${build}"/>
</target>
With these parameters, if the compiled code in the build directory is up-to-date
(each class file has a timestamp later than the corresponding Java file in the
source directory), the source will not be recompiled.
Distribution target
The distribution target creates a JAR file that contains the compiled class files
from the build directory and places it in the lib directory under the dist directory.
Because the distribution target depends on the compile target, the compile target
must have executed successfully before the distribution target is run.
<target name="dist" depends="compile">
<!-- Create the distribution directory -->
<mkdir dir="${distribute}/lib"/>
<!-- Put everything in ${build} into the output JAR file -->
<!-- We add a time stamp to the filename as well -->
<jar jarfile="${distribute}/lib/${outFile}-${DSTAMP}.jar" basedir="${build}"/>
</target>
Cleanup target
The last of our standard targets is the cleanup target. This target removes the
build and distribute directories which means that a full recompile is always
performed if this target has been executed.
<target name="clean">
<!-- Delete the ${build} and ${distribute} directory trees -->
<delete dir="${build}"/>
<delete dir="${distribute}"/>
</target>
Note that our build.xml file does not call for this target to be executed. It has to
be specified when running Ant.
To run our build script, we select the build.xml file, open its context menu and
select Run Ant as shown in Figure 19-4.
Application Developer displays the Run Ant dialog (Figure 19-5), which allows
you to select the targets to run.
The default target specified in the build file is already selected as one target to
run. You can check, in sequence, which ones are to be executed, and the
execution sequence is shown next to each target.
Note that because dist depends on compile, even if you only select dist, the
compile target is executed as well.
In the Arguments field, you can supply additional parameters to Ant, but we leave
that empty for now. If Show execution log in console is selected, messages from
Ant are displayed in the Log Console. If this is not selected, you will not see any
output from Ant, so make sure it is checked for now. Then click Finish to run Ant.
When Ant is running, you see the output in the Log Console (Figure 19-6).
The Log Console view opens automatically when running Ant, but if you want to
open it manually, select Window -> Show view -> Log Console.
The Log Console shows that Ant has created the build directory, compiled the
source files, created the dist\lib directory, and generated a JAR file.
Select the ItsoProGuideAnt project and Refresh (context). Now you can see the
JAR files in the Package Explorer view. To see the class files you have to open
the Navigator view (Figure 19-7).
Rerunning Ant
If you launch Ant again with the same target selected, you will see the following
in the Log Console.
As you can see, Ant did not do anything at all, because the build and dist\lib
directories were already created and the class files in the build directory were
already up-to-date.
Classpath problem
The classpath specified in the Java build path for the project is, unfortunately, not
available to the Ant process. If you are building a project that references another
project, the classpath for the javac compiler must be set up in the following way:
<javac srcdir="${source}" destdir="${build}" includes="**/*.java">
<classpath>
<pathelement location="../MyOtherProject"/>
<pathelement location="../MyThirdProject"/>
</classpath>
</javac>
EAR, WAR, and EJB JAR files all contain a number of deployment descriptors
that control how the artifacts of the application are to be deployed onto an
The actual EAR being tested, and its WAR, EJB, and client application JARs, are
not actually created as a standalone file. Instead, a special EAR is used that
simply points to the build contents of the various J2EE projects. Because these
individual projects can be anywhere on the development machine, absolute path
references are used.
You can use the ItsoProGuide enterprise application that you have in your
workspace, or you can import our sample application as described in “Installing
the ItsoProGuide.ear file” on page 812.
<target name="init">
<!-- Create the time stamp -->
<tstamp />
<!-- Create the dist directory where the output files are placed -->
<mkdir dir="${dist}" />
</target>
<target name="info">
<!-- Displays the properties for this run -->
<echo message="debug=${debug}" />
<echo message="type=${type}" />
<echo message="source=${source}" />
<echo message="meta=${meta}" />
<echo message="noValidate=${noValidate}" />
<echo message="Output directory=${dist}" />
<echo message="project.ear=${project.ear}" />
<echo message="project.ejb=${project.ejb}" />
<echo message="project.war.1=${project.war.1}" />
<echo message="project.war.2=${project.war.2}" />
<echo message="project.util=${project.util}" />
<echo message="project.client=${project.client}" />
</target>
<target name="buildWar1">
<!-- Builds the WAR project -->
<projectBuild ProjectName="${project.war.1}" BuildType="${type}"
DebugCompilation="${debug}" />
</target>
<target name="buildWar2">
<!-- Builds the WAR project -->
<projectBuild ProjectName="${project.war.2}" BuildType="${type}"
DebugCompilation="${debug}" />
</target>
<target name="buildUtil">
<!-- Builds the utility project -->
<projectBuild ProjectName="${project.util}" BuildType="${type}"
DebugCompilation="${debug}" />
</target>
<target name="buildClient">
<!-- Builds the application client project -->
<projectBuild ProjectName="${project.client}" BuildType="${type}"
DebugCompilation="${debug}" />
</target>
<target name="buildEar">
<!-- Builds the EAR project -->
<projectBuild ProjectName="${project.ear}" BuildType="${type}"
DebugCompilation="${debug}" />
</target>
<target name="buildAll"
depends="buildEjb,buildWar1,buildWar2,buildClient,buildUtil,buildEar">
<!-- Builds all projects -->
<echo message="Built all projects" />
</target>
<target name="exportAll"
depends="exportEjb,exportWar1,exportWar2,exportClient,exportEar">
<!-- Exports all files -->
<echo message="Exported all files" />
</target>
<target name="clean">
<!-- Delete the output files -->
<delete file="${dist}/${project.ejb}.jar" failOnError="false" />
<delete file="${dist}/${project.war.1}.war" failOnError="false" />
</project>
This script provides you with a selection of useful J2EE operations you can
combine to produce the desired results. We will not go through all the different
Application Developer Ant tasks that we use because their names describe their
purpose.
Note: Documentation for the Application Developer Ant tasks can be found in:
<wsad>\wstools\eclipse\plugins\com.ibm.etools.j2ee.ant_5.0.1\doc\index.htm
There are also tasks for regenerating EJB Access Beans and some other
utility tasks.
In the global properties for this script we define a number of useful variables,
such as the project names and the target directory. We also define a number of
properties that we pass on to the Application Developer Ant tasks. These
properties allow us to control whether the build process should perform a full or
incremental build, if debug statements should be included in the generated class
files, and if Application Developer’s metadata information should be included
when exporting the project.
When launching this Ant script, we can also override these properties by
specifying other values in the arguments field, allowing us to perform different
kinds of builds with the same script.
We only included two of the Web projects for separate build and export. The
script could be expanded to include all the Web projects of the enterprise
application.
Select the build.xml file in the J2EE Navigator view and Run Ant (context).
Select the targets in the correct sequence and enter arguments to build the class
files with debugging information, include the source code, and include
Application Developer metadata in the generated EAR file:
-DDebug=true -Dsource=true -Dmeta=true
Figure 19-10 shows the target selection dialog with the argument. On the
right-hand side, the Log Console view shows the operations performed and their
results. At the very beginning, the properties used in the script are displayed.
To build a production-ready EAR file, you would have to execute the total target
with an argument of -Dtype=full so that all the classes are recompiled without
debugging information.
We have now shown you two examples of using Ant within Application Developer.
These are basic operations that you could perform using the Application
Developer GUI.
With Ant you can also automate more complex tasks, for example, to perform a
complete build of a project, export the resulting EAR file, deploy it to a
WebSphere Application Server, start it, run regression tests using JUnit, and
send you an e-mail with the results. This is outside the scope of this book.
This command file invokes Ant in headless mode and passes the parameters
that you specify. The file must be tailored with the workspace location.
To build our J2EE project, we copied the runAnt.bat file to a new file called
itsoRunAnt.bat and changed it as shown in Figure 19-11.
echo off
setlocal
REM The root directory of your WSAD installation
set WSAD=D:\WSAD5\eclipse
:run
@echo on
%WSAD%\jre\bin\java -cp %WSAD%\startup.jar org.eclipse.core.launcher.Main
-consolelog -application com.ibm.etools.j2ee.ant.RunAnt
-data %WORKSPACE% %*
:done
Note that you have to tailor the file with correct directory locations.
Note: When running Ant in headless mode, Application Developer must not
be started. If Application Developer is started on the machine where
runAnt.bat is invoked, it does not do anything.
To run the command file, start a Windows command prompt and change to the
directory where the itsoRunAnt.bat file is located. Then execute the following
command:
itsoRunAnt -buildfile c:\WSAD5sg246957\ItsoProGuide\META-INF\build.xml
clean exportWar1 -Dsource=true -Dmeta=true
The -buildfile parameter should specify the fully qualified path of the
build.xml script file. We can pass the targets to run as parameters to itsoRunAnt
and we can also pass Java environment variables by using the -D switch.
In this example we chose to run the clean and exportWar1 targets and we chose
to include the Java source and metadata files in the resulting EAR file. The
output from the script is shown in Example 19-2.
clean:
init:
exportWar1:
[warExport] Exporting: ItsoProGuideBasicWeb ...
[warExport] Exporting: ItsoProGuideBasicWeb ... Building:
/ItsoProGuideBasicWeb.
Invoking Java Builder on /ItsoProGuideBasicWeb....
[warExport] Exporting: ItsoProGuideBasicWeb ... Building:
/ItsoProGuideBasicWeb.
Reading saved built state for project ItsoProGuideBasicWeb....
[warExport] Exporting: ItsoProGuideBasicWeb ... Building:
/ItsoProGuideBasicWeb.
Preparing for build...
BUILD SUCCESSFUL
Summary
In this chapter we introduced you to the Ant build tool and explained how to
perform a build of both a simple Java application and a full J2EE application.
We also described how to run the Ant tool outside of Application Developer for
easier integration into your build process.
Using filters, you can focus on classes that you are interested in and omit tracing
for others.
The basic architecture of the profiling tools involves the JVM, (Java Virtual
Machine), where the application is running, an agent running inside the JVM
capturing profiling information, an agent controller that controls the agent and
retrieves profiling information, and the performance analyzer inside Application
Developer. The relationships between the components is shown Figure 20-1.
The agent runs inside the JVM and uses the Java Virtual Machine Profiler
Interface, (JVMPI), to interface with the JVM. If you are interested in more
information about JVMPI, the following Sun Web site has details:
http://java.sun.com/products/j2se/1.3/docs/guide/jvmpi/jvmpi.html
Application Developer
Performance Analyzer
User
App Control Interface
Agent
data control
Viewer
control
We also run some of the Web application processes to collect and analyze data.
Agent Controller
Before you can start using the profiling tools, be sure that you have the Agent
Controller installed, and that it is started as a service on the host where the
application to profile is running.
Once the Agent Controller is installed, ensure that it is started as a service. Click
Start -> Settings -> Control Panel, then select Administrative tools and Services.
You should see an entry for the IBM Agent Controller in the list of services
(Figure 20-2).
We assume here that you have created the ItsoServer test server, as described
in “Creating a server for testing” on page 224.
To begin, you must start your test server in profiling mode. To do so, switch to
Server perspective and select the ItsoServer in the Servers view, then select
Profile from the context menu.
Figure 20-3 shows the server in the Server view once it has started in profiling
mode.
There are two agents available for you to select: Java Profiling Agent and J2EE
Request Profiler.
The Java Profiling Agent collects data within the boundaries of a single Java
Virtual Machine's (JVM) execution space. The agent is attached to a JVM in
which the profiled application runs. Profiling focuses on the level of an agent or
process and provides the following types of sequence diagrams:
Object interactions
Class interactions
Thread interactions
The J2EE Request Profiler is an agent that resides within the application server
process for the purpose of collecting data from the interception points of the
application's requests. The J2EE Request Profiler uses the Agent Controller to
externalize this data so that it can be rendered by the various views provided by
the Profiling perspective of the Workbench.
The J2EE Request Profiler collects data from requests arriving in EJB containers
as well as Web containers. This data collection mechanism enables the creation
of sequence diagrams, which represent interactions among servlets, JSPs, and
Click All>> to select both the Java Profiling Agent and the J2EE Request Profiler.
Click Next to proceed to the next page of the wizard. On this page, you can
change the default name of the monitor. Normally you will leave the defaults on
this page (Figure 20-5).
Click Next to proceed to the Profiling Filters page (Figure 20-6). On this page,
there are several existing sets of filters for you to select from.
You can select one of the predefined filters, edit a filter, or add a new one.
Note: A filter limits the profiling data that is collected by package or class
name.
Click Next, and you are taken to a page where you an specify more profiling
options (Figure 20-7):
Start profiling after a number of invocations or time period (remove startup
invocations)
Collect boundary classes and instance-level information in the execution flow
Click Finish.
Start monitoring
The profiling perspective with the Profiling Monitor view opens with the two
agents. You are reminded with a pop-up window that you have to start
monitoring. We have connected so far, but we have not started monitoring.
The process along with both monitors are shown in the Profiling Monitor view
(Figure 20-8). Select them both and select Start Monitoring from the context
menu to begin gathering statistics.
Select Profile -> Launch -> Java Process and the Launch Java Process wizard
opens (Figure 20-9).
The remainder of the wizard is the same as the Attach to Java Process wizard.
We leave the default options, so click Finish.
Your are automatically taken to the Profiling perspective, the Java process is
launched and monitored, and the output is displayed in the Profiling Console
view, as shown in Figure 20-10.
Retrieve the data using Refresh Views. You can now analyze the profiling data
that was collected, as explained in “Performance analysis” on page 666.
If Application Developer is not installed on the remote host, the Agent Controller
has to be installed separately. IBM Agent Controller is available for many different
environments, including AIX®, HP, Windows, zOS, i-series, Linux, and Solaris.
Profiling a remote server uses the same process as a local one, as described in
“Profiling an application in the WebSphere Test Environment” on page 658.
Using the performance analysis data gathered by the agent, you can identify
potential problems by focusing on:
Time consuming classes and methods
Memory intensive classes and methods
Garbage collection statistics
Objects that are not garbage collected
Thread activity
To help you analyze the data returned by the profiler, Application Developer
provides a number of different views that focus on different aspects of the data.
They include:
Package statistics (statistical)
Class method statistics (statistical)
Method statistics (statistical)
Heap (graphical)
Execution flow (graphical)
Object interactions (graphical)
Class interactions (graphical)
The different views should be used in conjunction to gather the complete picture
of your application performance. This will provide you with the information
required to determine where you can most productively concentrate your efforts
to improve performance.
The views are linked together; that is, if you have selected something in one
view, the other views will show information about the same object. This makes it
easy to collect all information about a particular object.
As an example, if you select a class from the Package Statistics view, you can
switch to the Class Method Statistics view to get details about the execution of
the methods of that class.
To update the information in the profiling views to show the latest data captured
by the profiler, select Refresh Views from the view menu. This will refresh all the
views, not just the one you are currently in.
By default this view shows the following information about the packages:
Total base time for all classes in the package
Total cumulative time for all classes in the package
Number of calls made to each class
Number of live object instances of the class for which garbage collection has
not occurred
Active size of memory consumption by each live object instance of this type
Base time of a method is the time spent executing this method only. It does not
include time spent in other Java methods that this method calls.
Cumulative time of a method is the time the method spends on the execution
stack, including both time spent in the method itself and in other methods that it
calls.
You can sort on different columns by clicking in the column header. If you are
interested in determining the package with the longest base time, you would click
in the header of the Base Time column.
By default, this view shows the following information about your methods:
Class names
Method names (when the class name is expanded)
Package to which each class belongs
Total base time spent in each class, and broken down by method
Average base time spent in each class, and broken down by method
Total cumulative time spent in each class, and broken down by method
Number of calls made to each class, and broken down by method
Method statistics
The Method Statistics view is essentially the same as the Class Methods
Statistics view, except that it lists all methods together instead of separating them
by class. This allows us to sort by base and cumulative times to compare all
methods. The view is shown in Figure 20-14.
This view has the same columns as the Class Method Statistics view, except
here the package column is replaced by a class name column.
Heap
The Heap view is the most versatile profiling view and can be used to help you in
a number of performance analyzing tasks, such as:
Identifying time-consuming objects and methods
Identifying memory-intensive classes
Gauging garbage collection
Gauging program concurrency
Identifying memory leaks
Browsing method execution as a function of time.
The Heap view is color coded to make it easier to identify trouble spots in the
code (Figure 20-15).
This version of the Heap view shows base time per class. Red is used to indicate
classes that have a relatively high base time. To switch to other types of
information in this view, you select from the Color by drop-down combo box
(Figure 20-16).
The status line at the bottom of the Heap view displays information about the
currently selected object or method in the view.
The following sections describe how you can use the Heap view to help you with
the tasks listed above. Note that the other profiling views can also be used for
some of the tasks or to provide additional information.
Move the slider, adjusting the color coding until you see a variation in the color of
the rectangles that represent object instances, or diamonds that represent class
objects in Objects mode; or the rectangles that represent the methods in
Methods mode (Figure 20-17).
Slider
Figure 20-17 Heap view before and after adjusting the slider
The same process can be repeated for all entries in the Color by combo box.
Note: A class name might be red, but the rectangle representing it in the
histogram might be blue. The reason for this difference is that there are many
instances of the class, but each one alone does not occupy much memory
(blue). However, the total combination of all such instances takes up a lot of
memory (indicated by the red font color for the class and the length of the bar
in the histogram).
Select a method in the Heap view. The status line displays the name of the
method, the base time, the cumulative time, and the number of calls of that
particular method. This information gives you an indication of the time (in
seconds) that was spent executing that method. In our case, we select
PerformTransaction.doPost.
Method invocation
In the Heap view or in one of the statistics view, select the
PerformTransaction.doPost method and Show Method Invocation from the
context menu to display the Method Invocation view (Figure 20-19).
This view shows a representation of one method and the calls that are executed
from that method and the called methods. Clicking or scrolling over each method
(the vertical bar) shows its cumulative time.
Using the zoom icons (+ and -) you can zoom into areas of the graph.
From the context menu, click Show Caller to see the caller(s) of the selected
method in the view.
Each time you do this, one method higher up in the calling sequence is
displayed.
Select the method. The vertical length of the selected area indicates the base
time for the method. You can determine the execution time for this method by
checking the vertical time scale on the right side of the view. The status line gives
you the cumulative time for the method.
Note: Selecting Next and Previous in the context menu navigates through all
the invocations of the current method.
Select Show Method Invocation Table from the context menu, to see the related
tabular view of this (Figure 20-21).
Method execution
Open the Method Execution view by selecting Show Method Execution from the
context menu of a selected method.
Figure 20-22 shows the Method Execution view for the listAccounts.doPost
method. This is an accumulation of all instances. It shows the invoked methods.
In our case we can see the findByPrimaryKey method took a long time.
The Method Execution view displays a single pattern at a time. However, it may
contain hidden patterns or sub-patterns, which are points of variance in the
pattern. If it does display any hidden patterns or sub-patterns, you will see one or
more indicators of the form n/m. To see these hidden variants, click the indicator
repeatedly. There may be several such indicators throughout the view.
Note: Zoom In from the view menu to focus on specific parts of the graph and
Zoom Out to see the bigger picture.
When you are in the Execution Flow view, or in the Method Invocation or
Executions views, you can open the editor on a method by selecting Open
Source from the context menu. This is true for classes whose source files exist in
the Workbench.
An example of an Execution Flow view is shown in Figure 20-23. When you move
the cursor over the vertical bars, the status line at the bottom of the view shows
the method name and other related information.
Horizontally you can see the active threads, with the garbage collection thread,
(GC), always shown at the far left (not shown in Figure 20-23). At the far right of
the graph is the time scale showing elapsed time in seconds.
Note: By default, all objects show the same color. Selecting Graph Colors
from the context menu opens a dialog where you can change the preferences
so that each class has a unique color. Then bars of the same color would
represent methods belonging to the same class.
You can use the Zoom In action on the view menu to show parts of the graph in
higher resolution. As you do this, you will see the time scale at the right of the
graph get more granular. If you want to see more details about a method’s
execution, select it in this view and then select Show Method Execution from the
context menu.
To reduce the amount of information in the view, you can remove threads from it.
To do this, select Threads from the view’s context menu and deselect any
threads that you are not interested in at the moment. From the menu you can
also show or hide all repetitions of methods.
Sequence diagram
The Sequence Diagram view presents the execution flow of an application
according to the notation defined by UML. The view presents a sequence of
dependent events, where events are defined as method entries and exits as well
as outbound calls and return calls.
To show this view, select Window -> Show View -> Sequence Diagram.
Figure 20-24 shows the Sequence Diagram view.
The Zoom In and Zoom Out buttons enable you to view either more or less detail
of the view. The Home button returns the view to its original size.
Within the Sequence Diagram view in the Profiling perspective, any two
consecutive events have the same vertical distance between them. This does not
take into account the time elapsed between the occurrence of these two events.
The vertical bar to the left of the diagram, with rectangles of equal height and
different shades of red, corresponds to the representative distance between
events. Scrolling over the red rectangles will show the elapsed time between
events.
On activation, the button moves up along with the upper frame of the overview,
and clicking it at this time closes the overview.
The overview presents the same sequence diagram as the main view, but it is
complete, scaled-down, and simplified to the vertical object life span lines and
the call lines. This compact view of the diagram provides you with the means to
find interesting sections of the diagram, which may be obvious in this scaled
down view. On finding an interesting section of the diagram, you can move the
main view to that position by double-clicking the spot or dragging and dropping
the light red rectangle within the overview boundaries.
Instance statistics
The Class Instance Statistics view shows the number of objects of each class
(Figure 20-26).
When a class is expanded, you can see the actual objects. The icons are the
same as in the Package Statistics view.
Note: To interpret this view, you need to have a good understanding of how
objects are allocated and referenced in your application and how Java handles
object referencing.
Note: Old objects are those created prior to a certain point during the
profiling session. You can specify that point as you create a dump of the
object references using the Collect Object References icon in the
toolbar. Objects that are created after that point in time are referred to as
New-generation objects.
Summary
In this chapter, we covered the profiling tools of Application Developer and
included examples of the different statistics that are accumulated.
In most cases, though, developers do not work alone, but rather as part of a
team. Application Developer’s open architecture allows software configuration
management (SCM) systems to be plugged-in to support such kinds of
development effort.
Note: Only files have local histories. Projects and folders do not. The local
history is independent of the team development environment and the shared
team repository.
Comparing files
To compare the current edition of a file with a different one, choose Compare
With -> Local History from the file’s context menu. You can select different local
editions and compare them against the currently loaded edition (Figure 21-1).
Figure 21-1 Comparing the TransRecordBean class with its local history
There are three panels in the Compare with Local History window:
The top left panel lists all the available editions in the local history for the
selected file. These editions are grouped by the save date.
Replacing files
A similar dialog (Figure 21-2) lets you replace the loaded edition of a file for
another one. To do that, select Replace With -> Local History from the file’s
context menu.
Figure 21-2 Replacing the loaded edition with another one from the local history
This time around, the dialog presents you with just two panels. It would make
little sense to show the Java Structure panel because a replace would affect the
whole compilation unit.
Preferences
Finally, you can set how Application Developer manages the local history by
selecting Window -> Preferences and then selecting Workbench -> Local History
(Figure 21-4).
These tools must support a set of related and sometimes overlapping functional
areas, among which are:
Version control—This is the ability to store and retrieve snapshots of the
state of components at any given point in time. The mechanism usually
employed to store these versions is called forward-delta versioning, that
enables version branching with a minimum of storage wasted.
Problem tracking—Problem tracking usually works through two
mechanisms: defects and features. Defects track the life cycle of a problem
with any of the software components from identification all the way through to
final resolution. Features are additional requirements that must be
implemented in the system.
Change management—It is the process of identifying, tracking, and
controlling changes to software components.
Change management commonly provides an audit track that identifies which
files have gone through what changes, when these changes occurred, who
modified the files, and why. A defect or feature may result in the modification
of hundreds of files across more than one product, including documentation
and test cases.
Change management, through the mechanism of tracks, should produce and
keep records of each file modified in each separate product as related to the
particular defect or feature. When you are ready to include the changes for
the defect in the release and build the release, you should only need to
specify the track number and all the changes would be committed to the
repository and included in the release.
Build and deployment management—Gives you the ability to build and
deploy your software product in a repeatable manner.
The choice of a particular SCM usually affects the users’ workflow, because the
steps for retrieving files, comparing their content with local content, returning
updated files to the repository, and so forth, depend on the product that offers
these services. For this reason, this chapter only covers the concepts relative to
Application Developer’s support for SCM systems.
Repository
SCM systems store software components in a persistent storage called a
repository. Repositories coordinate multi-user access to the artifacts shared by
the development team. Projects in a repository can be of two forms: a branch
(modifiable) or a version (immutable).
Branches
A branch is a shared work area that lets team members release their work and
use code updates from others. Teams share and integrate their ongoing work in
branches. Thus, a branch represents the current state of a shared project.
A repository can contain multiple branches, such as one for new development
and another one for maintenance. Projects may be developed in multiple parallel
branches. You could, for example, be making fixes to Version 1.3 of a product in
order to evolve to Version 1.3.1, while at the same time working on the
development of Version 2.
Synchronizing
Resources can be changed in the team members’ individual workspaces without
affecting the branch. Each developer must explicitly commit changed resources
to the branch, while taking care not to overwrite resources changed by other
developers. This process is called synchronization.
Updating is the process of copying changes other developers have made into
your local workspace. This ensures that you will have the latest work from the
other team members incorporated in your work as well.
During update, conflicts due to parallel changes may arise. These conflicts must
be resolved in your local workspace. Application Developer offers you the
necessary tooling that makes this process easier. Do not forget to do the
appropriate testing before considering the update process successful.
Important: If you do not resolve conflicts between your local workspace and
the branch before committing your work, you run the risk of overwriting
resources that were updated by other team members. Application Developer
will let you do that, because that might be just what you want to do. Exercise
special care when proceeding this way.
After you have updated your workspace with the latest resources in the branch,
merging any conflicting changes and making the appropriate tests locally, you
can safely commit your changes to the branch.
When you commit your changes, they get copied from your local workspace to
the branch. As a result, these changes will be seen by other developers as
incoming changes when they later update their workspaces.
It is possible to version a resource without versioning the project that contains it.
You would do that if you wanted to create temporary baselines that alone were
not enough for a new project version. Most of the time, though, you will version
entire projects. During the synchronization of a whole project, the contained
resources are implicitly versioned.
You may create versions of resources that are either on your workspace or on the
branch. When you version a set of resources from your workspace, their current
state will be frozen and made a version. This is the preferred method of
versioning because when you do so, you know exactly what will be released into
the version.
When you version set of resources from the branch, the current state of the
branch frozen and versioned. You should not do that unless you are sure what is
currently committed to the branch.
Concurrency strategy
Application Developer uses an optimistic concurrency strategy in the sharing of
the repository resources. This means that any member of the team can make
changes to any resource he or she has access to. Because two team members
can commit to the branch changes to the same resource, conflicts can occur and
must be dealt with. This model is termed optimistic because it is assumed that
conflicts are rare.
Figure 21-5 shows how two developers would work on the same resource at the
same time:
Initial
Project Load
or
Development
Change #2
Developer 1
commit update commit
Branch
update update
commit
Developer 2
Change #1
Time
Figure 21-5 Concurrency workflow
Under some circumstances, this work flow may be simplified. You may be
confident that incoming changes do not affect you, and choose to commit without
updating. In general, however, team members should be encouraged to follow a
flow similar to the one presented above to ensure that the branch’s integrity is not
accidentally compromised.
The diagram in Figure 21-6 shows a comparison of the functionality of the two
SCM products for which adapters are shipped with Application Developer.
SCM adapters for other commercial SCM products are provided by the vendors
of these products. To find a list of SCM products and adapters provided by IBM
Business Partners, go to the SCM Adapters page on the Application Developer
site:
http://www.ibm.com/software/ad/studioappdev/partners/scm.html
Terminology comparison
When working with Application Developer, you will use the terminology provided
by the team development environment. When you use facilities of SCM systems
outside of Application Developer, you also have to understand their terminology.
Table 21-1 shows the mapping between terms used in Application Developer,
CVS, and ClearCase.
Summary
In this chapter we introduced version control, the local history, and the basic
terms of team programming.
Note: To complete the steps described in this chapter, you need two instances
of Application Developer, one for each of the two simulated team members. It
is much easier and more efficient to do so using two different machines, but
you can also open two Workbenches on just one machine with two
workspaces. Refer to the “Workspace basics” on page 23 for detailed
instructions.
It stores all the versions of a file in a single file using forward-delta versioning,
which stores only the differences among the versions.
It insulates the different developers from each other. Every developer works in
his own directory, and CVS merges the work in the repository when each
developer is done. Conflicts should be resolved in the process.
Please refer to it for information about how to install and configure your CVS
repository.
Follow these steps to install CVSNT. Note that you must have Windows
administrative rights to be able to follow these instructions:
Download and execute the installer, in our case cvsnt-2.0.0rc3.exe.
Select the typical install and leave all the options at their default values.
Reboot your machine, even if the installer does not tell you to do so. This step
will guarantee that the environment variables are properly set up.
On the Service Status page, stop the CVS services by clicking both Stop buttons.
Click Repositories to switch to the page to configure our new repository.
Select the Repository Prefix option because we want our repositories to be under
a common root directory. This is just an organizational feature, and is not really
mandatory for your own setups. You have to manually create a C:\Repositories
directory in your file system before configuring it.
Now click Add to create the new /RedBank repository and complete the dialog as
shown in Figure 22-2.
Note: CVS users must have the appropriate access rights to the repository
directory structure (full control in Windows).
After you are done, the Repositories page should look like Figure 22-3.
CVSNT uses either the domain or the local server directory for user
authentication under the pserver protocol. You have to choose the correct value
for your environment. This setting only applies if your machine is connected to a
Windows domain. This specification is in the Advanced page (Figure 22-4).
This list does not include all the new features, but points to the major differences
compared to previous versions of WebSphere Studio products.
Also expand the CVS section and verify the settings of the subsections. For
example, you can change these options:
Show the CVS Console when there is output
Name of the CVS server (in case you renamed the server during installation)
Keyword expansion
It is interesting to get the versioning information that is inside of CVS in the
Javadoc that is created for each file. One way to accomplish this is through
keyword expansion.
On the CVS preferences page, set Default keyword substitution to ASCII with
keyword expansion (-kkv).
Some of the available keywords (case sensitive) are:
– $RCSfile$—Adds the file name without the path
After committing a new class to CVS, you can see the comments in the source:
/**
* class comment goes here.
*
* <pre>
* Date $Date: 2003/04/20 02:14:05 $
* CVS History:
* $Log: Test.java,v $
* Revision 1.1 2032/04/20 02:14:05 UELI
* Change 2
*
* </pre>
* @author $Author: UELI $
* @version $Revision: 1.1 $
*/
In Version 5, this scenario will lead to many errors, such as missing classes, and
you have to redeploy the EJBs. The reason is that some of the components, such
as the deployed code, are not stored in the CVS repository in the default setup.
Ignored Resources
To store the deployed code in the CVS repository, you have to change the
preferences of the Workbench:
Select Window -> Preferences -> Team -> Ignored Resources (Figure 22-8).
Remove the check marks to store EJB deployed code in CVS.
To add a file type to the ignore list, click the Add button. In the window, enter a file
type (for example, *.class). To remove a file type from the ignore list, select the
file type in the ignore list and click Remove. You can temporarily disable ignoring
the file pattern by de-selecting it from the list; you do not have to remove the
specified file pattern from the list.
This text file consists of a list of files, directories, or patterns. In a similar way to
the global ignore facility, the wildcard * and ? may be present in any entry in the
.cvsignore file. Any file or subdirectory in the current directory that matches any
one of the patterns is ignored.
It is important to note that the semantics of this file differ from that of the global
ignore facility in that they apply only to files and directories in the same directory
as the .cvsignore file itself. A project may contain one .cvsignore file in each
directory. For more information, visit http://www.cvshome.org.
Resources that have not been added to CVS control can be ignored by selecting
Team > Add to .cvsignore from the context menu of the resource in the Navigator
view. This menu option is also available in the Synchronize view.
Before we begin working with CVS in Application Developer, select Window ->
Preferences, then select Workbench -> Label Decorations in the Preferences
window.
Click OK to save these preferences. The results of this are evident in this chapter
in all figures that show the Navigator view.
CVS console
In the CVS Console view, you can see all the interactions between Application
Developer and CVS. Select Window -> Show View -> Other -> CVS -> CVS
Console to open the view.
Two developers, stade1 and stade2, work together to create three entity beans:
Customer, TransRecord and Account. These are the same entity beans created in
Chapter 12, “Developing EJB applications” on page 373, so you can refer to that
chapter for additional details.
4 Creates the Account entity bean. Creates the TransRecord entity bean,
adds it to the version control and
synchronizes the project with the
repository.
In the sections that follow, we will perform each of the steps and explain the team
actions in detail.
Select New -> Repository Location from the context menu to open the Add CVS
Repository dialog (Figure 22-10).
Type localhost (or the server name or IP address of your CVS server) in the
Host field. In the Repository path field, type /RedBank. Recall that /RedBank was
the path specified when you created the repository, including the leading slash.
Important: With pserver, passwords are stored on the client side in a trivial
encoding and transmitted in the same encoding. The encoding is done only to
prevent inadvertent password compromises, and will not prevent an attacker
from obtaining the password. The other supported protocol, ssh, does not
have this problem, but has to be manually set up.
Click Finish, and the CVS Repositories view now contains the new repository
location (Figure 22-11).
You can use the CVS Repositories view to checkout repository resources as
projects on the Workbench. You can also configure branches and versions, view
resource histories, and compare resource versions and revisions.
We must first create a project and share it before making full use of the
repository.
Create a project
Switch to the J2EE perspective and create a new EJB project called
ItsoProGuideCVS by selecting File -> New -> EJB Project.
In the wizard’s first page, select Create 2.0 EJB Project and click Next to proceed
to the second page (Figure 22-12).
Click Finish to create the project. The new project now appears in the J2EE
Navigator view. Share the project by selecting Team -> Share Project from its
context menu. The Share Project wizard opens (Figure 22-13).
Select CVS as the repository type. Sharing a project using Rational ClearCase is
explained in “Adding a project to ClearCase source control” on page 762.
Click Next and select the existing repository location that you defined earlier. You
could also create a new repository location from here, if it was not already
defined (Figure 22-14).
Click Next to proceed to the next page of the wizard. Here you could specify a
different name for the CVS module than the project name, but we do not want to
do that. We leave the default, as shown in Figure 22-15, and click Finish to
complete the wizard.
Figure 22-16 Synchronizing project with repository before adding to version control
The question marks indicate that the resources do not exist in the repository;
only the project is in the repository for now.
Select the project folder (ItsoProGuideCVS) and select Add to Version Control
from the context menu. The Synchronize view is updated (Figure 22-17).
Figure 22-17 Synchronizing project with repository after adding to version control
Now select Commit from the ItsoProGuideCVS project’s context menu to commit
the changes to the repository.
Click OK to commit the changes to the repository. The project is now shared.
First of all, the second developer must add the CVS repository location to the
workspace using the CVS Repositories view in the CVS perspective, as
described in “Adding a CVS repository” on page 714.
The difference is now that the HEAD branch in the repository, if expanded,
contains the ItsoProGuideCVS module, as shown in Figure 22-19.
Select the ItsoProGuideCVS module and Check Out As Project (context). The
current project in the HEAD branch is added to the workspace.
When you are done, the generated files are shown in the J2EE Navigator view
(Figure 22-20).
Figure 22-20 J2EE Navigator view after creating the Customer entity bean
Tip: The “greater than” sign in front of a resource name means that the
particular resource is not synchronized with the repository. You can always
use this visual cue to determine when a project requires synchronization.
This view allows you to update resources in the Workbench with newer content
from the repository, commit resources from the Workbench to the repository, and
resolve conflicts that may occur in the process. The question mark icons indicate
that the files do not exist in the repository.
Click OK to add the comment and commit the files to the repository.
In the J2EE Navigator view, select the ItsoProGuideCVS project and Team ->
Synchronize with Repository (context). The Synchronize view opens
(Figure 22-24).
new
modified
new
Select the ItsoProGuideCVS project in the Synchronize view and select Update
from Repository (context). Figure 22-25 shows the updated J2EE Navigator view.
Figure 22-25 J2EE Navigator on the first developer’s machine after synchronization
Now it is time to do some parallel development, just like you would do in a real life
scenario. The first developer create the Account bean and the second developer
creates the TransRecord bean. The synchronization of workspaces will happen
only after both are done, so that conflicts show up and can be resolved.
There are still no conflicts, because the first developer has not yet synchronized
the changes. Add the new files to version control and commit the changes to the
repository. When asked, enter the commit comment:
Added TransRecord bean
Open the J2EE Navigator view and select the ItsoProGuideCVS project. Select
Team -> Synchronize with Repository from its context menu to open the
Synchronize view.
The Synchronize view lets you inspect the changes to both the workspace and
the repository. By clicking the mode buttons on the view’s toolbar, you can limit
what it displays. The available modes are:
Incoming mode—Shows changes to the repository that have to be copied to
the workspace, as well as conflicts.
Outgoing mode—Shows local changes to the workspace that have to be
copied to the repository, as well as conflicts.
Incoming / outgoing mode—Shows both workspace and repository
changes, as well as conflicts.
Conflicts only—Shows only the conflicts
Outgoing
Incoming
Conflicts
Note that we have three steps to take to synchronize the first developer’s
workspace with the repository:
Add the Account bean related files to the repository (outgoing).
Retrieve the TransRecord bean related files from the repository (incoming)
Resolve conflicts with the deployment descriptor (ejb-jar.xml) and the
WebSphere extensions descriptor (ibm-ejb-jar-bnd.xmi).
Select the itso folder and select Commit from its context menu. When asked,
enter the Commit comment:
Added Account bean
Note that the files related to the Account bean have disappeared from the
Synchronize view, because they are now synchronized with the repository.
Select the itso folder again, but this time select Update from Repository from its
context menu. The whole folder is removed from the Synchronize view.
We now have to handle the conflicts. Double-click the ejb-jar.xml file (the EJB
deployment descriptor) to open the Text Compare pane, which shows you the
differences between the file in the workspace and in the repository
(Figure 22-27).
Figure 22-27 Resolving conflicts with the EJB deployment descriptor (step 1)
In the right-hand pane, select the TransRecord bean declaration, that spans from
the <entity id="TransRecord"> tag to the </entity> tag, and select Copy from
its context menu.
Figure 22-28 Resolving conflicts with the EJB deployment descriptor (step 2)
Now click Save on the left-hand pane’s context menu to save the changes.
Application Developer informs you that the changes have been saved and that
you should select Mark as Merged to make this file an outgoing change
(Figure 22-29).
Click OK to close the dialog. The Synchronize view shows you that the EJB
deployment descriptor have been saved and should be marked as merged by
placing an asterisk right next to the file name (Figure 22-30).
Select the ejb-jar.xml file and select Mark as Merged from its context menu.
The Synchronize view is updated to reflect an outgoing change (Figure 22-31).
Similarly to the deployment descriptor, the file in the workspace declares JNDI
bindings for the Customer and Account beans. The file in the repository declares
JNDI bindings for the Customer and TransRecord beans. These three bindings
have to be combined in the workspace.
Select the binding declaration for the TransRecord bean on the right-hand pane,
copy it and paste it on the left pane after the binding declaration for the Account
bean (Figure 22-33).
Figure 22-33 Resolving conflicts with the WebSphere extensions descriptor (step 2)
Finally, select the META-INF folder and select Commit from its context menu.
Enter the commit comment: Added Account bean.
The Synchronize view should go empty because there are no more differences
between the workspace and the repository, and the J2EE Navigator view should
be updated as shown in Figure 22-34.
Figure 22-34 J2EE navigator view showing all the entity beans synchronized
Select the ItsoProGuideCVS project in the J2EE Navigator view and select Team
-> Tag as Version from its context menu. The Tag Resources dialog opens
(Figure 22-35).
Type EntityBeansCreated as the version tag and click OK. If you now switch to
the CVS Repository Exploring perspective, you can see the version in the CVS
Repositories view (Figure 22-36).
project version
If you expand the ItsoProGuideCVS project you can also see the versions of all
the files.
Select the ejb-jar.xml file in the J2EE Navigator view and Team -> Show in
Resource History (context). The CVS Resource History view opens (if not
already open) and shows the change history of the file (Figure 22-37).
In our case, the developer has version 1.3 of the resource, as indicated by the *
in the Revision column.
Note: Figure 22-37 displays the resource history for developer 2, who has not
synchronized with the repository to pick up the merge done by developer 1.
The same resource history for developer 1 would mark revision 1.4 as current.
To compare differences between revision 1.3 and 1.4, select both lines and
Compare (context). The compare view is displayed (Figure 22-38).
We can see the differences between the two revisions: the Account entity was
added to the XML file.
Branches in CVS
In CVS, teams share and integrate their ongoing work in branches. Think of a
branch as a shared work area that can be updated at any time by team
members. In this way, individuals can work on a team project, share their work
with others on the team, and access the work of others during all stages of the
project. The branch effectively represents the current shared state of the project.
Every CVS repository has at least one branch, referred to as HEAD. Under certain
conditions, more than one branch may exist in a repository. For example, one
branch may be for ongoing work, and another branch may be for maintenance
work.
Ideally, you should update your local workspace with any changes others have
made in a branch before committing your work. This ensures that you have the
very latest work from the other team members. After you have updated from the
branch, merged any conflicting changes in your local Workbench, and tested
your changes locally, you can more easily commit your Workbench's changes to
the branch.
When you commit changes to the branch, your changes are copied from your
local Workbench to the branch. As a result, these changes are then seen as
incoming changes when other developers update from the branch later.
To determine what branch a project is a part of, select the project, then select
Properties from the context menu. Select CVS in the properties window. The
Tag field shows the current branch or version.
When you create a new branch, the names of all existing projects in the
repository show up as children of the branch node in the repository browser
tree.
Discarding a branch from the CVS Repositories view removes the definition
from the Workbench only. The underlying CVS branch is left untouched.
In the following sections, we create a new branch, make changes to that branch,
then merge the changes back with the HEAD branch.
Branching
Creating a branch and releasing resources to that branch is useful in cases
where you are not yet ready to put your changes in the main development flow. It
is also useful for creating incremental patches to existing versions.
To create a branch, select ItsoProGuideCVS and Team -> Branch (context). Enter
Maintenance as the branch name. We require a new version as the starting point
for the branch. A version name is generated for us in the text area, and we leave
the default name (Figure 22-39).
If you would like to start working in the branch immediately, make sure the check
box is selected. Click OK to create the new branch.
Note: The version name is important; you will need it when you want to merge
the branches later. It identifies the point at which the branch was created.
In CVS Repositories view, expand Branches to see the new Maintenance branch
that you just created. Expanding Versions reveals the newly created
ItsoProGuideCVS Root_Maintenance version (Figure 22-40).
The project has now been versioned, and is split from the HEAD branch. We make
a few changes to the project, so that when we merge back with the HEAD branch,
there are changes.
We must now synchronize these changes with the Maintenance branch in the
repository. Select ItsoProGuideCVS then select Team -> Synchronize with
Repository. Commit your changes, as explained in “Synchronizing with repository
(step 3 - stade1)” on page 722. We now have a new branch with contents that
differ from the original branch.
Merging
After creating and working in a CVS branch for some time, you may want to
merge your changes from the branch into another branch, or into HEAD. This is
typical if a development team keeps their work separate for a long period of time,
then merges after their code has stabilized.
To merge the branch, ensure that the destination branch is loaded into your
workspace. Because we want to merge our changes into HEAD, we must make
sure the project is shared with HEAD in the workspace. Select the project and
Replace With -> Branch or Version (context). Then select HEAD (Figure 22-42).
Click OK to replace the project. We can now merge the HEAD branch with the
Maintenance branch. Select ItsoProGuideCVS and Team -> Merge (context). The
Merge wizard opens (Figure 22-43).
Select Root_Maintenance as the start point of the merge. This is the version from
which the branch was created. Click Next.
Click Finish, and the changes from the Maintenance branch are compared with
the HEAD branch.
The Merge editor opens, showing all differences between your workspace and
the Maintenance branch (Figure 22-45).
In a real-life scenario, you would likely run into conflicts at this point. In our case,
we keep it simple. More information on dealing with conflicts is explained in
“Resolving conflicts (step 5 - stade1)” on page 724.
After all desired changes are in the workspace, select Team -> Synchronize with
Repository (context). This is where you commit all the changes to the repository,
as explained in “Synchronizing with the repository” on page 720.
Note: If there are no repository locations listed in the Repositories view, you
have to add a location as explained in “Adding a CVS repository” on page 714.
From the context menu, select Define Branch Tag. The Enter Branch Tag dialog
opens, where you enter the name of the branch you want to use (Figure 22-46).
Note: Defining a branch tag does not add the tag to the repository. If the tag
already exists in the repository, defining the tag in the CVS Repositories view
allows the contents of the branch to be browsed. If the tag does not exist, then
the contents of the branch will be empty.
In the Repositories view, expand Branches and observe that it now contains the
new Development branch. You can now check files out from this branch, if they
exist.
In this situation, the developer can create a patch and either e-mail it to a
developer who does have write access or attach it to an error in the error
reporting system used by project management, depending on the process
defined by the project. A developer that does have write access can then apply
the patch to the project and commit the changes.
Creating a patch
To create a patch from a CVS project, select the resources that contains the
modifications to be included in the patch. Although this can be any folder, it is
easiest to select the project itself because the patch must be applied to the same
resource it is generated from.
Follow the steps explained in “Create session bean” on page 736 to create a
session bean called Test. We then create a patch that includes this new bean.
The patch should also be applied to the same file revision that it is based on.
Therefore steps should be taken to ensure that the patch is applied to the same
resource revision; the easiest way to enforce this is to create the patch on top of
a version.
From the context menu, select Team -> Create Patch. The Create Patch wizard
opens (Figure 22-47).
For small patches it may be reasonable to transfer the patch using the clipboard
but in most cases the local file system in the best option to use. Click Next to
configure how the patch is generated (Figure 22-48).
Click Finish.
Transfer the patch as appropriate for the project being patched. Typically, you
would e-mail the patch or send the file to someone with write access to the
repository.
Applying a patch
Before applying the patch, restore your workspace to be the same as the current
branch. This removes the Test session bean from your workspace, so that you
can add it with the patch. Select the ItsoProGuideCVS project and Replace With
-> Latest From Repository (context).
To apply a patch, you must first select the resource that the patch was generated
on. This resource should contain the same file revisions on which the patch was
generated. Select Compare with -> Patch (context). The Resource Patcher
wizard opens (Figure 22-49).
In our case, the patch is found in the clipboard. Click Next to see the effect of
applying the patch (Figure 22-50).
The top pane of this page shows whether the patch could be successfully applied
to files in your workspace. If you select an item in the tree, the bottom pane
shows the a comparison of the original and with the patch applied.
Note: To apply the full patch successfully you have to eliminate the problems
(red exclamation marks) and get checked items everywhere by tweaking the
options on this wizard page (see “Options for applying a patch” on page 744).
If all is well, click Finish to apply the patch. The workspace now contains outgoing
changes for each file modified by the patch, as indicated with > signs in the J2EE
Navigator view (Figure 22-51).
As you can see, Test.java, TestBean.java, and TestHome.java files have been
added, and ejb-jar.xml and ibm-ejb-jar-bnd.xmi files have been updated by
the patch, and are ready to be committed to the CVS repository.
Disconnecting a project
You can disconnect a project from the repository. Select the ItsoBank5Utility
project and Team -> Disconnect. You are prompted to confirm and also if you
want to delete CVS control information (Figure 22-52).
CVS adds special directories named CVS to the project and its folders. These
directories can be deleted or kept on disconnect.
Reconnect
You can reconnect a project to the repository ( Team -> Share Project).
Reconnect is easier if the CVS folders are still in the project. If they were deleted,
you are prompted to synchronize your code with the existing repository code.
CVS provides a simple but efficient team development environment. You should
consider CVS even in a single workstation environment so that you get the
benefits of versioning your own code.
Snapshot views support a disconnected use model for working away from the
office. All changes since the last snapshot are automatically updated once you
are connected again.
ClearCase LT is a light version for support of small teams that do not need the full
functionality of the complete ClearCase product (distributed servers, database
replication, advanced build management, transparent file access). For the
full-sized ClearCase, Rational also provides an add-on MultiSite feature.
Installing ClearCase LT
Application Developer 5.0 includes both the Rational ClearCase LT Server and
Rational ClearCase LT Client products. From the Application Developer product
installation dialogs you can start the installation of ClearCase LT. You can also
start the ClearCase LT installation from the Rational_ClearCase_LT directory on
the Application Developer 5.0 CD.
Notes:
When installing the ClearCase LT Server, you can be logged on either
locally on your Windows machine or logged on to a Windows domain. If
installing while logged on locally, you will only be able to connect to the
server from your local machine. Other people in your development team
will not be able to connect to your machine and use your ClearCase LT
Server. The user account used when installing must be a member of the
local Administrators group.
To use ClearCase LT in a team environment and let other team members
use your ClearCase LT Server, you must be logged on to a Windows
domain with a user account having Domain Administrator privileges while
installing ClearCase LT Server. The domain must also have a group for the
ClearCase users and all members of your development team must be
members of this group. This group should also be the Primary Group for
these users. You can use the Domain Users group for this.
Windows 2000
logon Domain Controller logon
Developer 1 Developer 2
When you have installed the ClearCase LT server, review the Rational
ClearCase: Upgrades, Patches and Service Releases page on the Rational Web
site and make sure that the latest fixes have been applied. The Web site can be
found at:
http://www.rational.com/support/downloadcenter/upgrades/index.jsp
ClearCase preferences
There are a number of ClearCase preferences that you can modify by selecting
Window -> Preferences -> Team -> Rational ClearCase (Figure 23-3).
We recommend that you check out files from Rational ClearCase before you edit
them. However, if you edit a file that is under ClearCase control but is not
checked out, Application Developer can automatically check it out if you select
Automatically checkout for the setting: When checked-in files are saved by an
internal editor.
You can specify if you want to automatically connect to ClearCase when you
start Application Developer. Select Automatically connect to ClearCase on
startup to enable this option.
If you click Advanced Options and then select the Operations tab, you can select
if you want ClearCase to generate backup copies of files you perform an undo
check out operation on. The backup copies will have a .keep extension.
Note: You must be connected to ClearCase for the Advanced Options button
to be active.
Developer 2:
Joins the ClearCase project by creating views
Imports the project into Application Developer
Adds a servlet, ServletB
Checks in the servlet
Verifies that no other developers has modified the project by performing a
Rebase preview operation
Delivers the work to the integration stream
Makes a baseline
Developer 1:
Updates his view to get the latest changes
The setup of this scenario and its flow is shown in Figure 23-4. ClearCase
terminology is used for the tasks.
dev2_View
dev1_View ITSO_Project
Basically, the developer retrieves the latest version of the code from the VOB to
the integration view by using the ClearCase Update View function. Once this is
done the developer can use the Rebase Stream function to update the
development view and start working with the code.
When finished with the changes, the developer delivers the development stream
back to the integration stream. A project integrator (or any of the developers) can
then make a new baseline freezing the latest code changes.
On the confirmation page, click OK. ClearCase now creates a new VOB. Click
Close on the summary dialog.
In the Step 2 dialog (Figure 23-7) make sure that No is selected. Click Next.
In the Step 4 dialog (Figure 23-9) select ITSO_VOB under Make the following
components modifiable. Leave the other values as their defaults. Click Next.
In the View Creation Status dialog that is displayed after the views are
created, click OK.
In the Add Elements to Source Control (Figure 23-16) leave all items selected
and deselect Keep checked out. Click OK.
In the Select Activity dialog (Figure 23-17) select New and enter Developer 1
adds project to source control. Click OK to return and then click OK to
continue. The EAR project is now added to ClearCase source control.
Select the ITSOProGuideCCWeb project and add this to source control using the
same method (do not create a new activity, use the activity created when
adding the EAR project to source control).
Both projects are now under ClearCase source control and their contents has
been moved from the Application Developer workspace (C:\WSAD5sg246957 in
our example) to C:\ITSO\dev1_View\ITSO_VOB.
In Figure 23-18 you can see that the icons for the resources now have blue
background. This means that the resources are under ClearCase source
control.
On the Select Activity, select New and enter Developer 1 adds ServletA as
the name for the activity. Click OK twice. The servlet is generated.
On the Add Element(s) to Source Control dialog, make sure the packages
and servlet are selected as shown in Figure 23-20. Deselect Keep checked
out and click OK.
On the Select Activity dialog, select Developer 1 adds ServletA and click OK.
The servlet is added to the project and to ClearCase source control.
Click Yes on the File Changed dialog.
As we only want to show how to work with ClearCase, we do not need to add
any real code to the servlet so simply enter your name in the author Javadoc
comment. As soon as you start typing in the editor, the servlet needs to be
checked out (it is checked in because we deselected the Keep checked out
option). The dialog shown in Figure 23-21 is displayed asking you to check
out the servlet. Click OK.
Before we can deliver the project to the stream, the ibm-web-bnd.xml and
ibm-web.ext.xmi files must be checked in as well. As their contents have not
changed, ClearCase default settings does not allow them to be checked in so
we need to undo their check out. Select both of them and select Team ->
Undo Check Out from the context menu. On the Undo Check Out for
element(s) dialog, make sure both files are selected and then click OK.
Before delivering to the stream, it is good practice to make sure that nothing is
checked out. Select ClearCase -> Show Project Checkouts. On the Find
Criteria dialog (Figure 23-23) click Browse and select the
C:\ITSO\dev1_View\ITSO_VOB directory. Keep the other defaults as shown and
click OK.
No checked out files should be found. Click OK to dismiss the dialog and then
close the Find Checkouts window.
Optionally you can click Details to see a list of the files delivered
(Figure 23-28), then click Close.
Click OK on the confirmation dialog (1 new baseline was created) and then
close the Make Baseline dialog.
You can now close the ClearCase Project Explorer. Developer 1 has now
finished his current task and developer 2 will now join the project and add a
servlet.
Click OK to dismiss the Hijacked Files Warning dialog. The contents of the
integration view is now copied to the developer 2’ development view.
In the Rebasing in View dialog, click Complete to perform the rebase action.
After this click Close.
In Application Developer, select File -> Import -> Existing Project into
Workspace and click Next (Figure 23-37).
Click Browse and select the EAR project and click Finish.
C:\ITSO\dev2_View\ITSO_VOB\ITSOProGuideCCEAR
Note: By now developer 1 and developer 2 are setup with a new shared
project. Both can now check out files, work with these files, check them in, and
deliver their work to the stream.
Developer 2 is now ready to deliver the changes to the stream and share the
code with the other developers. Before doing this, it is best practice to make sure
that no other developer has made changes.
Select ClearCase -> Rebase Stream. In the Rebase Stream dialog, select
developer 2’s development stream as shown and click OK (Figure 23-38).
In the Rebase Stream Preview dialog (Figure 23-39) make sure the
dev2_View view is selected, otherwise click Change -> Browse and select it.
Click OK.
The Rebase Stream dialog is displayed and notifies you that the stream is
currently up-to-date. Click OK to dismiss the information dialog and click
Cancel to dismiss the Rebase Stream Preview dialog.
Note that what we did was to check to make sure developer 1 did not make any
changes to the stream.
On the Deliver from Stream Preview dialog (Figure 23-41) make sure the
dev2_IntegrationView is selected as the integration view. Click OK.
The integration view is now updated with the contents of the development
view. In the Deliver from Stream - Merges Complete dialog, deselect Open a
ClearCase Explorer window.... and click OK.
On the Delivering to View dialog, click Complete and then Close.
Developers synchronize
Developer 2 has now finished his current task and developer 1 can now catch up
with the latest changes made by developer 2:
As developer 1, connect to ClearCase
Select ClearCase -> Update View.
On the Snapshot View Update dialog (Figure 23-43) select Changed in the
left pane. The right pane changes and displays all the changed files.
In the right pane select web.xml and select Show Version Tree from its context
menu. This displays the Version Tree Browser as shown in Figure 23-44. This
window shows the version history for this file.
Close the Version Tree Browser and then close the Snapshot View Update
window. Click OK to dismiss the Save Update dialog.
The integration view is now updated with the latest changes made to the
integration stream. Before developer 1 can continue working his development
view needs to be refreshed.
Select ClearCase -> Rebase Stream. From the Rebase Stream dialog, select
Projects -> ITSO_Project -> ITSO_Project_Integration -> dev1_View and click
OK.
In the Rebase Stream Preview dialog (Figure 23-45) select the new baseline,
ITSO_VOB ITSO_Project_<date>-2, from the baseline drop-down list and
make sure the dev1_View is selected as the target view. Click OK.
Click OK to dismiss the Hijacked Files Warning dialog. The contents of the
integration view is now copied to developer 1’s development view.
Summary
In this chapter we have shown you a very basic scenario with two developers
working on a common Web project.
One of the developers set up the initial environment, added a servlet, delivered
the development stream to the shared integration stream, and made a new
baseline.
The second developer then joined the project, imported its contents into the own
workspace, added a second servlet, delivered the contents to the integration
stream, and made a new baseline.
Part 6 Appendixes
This part of the book includes the following supplementary information:
Appendix A, “Product installation” on page 785
Appendix B, “Keyboard shortcuts” on page 801
Appendix C, “Additional material” on page 809
Although it may be possible to run most of the examples with another relational
database system, we only tested the examples with DB2 UDB.
Installing DB2 UDB Version 7.2 is straight forward. Just follow the installation
panels. You do not have to install all of the components, such as data
warehousing and performance tools.
After the base installation, you have to install Fix Pack 7 or later.
Also, it is required that you run the command file java12\usejdbc2.bat which is
located in the installation directory of DB2 (usually SQLLIB) to enable the JDBC
Version 2 support for data sources. This is not required if you use DB2 Version
8.1.
Hardware prerequisites
Hardware requirements include:
Any Intel®-based PC running Windows NT® Server V4.0, SP 6a or later,
Windows 2000 Server, or Advanced Server SP 2
Intel Pentium® processor at 500 MHz, or faster
Minimum 180 MB free disk space for installation (includes SDK)
Minimum 384 MB memory; 512 MB recommended
Software prerequisites
The installation requires the following software to be installed:
Windows NT Server or Windows 2000 Server
Netscape Communicator 4.7.9 or Microsoft Internet Explorer 5.5 SP 2 and 6.0
Web browser that supports HTML 4 and CSS
For the WebSphere installation, the database does not have to be configured.
Cloudscape can be used in test environment, however, other databases are
required for the production environment. The following databases are supported
with WebSphere Application Server V5 and WebSphere Network Deployment V5
on Windows platforms:
Cloudscape 5.06
DB2 UDB V7.2 Fixpack 7
Informix Dynamic Server Versions 7.31 and 9.3
Oracle Enterprise Edition 8i Release 3 (8.1.7)
Oracle Enterprise Edition 9i Release 2 (9.2)
SQL Server Enterprise 7.0 SP 4 and 2000 SP 2
IBM HTTP Server is bundled with base WebSphere Application Server V5.
However, the following HTTP servers can also be installed and configured to
work with WAS V5:
Apache Server 1.3.26
HTTP Server 1.3.26 AIX, Linux/390, Linux/Intel, NT
Internet Information Server 4.0
Sun ONE Web Server, Enterprise Edition (formerly iPlanet) 6.0 SP 4
Lotus Domino™ Enterprise Server (as HTTP Server) 5.0.9a
Before we start the installation we also have to create the user with
administrative rights on the local machine.
The administrative database of WebSphere Version 4 does not exist any longer.
All of the configuration information for the WebSphere Application Server Version
5 is now contained in XML files in the ${WAS_ROOT}\config directory. There are
many files that contain all the configuration information.
In the first dialog panel, select the language and click OK.
Click Next in the Welcome panel.
After confirming that we agree with the licence agreement, we have to choose
between two installation choices: Typical and Custom. Choosing Typical
installs the entire product, whereas the Custom installation option allows you
to deselect components you do not want to install. We chose the Typical
installation.
The installation directories for the selected components are entered in the
next panel. We chose:
C:\WebSphere\AppServer
C:\IBMHttpServer
C:\WebSphere MQ
If the install was successful, you should see messages similar to the following:
OS: Windows 2000
locale: en_US
hostname: NODENAME
cmd.exe /c "C:\WebSphere\AppServer\bin\ivt" NODENAME 9080
C:\WebSphere\AppServer
IVT0006I: Connecting to the WebSphere Server NODENAME on Port:9080
IVT0007I:WebSphere Server NODENAME is running on Port:9080
IVT0060I: Servlet Engine Verification: Passed
IVT0065I: JSP Verification: Passed
IVT0066I: EJB Verification: Passed
IVT00100I: IVT Verification Succeeded
IVT0015I: Scanning the file
C:\WebSphere\AppServer\logs\server1\SystemOut.log for
errors and warnings
IVT0020I: 0 Errors/Warnings were detected in the file
C:\WebSphere\AppServer\logs\server1\SystemOut.log
IVT0110I: Installation Verification is complete.
Note: Refer to the Migration Guide (these are the migrate.html and
migrate.pdf files in Application Developers installation directory) for
information on how to migrate from VisualAge for Java, WebSphere Studio,
and previous versions of Application Developer.
Hardware prerequisites
Intel Pentium II processor minimum (Pentium III 500 MHz or higher is
recommended)
512 MB RAM minimum (768 MB RAM is recommended)
Disk space: You will require 940 MB minimum disk space for installing
Application Developer and additional disk space for your development
resources. Minimum disk space can be reduced if optional features and
run-time environments are not installed
In addition to the space required to install the product, you must have at least
50 MB free on your Windows system drive, and your environment variable
TEMP or TMP must point to a valid temporary directory with at least 10 MB
free
Note that you also require additional disk space if you download the electronic
image to install Application Developer
Display resolution: 800 x 600 pixels minimum (1024 x 768 recommended)
Software prerequisites
The following software must be installed before you install WebSphere Studio
Application Developer:
One of the following operating systems:
– Windows 2000 Professional with Service Pack 2 or higher
– Windows XP Professional
– Windows NT Workstation or Server Version 4.0 with Service Pack 6a
– Red Hat, Version 7.2
– SuSE, Version 7.2
A Web browser to view the license agreements and the online help for the
WebSphere Studio Installation Launcher
For information about supported database servers, Web application servers, and
other software products, see the readme and the install files located in the root
of the installation CD directory.
Note: If you have VisualAge for Java or any version of WebSphere Studio
already installed, there is no need to un-install it before installing Application
Developer. You can install Application Developer 5 in a separate directory, but
do not install this version of Application Developer over an earlier version.
1. Install Application
Developer
2. Install IBM Agent
Controller
3. Embedded
messaging not
required for the
samples
Select Install IBM Agent Controller from the WebSphere Studio Installation
Launcher (Figure A-2). For Windows you can also run the setup.exe from the
IBM_Agent_Controller\windows directory on the CD. In the installation dialog (for
Windows):
Accept the license.
Enter user name and organization.
Select the installation directory. The default is:
C:\Program Files\IBM\IBM Agent Controller
Select the Java runtime library, for example:
<wsadhome>\eclipse\jre\bin
Select to enable or disable security. If you enable security, you have to prove
the user IDs of authorized users
Select which host computers can access the Agent Controller:
– This computer only
– Any computer
– Specific computers: you provide a list of host names
Start the installation.
You can launch the update manager by selecting Help -> Software Updates ->
Update Manager from the menu bar. This opens the Install/Update perspective.
Note, that you can also open the perspective Install/Update directly.
Note: A detailed description about the Install/Update perspective and its views
is provided in the section “Install/Update perspective” on page 75.
Click the Feature Updates link in the Feature Updates section of the welcome
page to launch the search site. Figure A-4 shows the search page.
Available Updates:
install in this sequence
Select the update you would like to install from the list. Note that the Preview
view changes and displays detailed information regarding the selected update.
This is shown in Figure A-6.
Click here to
start the update
Click the link More Info to open a document which provides more details about
the update. Click Update to launch the update.
Click Next, to bring up the License Agreement dialog up. Carefully review the
license agreements for the upgraded features. If the terms of all these licenses
are acceptable, check I accept the terms in the license agreements and click
Next again, to continue the installation.
Another dialog named Optional Features might come up if the update lets you
choose the components you want to install (Figure A-8).
Select the components you want to install and click Next. The Install Location
dialog comes up as shown in Figure A-9.
Note: While the update is launched, there might another dialog be displayed,
which shows a warning that the feature has not been digitally signed. To
continue the installation process, confirm this dialog with Install.
When the update installation has finished, a dialog comes up which asks, if you
want to restart the Workbench (Figure A-10). It is always recommended to restart
the Workbench after installing an update. Clicking Yes saves the workspace,
closes it and restarts Application Developer.
Once you have installed an update and restarted the Workbench a page comes
up which provides you information about the new update.
Manual update
To install fixes and updates without the Update Manager, download the
appropriate file from the Application Developer’s support web site:
http://www.ibm.com/software/awdtools/studioappdev/support/
Once you have download the update file, consult the installation instructions for
how to perform your update. Note that the Workbench should not be running
while the updates are being installed.
In the Feature Update view, select the update by expanding the “My
Computer” tree to the folder where you have unzipped the package and click
Update in the Preview view. Then follow the instructions on the screen.
There is an install.html file that describes (in detail with screenshots) how to
install the downloaded update or PTF.
B Rebuild All
F2 Rename (Navigator
view)
Editing shortcuts
Table B-2 Keyboard shortcuts for editing
Key Ctrl+Key Ctrl+Shift+Key
E Edit > Delete Line Edit > Delete Line to the End
F Format
M Add import
O Organize imports
1 Quick fix
F3 Open on selection
F4 Open type
hierarchy
T Open type
B Add/Remove
breakpoint
D Display
Q Inspect
R Run to Line
U Run snippet
F5 Step into
F6 Step over
F7 Run to return
F8 Resume
F9 Relaunch last
A Add Column to
Left
B Bold
C Select Column
E Align Horizontal
Center
G Insert Image
I Italic
L Align Left
O Insert Form
P Preview Page
(toggle)
S Source Page
(toggle)
T Insert Table
U Underline
Space Insert
Non-breaking
Space ( )
Right arrow Next Word Join Cell with Split Cell into
Cell on Right Columns
Down arrow Focus Hierarchy Join Cell with Split Cell into
Down Cell Below Rows
0 Insert Paragraph
1 Insert Heading 1
2 Insert Heading 2
3 Insert Heading 3
4 Insert Heading 4
5 Insert Heading 5
6 Insert Heading 6
C Cleanup Document
F Format Document
Select the Additional materials and open the directory that corresponds with
the redbook form number, SG24-6957.
EJBBANK database
The EJBBANK database is the same as is used in the IBM Redbook EJB 2.0
Development with WebSphere Studio Application Developer, SG24-6819. For
details about the data model and content, refer to Chapter 10, “Introducing and
preparing for the sample application” in that redbook.
On the next page (Figure C-2) select Create a new Java project defined as a
utility JAR or web library. This creates the ItsoProGuideJava project that is
used as a utility JAR file in other projects.
Click Next and go through the remaining pages (Figure C-3), but do not
modify anything, or click Finish now.
The publications listed in this section are considered particularly suitable for a
more detailed discussion of the topics covered in this redbook.
IBM Redbooks
For information on ordering these publications, see “How to get IBM Redbooks”
on page 819. Note that some of the documents referenced here may be available
in softcopy only.
EJB 2.0 Development with WebSphere Studio Application Developer,
SG24-6819
WebSphere Version 5 Web Services Handbook, SG24-6891
The XML Files: Development of XML/XSL Applications Using WebSphere
Studio Version 5, SG24-6586
Exploring WebSphere Studio Application Developer Integration Edition 5.0,
SG24-6200
Linux Application Development Using WebSphere Studio 5, SG24-6431
IBM WebSphere Application Server - Express V5.0 Handbook, SG24-6555
IBM WebSphere Application Server Version 5.0 Handbook, SG24-6195
IBM WebSphere V5.0 Security WebSphere Handbook Series, SG24-6573
Legacy Modernization with WebSphere Studio Enterprise Developer,
SG24-6806
WebSphere Studio Application Developer Programming Guide, SG24-6585
Web Services Wizardry with WebSphere Studio Application Developer,
SG24-6292
Self-Study Guide: WebSphere Studio Application Developer and Web
Services, SG24-6407
WebSphere Version 4 Application Development Handbook, SG24-6134
EJB Development with VisualAge for Java for WebSphere Application Server,
SG24-6144
Design and Implement Servlets, JSPs, and EJBs for IBM WebSphere
Application Server, SG245754
Online resources
These Web sites and URLs are also relevant as further information sources:
IBM WebSphere Studio Application Developer
http://www.ibm.com/software/awdtools/studioappdev/support
IBM WebSphere Application Server
http://www.ibm.com/software/webservers/appserv/
IBM WebSphere Developer Domain
http://www7b.software.ibm.com/wsdd/
Eclipse workbench
http://www.eclipse.org
Apache open source
http://jakarta.apache.org
Apache Struts Project
http://jakarta.apache.org/struts
Apache XML Project
http://xml.apache.org/
Apache Tomcat Project
http://jakarta.apache.org/tomcat
Apache Ant Project
http://ant.apache.org
Index 823
CustomerListing 100, 110, 498 create 256
CustomerListingDS 614 EJB access 428
CustomerListingNet 101 server configuration 533
customize server definition 256
perspective 54 data transfer object 385, 388, 425
server configuration 544 database
Visual Editor 478 application run 259
CVS 701 applications 139
branch 733 connection 145
configuration 706 create 155–156
console 712 tools 14
Console view 706, 712 Database Access
control information 745 Java Beans 250
decorators 706 Tag Library 250
ignore facility 711 Database Web Pages wizard 249
ignored resources 710 DB Beans 248, 260
installation 703 DB Output view 278
patch 740 DB Servers view 69, 143
preferences 707 DB2
reconnect 745 App Driver 146
Repositories view 73, 715 Command Window 163
repository 703 JDBC driver 104
add 714 Net Driver 146
Repository Exploring perspective 73, 706 UDB installation 786
Resource History view 74, 731 user ID and password 814
scenario 713 XML Extender 14, 445
server 707 DB2ConnectionPoolDataSource 619
services 704 db2java.zip 104, 176, 412, 618
share project 716 dbbeans.jar 261, 263
Web site 703 dbbeans_javadoc.zip 261
CVSNT 703 DBConnectionSpec 261
service configuration 705 DBProcedureCall 263
DBSelect 261
DDL 142
D generate 151, 161
dab
dds.xml 445, 456
dataSourceSpec 267, 291
Debug
getColumn 268
perspective 69, 109
parameter 268, 291
view 70, 111, 560
procedureCall 291
-debug 24
repeat 268
debugging 109
select 268
icons 560
DADX 445
JSP 564
Data
port 566
Definition view 69, 143, 272
remote 566
perspective 68, 142
source code 570
-data 24
step-by-step 558
data source 141, 177, 251
tools 16
Application Server 619
Web application 554
Index 825
archive 15 Struts
export 616 form bean 310
installation 622 formatting rules 35
Enterprise Application project 83, 514 fragment 18
Enterprise Developer 8 frameset 196
overview 10 front controller 252
enterprise generation language 10 FTP 520
Enterprise Java Server 377 file transfer 526
entity bean 381
create 389
event handling 502
G
Gallery view 60
Execution Flow view 72, 679
garbage collection 666, 673
Execution view 72
thread 679
export
generate
enterprise application 616
DDL 161
GUI application 508
DDL from XMI 142
Java class 106
getter methods 422
Expressions view 71, 562
getter/setter 127
extract
XML schema 152
method 123
Generate Deploy and RMIC Code wizard 426
variable 123
GenPluginCfg 629
extreme programming 574
getConnection 175
GetCustomberBean 281
F GetCustomerMain 280
facade 112, 184, 295, 436 Graph view 355
EJB 385 graphical user interface 469
Feature Updates view 75 GridBagLayout 492
file GridLayout 489
associations 28 GROUP BY 169
compare 690 GUI application 469
replace 691
restore 692
serving 613
H
hardware prerequisites
transfer mechanism 520
Application Developer 790
filter
Application Server 786
chaining 227
HEAD branch 719
create 227
headless 652
profiling 660
heap 547, 666, 670
servlet 226
Heap view 72, 670–671
Tasks view 122
help
finder method 383
Application Developer 48
findGoldAccounts 407
bookshelves 49
FirstHTTPTest 599
Hierarchy view 62, 65
firstSteps 629
history 29
Fix Packs 549
hit count 555
FlowLayout 492
home interface 382, 396
foreign key 162
horizontal integration 7
form bean 300
host variable 169
Index 827
itso.jbwp 238 JAAS 533
itso.junit 579 JAR 81
itso.storedproc 275 Java
itso.storedproc.bean 281 application development 93
itso.storedproc.main 280 Beans view 490
itso.strutsweb.forms 311 Browsing perspective 63
itso.strutsweb.resources 304 build path 87
itso.webserv.model 446 build settings 96
itso.xml 350, 371 class 100
ItsoProGuide 187, 302, 608, 616, 645, 657 development
ItsoProGuide.ear 812 preferences 33
ItsoProGuideAnt 635 tools 15
ItsoProGuideBasicWeb 186, 436, 554, 570, 611 Editor
ITSOProGuideCCEAR 762 preferences 37
ITSOProGuideCCWeb 762 package 99
ItsoProGuideCVS 715 perspective 61
ItsoProGuideDatabase 149 Profiling Agent 659
ItsoProGuideDataBaseWeb 248 project 82, 94
ItsoProGuideDatabaseWeb 538 Runtime Environment 39
ItsoProGuideEJB 388, 464 Scrapbook 115
ItsoProGuideGui 471 search 128
ItsoProGuideJava 95, 114, 180, 188 source folder 191
ItsoProGuideJavaClient 613–614 stored procedure 272
ItsoProGuideJUnit 578, 589 test case 589
ItsoProGuideServer 519 Type Hierarchy perspective 64
ItsoProGuideServers 224 utility JAR 645
ItsoProGuideStoredProcWeb 272, 539 Virtual Machine 656
ItsoProGuideStrutsWeb 302, 436 Profiler Interface 656
ItsoProGuideWebServ 446 java
ItsoProGuideWebServClient 452 comp/env 614
ItsoProGuideXmlWeb 350 JavaBean
ItsoServer 224, 259 from WSDL 445
from XSD 445
Web Pages wizard 237
J Javadoc 133
J2EE
Ant 136, 651
API 80
code assist 118
architecture 80
comment 101
Hierarchy view 57
generation 133
Navigator view 56, 60
preferences 40, 133
perspective 56
JavaScript 13, 218
projects 83
JavaServer Pages 7
Publishing Server 516
JAXP 346
Request Profiler 659
JDBC 140, 174
specification 9
2.0 Standard Extension API 141
technologies 80
connection 140
Web project 84
create 146
J2SE
data source 177
specification 9
driver 174, 619
Index 829
MANIFEST.MF 191 NFS 23
mapping
editor 414
strategies 409
O
object
marker 554
caching 375
Master.css 201
pooling 375
MDB 378, 381
Object References view 72, 684
mediator 112
object-relational mapping 409
memory analysis 666
ODBC 140
memory leaks 673
OMG 142
merging 736
Open Source 679
Merging from a stream 736
optimistic concurrency 696
message-driven bean 378, 381
Oracle 147, 787
MessageDrivenBean 382
ORDER BY 169
MessageListener 382
org.apache.struts 298
messaging 377–378
organize imports 121
metadata directory 82
preferences 42
META-INF 191
ost variable 253
Method
Outline view 57, 59–60, 62, 67, 72, 119
Execution view 72, 677
override methods 127
Invocation view 72, 674
Statistics view 72, 669
method P
execution 673 Package Explorer view 61, 119
extract 123 Package Statistics view 72, 667
override 127 Page Designer 60, 193
pull up 123 JSP tag rendering 323
migration 12 palette 475
model 295 parallel development 723
MVC 180 patch 740
model-view-controller 294 apply 742
modify parameters 123 path language 348
module dependency 189, 303 pattern
multiplicity 402 command 181
MVC 180 MVC 180, 294
controller 296 PDE 17
model 295 performance
pattern 297 analysis 663, 666
Struts 297–298 profiling 10
view 296 profiling tools 16
MySQL 147 PerformTransaction 181, 229
PerformTransactionAction 336
persistence 374, 377–378
N Persistence Builder 12
namespace 348, 378
perspective 22
naming 377–378
Component Test 72, 588
NamingException 422
customize 54
Navigator view 56, 59, 67, 144
CVS Repository Exploring 73, 706
network file system 23
Data 68, 142
Index 831
properties reconnect 745
project 87 request sequence 299
Properties view 58, 476 requestor 442
filter 489 Resource
provider 442 Patcher wizard 742
proxy 452 perspective 58
class 458 resource
proxy.soap 452 synchronization 711
pserver 702 resources
puggable 115 ignored 710
pull up method 123 restoreConfig 629
ResultSet 176
resume 560
R RMI 377
ramp-up time 576
role-based development model 4
RAR 545
root element 353, 360
Rational
Run on Server 259, 516
ClearCase
runAnt.bat 652
see ClearCase
RunBanking.jsp 446
Web site 748
run-time environment 514
rebase 749, 777
RunTranfer.jsp 291
Red Hat 790
RedBank 180
Redbooks Web site 819 S
Contact us xxiv sample code 18
refactoring 15, 122 scalability 375
example 124 schema
preferences 43, 124 create 157
preview 126 SCM 689
reference tools 699
EJB 418 scope 449
references 418 scrapbook 15, 115
relationship scriptlet 222
methods 404 search 50, 128
relationships 382 security 377–378
create 400 SOAP 449
remote SELECT
Application Server 566 statement 165
client view 416 self encapsulate 123
debugging 566, 629 Sequence Diagram view 680
file transfer instance 524 Server
profiling 665 Configuration view 66, 224, 529
server 520 perspective 66, 513
attach 567 project 85, 519
debug configuratoin 566 server
settings 523 configuration 514
user ID and password 538 create 519
rename 123 create manually 527
repository 694 customize 544
Index 833
configuration file 336 TCP/IP Monitor view 543
controller 297 TCP/IP Monitoring Server 516
create team development 8, 693
action 332 tearDown 582
form bean 311 template
JSP 316 application 88
framework 301 templates 43
JSP tags 300 preferences 44
logic tag 330 terminate 560
model 297 terminology comparison 699
MVC 297–298 test case
project 84, 300 create 578, 582
request sequence 299 HTTP 598
servlet 298 prepare 591
tag libraries 317 report 595
view 297 TestCase 577
struts.jar 304 TestClient.jsp 459
strutsbank.gph 308, 340 TestDBBeans.jsp 261, 538
struts-bean.tld 319 TestSuite 577, 584
struts-config.xml 304, 314, 336 TestTagLib.jsp 264
struts-html.tld 319 Text Editor 150
struts-logic.tld 324 theme 191
struts-xxxx.tld 304 thread activity 666
style sheet 200 Threads 680
Styles view 61 Thumbnail view 61
Sun ONE Web Server 787 time
SuSE 790 analysis 666
suspend 560 consuming objects and methods 672
Swing 470 Tomcat 515, 539
Sybase 14, 147 download 539
synchronization 484, 695 preferences 540
synchronize 779 tools 12
Synchronize view 718 transaction 377
syntax demarcation 378
highlighting 118, 351 TransactionAuditingFilter 228
HTML 194 transactions
EJB 375
transfer object 385
T
table
create 157 U
join 168 UDDI 15, 444
tag library 213 registry 454
data beans 248 UML view 402
import 265 Unified Change Management 748
stored procedure 285 unique identifier 395
Tasks view 57, 67, 108, 121 unit test
TCP/IP Monitor 540 case 575
port 542 environment 17
Index 835
overview 51 Service
Visual Composition Editor 12, 502 Explorer 455
Visual Editor 11, 469–470 service 9
code synchronization 484 client 461, 465
customize 478 create 446
event handling 502 from session bean 464
example 481 proxy 452
Java Beans view 490 scope 449
launch 472 test 459
look and feel 475 universal test client 460
palette 475 URI 448
preferences 478 XML mapping 450
-vm 24 services 443
-vmargs 24–25 clients 446
VOB 749 tools 445
create 756 services tools 15
Structure view 60, 300
Web Service Client wizard 461
W Web Service wizard 447
W3C 200, 346
Web Services Description Language 15
WAR 81, 645
Web Services Object Runtime Framework 632
class loader policy 546
web.xml 213
import 192
WEB-INF 191
watching variables 561
webservice-runtime.jar 456
Web
WebSphere
application
extension class loader 546
archive 15
WebSphere MQ 379
debug 554
WebSphere Studio
development 179
family 9
Art Designer 13
product family 4
Browser view 557
WebSphere Studio Application Developer
container 80
see Application Developer
content folder 191
WebSphere Studio Asset Analyzer 11
deployment descriptor 13, 213, 611
WHERE clause 168, 173
development tools 13
wizard
diagram 300
Application Template 88
complete 341
Create Web Pages from a JavaBean 286
components 308
Database Web Pages 249
create 307
Generate Deploy and RMIC Code 426
implemented 331
JavaBean Web Pages 237
material 810
SQL Statement 14, 165, 274
module 81
SQL to XML 14
pages from SQL queries 249
Stored Procedure 273
perspective 59
Web Service 447
project 84, 514
Web Service Client 461
create 185
XML Signature 361
dependencies 437
WORF 632
EJB reference 438
worf.jar 632
features 186
Workbench 4
Index 837
838 WebSphere Studio Application Developer Version 5 Programming Guide
WebSphere Studio
Application Developer
Version 5 Programming Guide
(1.5” spine)
1.5”<-> 1.998”
789 <->1051 pages
Back cover ®
WebSphere Studio
Application Developer
Version 5 Programming Guide
Develop Java, Web, This IBM Redbook is a programming guide for the application
XML, database, EJB, development tool, WebSphere Studio Application Developer V5. This
INTERNATIONAL
and Web services tool is not only intended for the Java developer, but also for the Web TECHNICAL
applications designer who creates Web pages. The WebSphere Studio Application SUPPORT
Developer basic tooling and team environment is presented along with ORGANIZATION
the development and deployment of Web applications.
Test with built-in and
remote servers WebSphere Studio Application Developer provides integrated
development tools for all e-business development roles, including Web BUILDING TECHNICAL
Deploy to WebSphere developers, Java developers, business analysts, architects, and INFORMATION BASED ON
Application Server enterprise programmers. The customizable, targeted, role-based PRACTICAL EXPERIENCE
approach of WebSphere Studio Application Developer will be
characteristic of all new products built on the WebSphere Studio IBM Redbooks are developed by
Workbench. It is well integrated with WebSphere Application Server the IBM International Technical
and provides built-in server test environments that can be used for Support Organization. Experts
testing and profiling Web applications. from IBM, Customers and
Partners from around the world
create timely technical
This redbook consists of six parts: information based on realistic
Introducing WebSphere Studio Application Developer scenarios. Specific
Developing applications recommendations are provided
Testing and debugging applications to help you implement IT
Deploying and profiling applications solutions more effectively in
your environment.
Team programming
Appendixes and additional material