Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

The Go-ForIt Chronicles: Memoirs of eXtreme DragonSlayers, Part 4

"Bean" there, done that: Using client-side beans for component independence

Sandeep Desai (sandeep@us.ibm.com), e-business Architect, IBM
Sandeep Desai is an e-business Architect in IBM's Developer Relations Technical Consulting group in Austin, Texas. He works with IBM's Business partners -- small or large companies, from startups to large firms, helping them get excited, evangelized, educated, and enabled on IBM's e-business platform. Sandeep holds the following technical certifications, among others: IBM Certified e-business Solution Advisor, IBM Certified e-business Solution Designer, IBM Certified e-business Solution Technologist, IBM Certified Specialist -- WebSphere Application Server, IBM Certified Systems Expert -- WebSphere Application Server. You can reach him at sandeep@us.ibm.com

Summary:  In this fourth part of our series about the DragonSlaying technical consulting team, Sandeep Desai describes how the team uses Java client-side beans in the Go-ForIt project. This article discusses the architectural and design issues that prompted the team to choose client-side beans and includes sample code showing the application design.

Date:  01 Jul 2001
Level:  Introductory

Activity:  2879 views
Comments:  

The Go-ForIt architecture

We're just full of beans on the Developer Relations Technical Consulting team. JavaBeans components, that is. We use them in our three-tier Go-ForIt.com application, as follows:

First tier
The browser.
Second tier
Servlets, JavaServer Pages (JSPs) technology, and a bunch of specialized JavaBeans components.
Third tier
Business logic, in Enterprise JavaBeans (EJB) technology, and a database.

The application is designed so each tier can reside on a separate machine. We think this is cool because when our user base grows, we can effectively scale using WebSphere's WorkLoad Management functions.


The design challenge

We decided to use client-side beans in response to a design challenge. We define requirements in terms of user stories. Our first user story, "The user registers with the Go-ForIt.com Web site," forced us to make a critical design decision. The figure below shows one solution to the problem.


Architecture before client-side bean
diagram shows the elements of each layer of the MVC

Our application has two types of users: customers and personal assistants (PAs). Because the user information has to be stored in a database, it is a persistent entity, and we implement it as a container-managed persistent EJB component on the third tier of the application.

In our application, the first thing users have to do is register. They complete all the required profile information in the form and send it to the registration servlet (on the middle tier). The servlet sends this data over to the User EJB component, so it can be persisted. The servlet will have to do a look-up on the User EJB component, get the component's home interface and call its create method, then get the component's remote interface and call individual set methods for each field. The current version of the User class has 20 fields, which means that the servlet has to call 20 set methods. That's a lot of remote method calls just to create a user.

When we started implementing the second user story, "User changes the user profile," guess what? We had to first go and get all 20 fields from the database with the EJB component, using servlets, and display them using JSPs technology. Then, when the user changed the profile, we had to go back and persist the change. This meant a lot of remote method calls between our middle and third tier. And more remote calls meant decreased performance. We needed a more elegant solution.


Client-side beans set us free

Reusable components are simply pre-built pieces of programming code designed to do a specific function. They help reduce the development time for applications. JavaBeans components are "capsules" of code, each designed for a specific purpose. The advantage of the JavaBeans component architecture over standard programming components is that JavaBeans components are independent. A JavaBeans component and a server bean, more commonly known as an Enterprise JavaBeans (EJB) component, have some similarities. They are both objects or components created with a set of characteristics to do a specific job. An EJB component is used on the server side to represent back-end business logic. An invisible JavaBeans component can be used either as a shared resource within a GUI application, or as a component in building server applications. JavaBeans components can be paired with EJB components to do business functions such as errands, credit card validation, and so on.

What do we mean by client-side beans?

The servlets are clients to EJB components. In our example, the registration servlet is a client to the User EJB component. The servlets can effectively use a JavaBeans component that captures the user profile, and the profile can be passed to the User EJB component. Since these JavaBeans components reside on the middle tier, which is a client to the EJB component, we call them client-side beans.

Another important use of the client-side beans is that they can be consumed by the JSPs, or other servlets, or client-side components and be reused. This reduces the trips to the server to get the data. In our example, user_profile_edit.jsp will use the User Data bean to get values of the different fields to display when users need to edit their profile.

Classes or beans?

The next dilemma we faced was to determine which components would be Java classes and which would be JavaBeans components. All of our objects can easily be represented as a Java class. We had to have a scheme to decide which Java classes should be beans, so we asked the following questions:

  • Can this piece of code be used in more than one area? Would others benefit from reusing this piece of code?
  • Can you quickly think of ways that this piece of code might be customized?
  • Is the purpose of this code easy to explain?
  • Does the code module contain all the information it needs to work by itself? Does it have good encapsulation?
  • Do these classes store all the data information and have none or little behavior information in them?

If we answered yes to all of the questions, we made the class a bean. You can make any Java class into a bean by changing the class to adhere to the JavaBeans APIs specification. For the client-side beans we used the Serializable interface. Because we're using eXtreme Programming (XP) we let the individual component developer use the questions above to decide whether to design a component as a bean or a Java class. (See "eXtreme programming: deceptively simple innovation" for information on XP.)

The figure below shows our application architecture after using client-side beans.


Architecture after client-side beans
diagram shows the elements of each layer of the MVC

How do client-side beans work?

When users register on the site, we collect information: their first and last name, address, phone number, whether they're a customer or PA or both, credit card information, user ID, and password. That information is then stored in the database.

Because the users need to be persistent and participate in a transaction, they are represented as an Entity bean that resides in a server-side EJB container. The HTML page invokes the registration servlet. The registration servlet is on the client-side Web container. It reads all the parameters from the request object and sets it in the user object, using the set methods. Setting each parameter individually requires invoking the corresponding set method. Since we didn't want to make remote method calls on the User EJB component, we used a client-side bean called the UserDataBean. This bean is in the same Web container as the servlets on the client side. The servlet instantiates a UserDataBean and then sets all the parameters in it, as shown in the code example below.


Listing 1: Registration Servlet sets the data in UserDataBean
\** This is sample code for performTask method of Registration Servlet**\
public void performTask(
     javax.servlet.http.HttpServletRequest req,
     javax.servlet.http.HttpServletResponse res) {
     //instantiate the Client Side Bean 
     UserDataBean user = new UserDataBean();           
     UserRegistersCommandBean dataCommand = new UserRegistersCommandBean();
     try {
             /*
              * Retrieve the form fields
              */
             user.setAltphone(req.getParameter("alternatePhone"));
             user.setCcname(req.getParameter("nameOnCreditCard"));
             user.setCcnum(req.getParameter("creditCardNumber"));
             user.setCctype(req.getParameter("creditCardType"));

             // convert from the string to an SQL date type. 
             // Day doesn't matter so we use 28 in all cases
             
             String dateString =
                     req.getParameter("expirationYear")
                             + "-"
                             + req.getParameter("expirationMonth")
                             + "-28";

             java.sql.Date date = java.sql.Date.valueOf(dateString);
             user.setExpdate(date);

             //
             user.setFname(req.getParameter("firstName"));
             user.setMidinit(req.getParameter("middleInitial"));
             user.setLname(req.getParameter("lastName"));
             user.setPassword(req.getParameter("password"));
             user.setCity(req.getParameter("city"));
             user.setStreet1(req.getParameter("address1"));
             user.setStreet2(req.getParameter("address2"));
             user.setTitle(req.getParameter("title"));
             user.setTstamp(Long.toString(System.currentTimeMillis()));
             user.setCctype(req.getParameter("creditCardType"));
             user.setUserid(req.getParameter("userid"));
             user.setState(req.getParameter("state"));
             user.setZip(req.getParameter("zipCode"));
             user.setEmail(req.getParameter("email"));
             user.setPhone(req.getParameter("phone"));
             user.setType(getUserType(req));

             /*
              * Update database with new user information
              */
             try {
                     dataCommand.setUser(user);
                     dataCommand.execute();

             } catch (Exception e) {
               .........
             } 
             /* Create/update session object to record new user information */
             HttpSession session = null;

             session = req.getSession(true);
             session.putValue("user", user);

             req.setAttribute("user", user);
             String userType = user.getType();

             /* Forward to HTML View JSP */

             if (userType.equals(UserDataBean.CUSTOMER)) {
                     /* Forward to HTML View JSP */
                     getServletConfig()
                             .getServletContext()
                             .getRequestDispatcher("pages/customer_main_menu.jsp")
                             .forward(req, res);
             } else {
                     /* set the paErrandList in the session to null */ 
                     com.goforit.ejb.Errand paErrandList = null;
                     session.putValue("paErrandList", paErrandList);

                     if (userType.equals(UserDataBean.PA)) {
                             /* Fill in PA Stuff */
                             getServletConfig()
                                     .getServletContext()
                                     .getRequestDispatcher("pages/pa_profile_edit.jsp")
                                     .forward(req, res);
                     } else {
                             /* Forward to HTML View JSP */
                             getServletConfig()
                                     .getServletContext()
                                     .getRequestDispatcher("pages/pa_profile_edit.jsp")
                                     .forward(req, res);
                     }
             }

     } catch (Throwable t) {
       ........  
     }
     

\** This is sample code for performTask method of Registration Servlet**\
public void performTask(
     javax.servlet.http.HttpServletRequest req,
     javax.servlet.http.HttpServletResponse res) {
     //instantiate the Client Side Bean 
     UserDataBean user = new UserDataBean();           
     UserRegistersCommandBean dataCommand = new UserRegistersCommandBean();
     try {
             /*
              * Retrieve the form fields
              */
             user.setAltphone(req.getParameter("alternatePhone"));
             user.setCcname(req.getParameter("nameOnCreditCard"));
             user.setCcnum(req.getParameter("creditCardNumber"));
             user.setCctype(req.getParameter("creditCardType"));

             // convert from the string to an SQL date type. 
             // Day doesn't matter so we use 28 in all cases
             
             String dateString =
                     req.getParameter("expirationYear")
                             + "-"
                             + req.getParameter("expirationMonth")
                             + "-28";

             java.sql.Date date = java.sql.Date.valueOf(dateString);
             user.setExpdate(date);

             //
             user.setFname(req.getParameter("firstName"));
             user.setMidinit(req.getParameter("middleInitial"));
             user.setLname(req.getParameter("lastName"));
             user.setPassword(req.getParameter("password"));
             user.setCity(req.getParameter("city"));
             user.setStreet1(req.getParameter("address1"));
             user.setStreet2(req.getParameter("address2"));
             user.setTitle(req.getParameter("title"));
             user.setTstamp(Long.toString(System.currentTimeMillis()));
             user.setCctype(req.getParameter("creditCardType"));
             user.setUserid(req.getParameter("userid"));
             user.setState(req.getParameter("state"));
             user.setZip(req.getParameter("zipCode"));
             user.setEmail(req.getParameter("email"));
             user.setPhone(req.getParameter("phone"));
             user.setType(getUserType(req));

             /*
              * Update database with new user information
              */
             try {
                     dataCommand.setUser(user);
                     dataCommand.execute();

             } catch (Exception e) {
               .........
             } 
             /* Create/update session object to record new user information */
             HttpSession session = null;

             session = req.getSession(true);
             session.putValue("user", user);

             req.setAttribute("user", user);
             String userType = user.getType();

             /* Forward to HTML View JSP */

             if (userType.equals(UserDataBean.CUSTOMER)) {
                     /* Forward to HTML View JSP */
                     getServletConfig()
                             .getServletContext()
                             .getRequestDispatcher("pages/customer_main_menu.jsp")
                             .forward(req, res);
             } else {
                     /* set the paErrandList in the session to null */ 
                     com.goforit.ejb.Errand paErrandList = null;
                     session.putValue("paErrandList", paErrandList);

                     if (userType.equals(UserDataBean.PA)) {
                             /* Fill in PA Stuff */
                             getServletConfig()
                                     .getServletContext()
                                     .getRequestDispatcher("pages/pa_profile_edit.jsp")
                                     .forward(req, res);
                     } else {
                             /* Forward to HTML View JSP */
                             getServletConfig()
                                     .getServletContext()
                                     .getRequestDispatcher("pages/pa_profile_edit.jsp")
                                     .forward(req, res);
                     }
             }

     } catch (Throwable t) {
       ........  
     }
     

Now we have an object that represents all the user data, we can pass this object on the server side to the User EJB component with the help of a command bean. The persistent file IDs of the User EJB component are initialized in its create method, as shown below.


Listing 2: Populating the User EJB with user data on the server side
/**
 * ejbCreate method for a CMP entity bean
 * @param argUserid java.lang.String
 * @exception javax.ejb.CreateException The exception description.
 * @exception java.rmi.RemoteException The exception description.
 */
public void ejbCreate(com.goforit.user.UserDataBean argUser) 
    throws javax.ejb.CreateException, java.rmi.RemoteException {
        
        // All CMP fields should be initialized here.
        userid = argUser.getUserid();
        altphone = argUser.getAltphone();
        ccexpdate = argUser.getExpdate();
        ccname = argUser.getCcname();
        ccnumber = argUser.getCcnum();
        cctype = argUser.getCctype();
        city = argUser.getCity();
        email = argUser.getEmail();
        firstname = argUser.getFname();
        lastname = argUser.getLname();
        midinitial = argUser.getMidinit();
        password = argUser.getPassword();
        phone = argUser.getPhone();
        state = argUser.getState();
        street1 = argUser.getStreet1();
        street2 = argUser.getStreet2();
        timestamp = argUser.getTstamp();
        title = argUser.getTitle();
        type = argUser.getType();
        zip = argUser.getZip();

/**
 * ejbCreate method for a CMP entity bean
 * @param argUserid java.lang.String
 * @exception javax.ejb.CreateException The exception description.
 * @exception java.rmi.RemoteException The exception description.
 */
public void ejbCreate(com.goforit.user.UserDataBean argUser) 
    throws javax.ejb.CreateException, java.rmi.RemoteException {
        
        // All CMP fields should be initialized here.
        userid = argUser.getUserid();
        altphone = argUser.getAltphone();
        ccexpdate = argUser.getExpdate();
        ccname = argUser.getCcname();
        ccnumber = argUser.getCcnum();
        cctype = argUser.getCctype();
        city = argUser.getCity();
        email = argUser.getEmail();
        firstname = argUser.getFname();
        lastname = argUser.getLname();
        midinitial = argUser.getMidinit();
        password = argUser.getPassword();
        phone = argUser.getPhone();
        state = argUser.getState();
        street1 = argUser.getStreet1();
        street2 = argUser.getStreet2();
        timestamp = argUser.getTstamp();
        title = argUser.getTitle();
        type = argUser.getType();
        zip = argUser.getZip();


UserDataBean is my friend

I've shown how to use UserDataBean to initialize the User EJB component. Now, let's say I need to activate the object from the database and display its values in a JSP servlet, so users can update their profile information. Think of the amount of network traffic for such a data-intensive object! I will again seek help from UserDataBean.

Our team has a UserController EJB that does the controller function for User EJB objects on the server side. It has a method getUserInfo(String userid). Using userid, we find the corresponding User EJB. Then we instantiate the UserDataBean and set its field value from the corresponding field values of the User EJB. Finally we return the UserDataBean back to the client side, as shown below.


Listing 3: UserController EJB retrieving user data from the User EJB and setting in UserDataBean
public UserDataBean getUserInfo(String userid)
        throws java.rmi.RemoteException {
        UserDataBean userDataBean =  null;

        try {
                // Get User info 
                User user = 
                        _userHome.findByPrimaryKey(new UserKey(userid)); 
                //instantiate the Client Side Bean 
                userDataBean = new UserDataBean(); 
                userDataBean.setUserid(userid);
                userDataBean.setAltphone(user.getAltphone());
                userDataBean.setCcname(user.getCcname());
                userDataBean.setCcnum(user.getCcnumber());
                userDataBean.setCctype(user.getCctype());
                userDataBean.setCity(user.getCity());
                userDataBean.setEmail(user.getEmail());
                userDataBean.setExpdate(user.getCcexpdate());
                userDataBean.setFname(user.getFirstname());
                userDataBean.setLname(user.getLastname());
                userDataBean.setMidinit(user.getMidinitial());
                userDataBean.setPassword(user.getPassword());
                userDataBean.setPhone(user.getPhone());
                userDataBean.setState(user.getState());
                userDataBean.setStreet1(user.getStreet1());
                userDataBean.setStreet2(user.getStreet2());
                userDataBean.setTitle(user.getTitle());
                userDataBean.setTstamp(user.getTimestamp());
                userDataBean.setType(user.getType());
                userDataBean.setZip(user.getZip());
                         
        } catch (ObjectNotFoundException e) {
                return userDataBean;
        } catch (Exception e) {
                throw new java.rmi.RemoteException(e.toString());
        }
        return userDataBean;
        

public UserDataBean getUserInfo(String userid)
        throws java.rmi.RemoteException {
        UserDataBean userDataBean =  null;

        try {
                // Get User info 
                User user = 
                        _userHome.findByPrimaryKey(new UserKey(userid)); 
                //instantiate the Client Side Bean 
                userDataBean = new UserDataBean(); 
                userDataBean.setUserid(userid);
                userDataBean.setAltphone(user.getAltphone());
                userDataBean.setCcname(user.getCcname());
                userDataBean.setCcnum(user.getCcnumber());
                userDataBean.setCctype(user.getCctype());
                userDataBean.setCity(user.getCity());
                userDataBean.setEmail(user.getEmail());
                userDataBean.setExpdate(user.getCcexpdate());
                userDataBean.setFname(user.getFirstname());
                userDataBean.setLname(user.getLastname());
                userDataBean.setMidinit(user.getMidinitial());
                userDataBean.setPassword(user.getPassword());
                userDataBean.setPhone(user.getPhone());
                userDataBean.setState(user.getState());
                userDataBean.setStreet1(user.getStreet1());
                userDataBean.setStreet2(user.getStreet2());
                userDataBean.setTitle(user.getTitle());
                userDataBean.setTstamp(user.getTimestamp());
                userDataBean.setType(user.getType());
                userDataBean.setZip(user.getZip());
                         
        } catch (ObjectNotFoundException e) {
                return userDataBean;
        } catch (Exception e) {
                throw new java.rmi.RemoteException(e.toString());
        }
        return userDataBean;
        

The EditUserProfileServlet sets the above UserDataBean in the request object and invokes user_profile_edit.jsp. So user_profile_edit.jsp now has access to the above bean using the <jsp:useBean> tag. We then retrieve individual properties using the <%jsp:getProperty> tag or a JSP expression. The following code sample shows the JSP expression.


Listing 4: user_profile_edit.jsp displays the user data for user to edit
<TD class="head">Edit User Information</TD>
      ........         
      <jsp:useBean id="user" class="com.goforit.user.UserDataBean" scope="session">
      </jsp:useBean>
      ........    
      <TD class="subhead">Please update the following information as required:</TD>
      ........ 
      <FORM action="/goforit/UpdateUserProfileServlet" 
           method="POST" onsubmit="return checkForm(this);"> 
      ........  
     
            <TD width="375" align="right">First Name:</TD>
            <TD>
            <%--METADATA type="DynamicData" startspan
                <INPUT size="20" type="text" maxlength="25" name="firstName" 
                   valueproperty="user.fname" dynamicelement>--%>
                <INPUT maxlength="25" name="firstName" size="20" 
                   type="text" value="<%= user.getFname() %>">
            <%--METADATA type="DynamicData" endspan--%>
            </TD>
          </TR>
          <TR>
            <TD width="375" align="right">Last Name:</TD>
            <TD>
            <%--METADATA type="DynamicData" startspan
                <INPUT size="20" type="text" maxlength="30" name="lastName" 
                    valueproperty="user.lname" dynamicelement>--%>
                <INPUT maxlength="30" name="lastName" size="20" 
                    type="text" value="<%= user.getLname() %>">
          <%--METADATA type="DynamicData" endspan--%></TD>
          </TR>
          <TR>

<TD class="head">Edit User Information</TD>
      ........         
      <jsp:useBean id="user" class="com.goforit.user.UserDataBean" scope="session">
      </jsp:useBean>
      ........    
      <TD class="subhead">Please update the following information as required:</TD>
      ........ 
      <FORM action="/goforit/UpdateUserProfileServlet" 
           method="POST" onsubmit="return checkForm(this);"> 
      ........  
     
            <TD width="375" align="right">First Name:</TD>
            <TD>
            <%--METADATA type="DynamicData" startspan
                <INPUT size="20" type="text" maxlength="25" name="firstName" 
                   valueproperty="user.fname" dynamicelement>--%>
                <INPUT maxlength="25" name="firstName" size="20" 
                   type="text" value="<%= user.getFname() %>">
            <%--METADATA type="DynamicData" endspan--%>
            </TD>
          </TR>
          <TR>
            <TD width="375" align="right">Last Name:</TD>
            <TD>
            <%--METADATA type="DynamicData" startspan
                <INPUT size="20" type="text" maxlength="30" name="lastName" 
                    valueproperty="user.lname" dynamicelement>--%>
                <INPUT maxlength="30" name="lastName" size="20" 
                    type="text" value="<%= user.getLname() %>">
          <%--METADATA type="DynamicData" endspan--%></TD>
          </TR>
          <TR>


Conclusion

Using client-side beans in our architecture helped us design our components independent of each other. They also turned out to be easy to implement, and come in very handy when we needed to pass data around the application. They help decouple our application logic from the data, so when we add or change user fields all we need to do is change UserDataBean and the corresponding User EJB; none of the servlet logic needs to change. Using client-side beans allows for localized changes, and that's always a good thing.


Stay Tuned...

Watch for our next installment of the Go-ForIt chronicles, where we'll cover View Beans, which offer a way to encapsulate a Web application's presentation logic. To see the previous articles in our tale of dragon slaying, go to our overview


Resources

About the author

Sandeep Desai is an e-business Architect in IBM's Developer Relations Technical Consulting group in Austin, Texas. He works with IBM's Business partners -- small or large companies, from startups to large firms, helping them get excited, evangelized, educated, and enabled on IBM's e-business platform. Sandeep holds the following technical certifications, among others: IBM Certified e-business Solution Advisor, IBM Certified e-business Solution Designer, IBM Certified e-business Solution Technologist, IBM Certified Specialist -- WebSphere Application Server, IBM Certified Systems Expert -- WebSphere Application Server. You can reach him at sandeep@us.ibm.com

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


Rate this article

Comments

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Sample IT projects
ArticleID=10081
ArticleTitle=The Go-ForIt Chronicles: Memoirs of eXtreme DragonSlayers, Part 4
publish-date=07012001
author1-email=sandeep@us.ibm.com
author1-email-cc=

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

For articles in technology zones (such as Java technology, Linux, Open source, XML), Popular tags shows the top tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), Popular tags shows the top tags for just that product zone.

For articles in technology zones (such as Java technology, Linux, Open source, XML), My tags shows your tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), My tags shows your tags for just that product zone.

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).