In Part 1 of this two-part series, we introduced Microsoft .Net and J2EE (Java 2 Platform, Enterprise Edition) from the 30,000-foot level. In this article, in contrast, we actually implement a representative Web based application—the Ice Cold Beer Boutique (ICBB)—in both J2EE and .Net. To do so, we evaluate the presentation, business, and data tiers for both technologies, looking at common services such as exception handling, caching, and configuration, as well as the technologies' tool support. We then bring it all together to implement the sample business application. We finish by discussing the future for both .Net and J2EE.

Read the whole "Rumble in the Jungle: J2EE Versus .Net" series:

Note: Download this article's sample source code from Resources.

Web application overview

For the Ice Cold Beer Boutique application, which Sheil introduced in "To EJB, or Not to EJB?" (JavaWorld, December 2001), we chose a problem interesting enough to be nontrivial, yet simple enough to ensure that we can clearly show each technologies' features and deficits. With that in mind, what should the ICBB application accomplish?

The Ice Cold Beer Boutique

ICBB, a business-to-business (B2B) company that sells premium beverages to resellers in Europe and the US, wants to reduce costs and order turnaround time by allowing resellers to create orders on a secure Website. The IT strategy calls for incrementally building up the site as demand increases.

The application's first release must:

  • Be secure by allowing only authorized visitors access the ICBB Website
  • Be easy to use; ICBB's CEO intends to test this feature himself
  • Allow resellers to view all currently stocked beverage types and prices
  • Allow an ICBB system administrator to update the details for a beverage type
  • Allow an ICBB system administrator to delete a beverage product

The second release, building on that functionality, will allow resellers to create orders and schedule them for shipment. Eventually, ICBB will integrate its Web store with its enterprise resource planning (ERP) system Sales order Processing module so sales invoices can be raised automatically and stock information updated.

Our goal: Produce an application using a technology and design that meets these immediate requirements and admits constant enhancements as the system expands.

Application structure

We implement a thin slice of the overall application, so you can see how the application layers communicate together. Figure 1 shows the distinct HTML pages planned for the system and how they hang together. All pages apart from the Welcome and Login pages are secure; only authenticated users can access them.

Figure 1. The system HTML pages in relation to each other, for both J2EE and .Net implementations. Click on thumbnail to view full-size image.

J2EE notes

Let's see how to design the ICBB application as a J2EE application, then look at the reasons behind the important J2EE-based implementation decisions. Figure 2 illustrates how the ICBB sample application looks when implemented with J2EE.

Figure 2. The ICBB schematic as implemented with J2EE. Click on thumbnail to view full-size image.

The presentation tier

Unlike .Net, with J2EE you can employ a number of free frameworks to help build an application. That's both good and bad: While I have freedom of choice, I may choose the wrong tool. For example, with Web frameworks, I can choose to build my own or choose between Struts, WebWork, Velocity, Turbine—jeez! Which one is the right one? It depends on the task at hand!

For our ICBB example, I chose the Jakarta Project's Struts Web framework as it is arguably the most deployed Web framework in the J2EE world. Such wide deployment means that more developers know Struts than any other framework, Struts boasts a large and stable developer community, all the major application servers support Struts, and documentation/support is easy to come by. In short, you can expect Struts to be a long-lived Web application framework.

When using Struts, the system JSPs (JavaServer Pages) handle only data formatting and presentation. The pages themselves remain as simple as possible by using Jakarta Project standard tag libraries. These tag libraries require JSP 1.2 specification support, contained in all J2EE 1.3-compliant servers.

With tag libraries, Java code exists away from the JSPs, making the pages much easier to read and maintain. In addition, with tag libraries you can more easily change the JSPs' look and feel.

Business and data tiers

I implement the business and data tiers as one unit using stateless session beans called the ProductManager and CategoryManager. These session beans retrieve requested products and categories from the database, delete products, and apply changes made to products by an ICBB system administrator. They also update the database using straight SQL executed as Java Database Connectivity (JDBC) code. SQL statements execute as PreparedStatement objects to allow JDBC drivers to optimize them as cacheable statements in the database wherever possible.

In a more complex system, I would split the ProductManager between session beans for business functionality and entity beans for persistence, but the business case for ICBB simply doesn't warrant that approach—yet. Looking forward, I could easily extend the ProductManager session bean to delegate persistence to a separate persistence object(s).

Further, container managed transactions provide the system with transactional capability. Each business method invoked on the ProductManager class executes with a Required transaction attribute, and the Enterprise JavaBean (EJB) container manages the in-depth transaction management details.

Common services

Any serious enterprise computing platform must do the simple things well. In this section, we examine the most common bread and butter tasks in enterprise application development and how the J2EE-based ICBB sample application meets the following needs:

  • Exception handling: ICBBException indicates when an unexpected error occurs. ICBBExceptions are logged at the source to aid finding and fixing the underlying cause.

    In the presentation tier, JSPs provide specific error-handling support through the <%@ page isErrorPage="true" %> attribute in the page directive. JSPs with that tag act as error handlers for other JSPs for use in application-wide error reporting and handling. See ExceptionHandler.jsp for a concrete example.

  • Logging: The code base uses the log4j logging library in conjunction with the Logger wrapper class to provide a library-independent logging system view. Log4j supports multiple destinations for logging information, including flat file, XML output, console and socket output, and even the Windows Event logger. In contrast to .Net, no explicit distinction exists between logging and trace output in J2EE, although your chosen server vendor may employ nonstandard features to provide trace information. Like .Net, the logging level can vary dynamically to aid debugging production systems while minimizing the overall impact on performance.
  • Configuration: Server-side components such as servlets and EJBs can also store configuration information outside code via the web.xml and ejb-jar.xml files. The ServletConfig for servlets and the "java:comp/env" JNDI (Java Naming and Directory Interface) naming context for EJBs enable access to that configuration information.
  • Authentication: The servlet container's built-in capabilities handle user authentication based on users' established roles. By simply setting up protected resources in a declarative fashion, we can hand off the authorization and authentication responsibilities to the servlet container. See the etc/web.xml file for more details on this functionality (specifically the <security-role>, <login-config>, and <security-constraint> tags).
  • Authorization: The J2EE specification strongly supports both declarative and programmatic security through APIs and XML configuration files. The ICBB application includes two roles: reseller and admin. J2EE's declarative security features prevent nonadmin users from editing products, while its programmatic features control what a user sees on a particular JSP based on his or her current role.
  • Session management: The servlet/JSP specifications' session management support lets developers create sessions and track users either through cookies or URL rewriting, while both JSPs and servlets can access the HttpSession object. The servlet container can invalidate these HTTP sessions automatically after a specified time-out period or programmatically (by calling the session.invalidate() method).

J2EE tools

As with application servers, J2EE developers can choose among a wide range of free and commercial tools to enhance their productivity. My favorites include:

  • Ant (free): The standard build tool for compiling, packaging, and deploying Java-based software.
  • JUnit (free): A simple, easy-to-use unit testing framework for Java.
  • xdoclet (free): Use custom Javadoc tags to generate code, XML, and so on from Java source code. I used xdoclet to generate some of the code and deployment descriptors for ICBB J2EE solution.
  • Eclipse (free): A good Java IDE (integrated development environment). Achieves native code performance in Java! Supports debugging via the Java Platform Debugging Architecture (JPDA), including debugging server-side components, plus productivity features such as smart coding help, Ant and JUnit integration, some source-code management integration, refactoring, and more.
  • IntelliJ (commercial): Another good Java IDE. Also provides debugging support through the JPDA, plus useful productivity features such as smart coding help, Ant and JUnit integration, source-code management integration, and refactoring.

(For more information on the most popular Java-based development tools at present, read Jennifer Orr's "Java's Top Guns," (JavaWorld, March 2002) which honors the leading Java technologies in the JavaWorld 2002 Editors' Choice Awards.)

Build and test the application

For detailed instructions on how to set up the J2EE-based ICBB application, read the INSTALL.txt file included with the download pack.

Application server selection and portability

I chose IronFlare's Orion application server to run the J2EE-based ICBB application. Orion boasts a small download size, supports the standard J2EE specifications, and is easy to set up and develop on. Orion also supports application hot deployment and is 100% Pure Java, so it runs on any platform with a JDK.

You can choose from numerous alternatives, such as JBoss, BEA WebLogic, or IBM WebSphere. For me, Orion's ease of use, size, and speed make it a good choice for this project. If you want to deploy the application on other application servers, feel free. I used xdoclet to generate the server-specific pieces, such as the deployment descriptors, easing the porting process. In addition, I used no proprietary Orion features to build the sample application.

Data validation

Since the J2EE-based ICBB implementation uses Struts, I can hand off most of the data validation work to Strut's behind-the-scenes code. For each HTML form from which I want to update the system, I define a class that extends ActionForm, such as EditForm. Then I implement the validate method to handle whatever necessary validation before the associated Struts Action fires. Note that the data validation is server-side; to enforce client-side validation of particular fields, I would have used the Jakarta Project's Validate tag.

Caching strategies

For Web applications, caching refers to the storing and reuse of previously constructed HTML fragments or retrieved objects to reduce the overall response time to users. The resulting performance gain can mean the difference between a successful application and a slow application that frustrates its user base. So, then, how do we handle caching in the J2EE-based ICBB application?

  • Page caching: Unlike .Net, in J2EE caching generated HTML does not typically fall under the J2EE developer/administrator's control. Rather, the JSP/servlet container controls page caching under the covers as it sees fit. That lets JSP developers focus on constructing the JSP without worrying about explicitly managing caching policies or enforcing them.

    However, in the spirit of flexibility, an open source JSP tag library from OpenSymphony lets JSP developers control JSP caching. In addition, vendors such as BEA also support JSP caching, albeit in a proprietary fashion.

  • Data caching: J2EE's data-caching strategy depends on the data access strategy in use. EJB 2.0-compliant containers provide advanced caching strategies. Vendors, moreover, compete on the strength of their implementation/interpretation of the baseline EJB 2.0 specification. With more mature J2EE offerings, developers can use transactions directly against a cache, safe in the knowledge that the cache provider ensures the database remains consistent.

.Net notes

Now that Sheil has explained how he proposes to implement the ICBB application with J2EE, let's see how Monteiro will build the same application with .Net.

Figure 3 illustrates how the ICBB sample application looks when implemented on .Net.

Page 2 of 3
Figure 3. The ICBB schematic when implemented with .Net. Click on thumbnail to view full-size image.

Presentation tier

The ICBB presentation tier contains numerous Webpages, each comprising an ASPX page and code-behind. The ASPX page represents the UI (user interface); it contains HTML and custom tags that correspond to ASP.Net Web controls. The code-behind represents the behavior behind the UI; it contains the page class's definition.

Create the UI by dragging ASP.Net Web controls onto ASPX pages using the Visual Studio.Net designer. After that, you code event handlers contained in the ASPX page's code-behind. That physical separation disentangles the UI from the behavior associated with the UI, similar to how J2EE allows developers to use tag libraries to simplify JSPs.

For example, the Login page code-behind contains an event handler to handle the Login button's click event. When the user clicks the Login button, ASP.Net calls the appropriate event handler defined in the ASPX page's code-behind. Using such an event-driven programming model improves productivity because most developers can readily understand it.

Web controls also improve productivity by providing advanced features not found in standard HTML controls. For example, each control can automatically maintain its state from one roundtrip to another. When pages change, you don't need to repopulate the category ListBox between requests because the ListBox Web control can maintain its state. That simplifies Web programming and improves performance by eliminating the need to reretrieve the product categories from the database.

Another important feature: You can access form data in an object-oriented way. Instead of getting form data from a key/value collection, developers access type-safe properties on Web controls declared in the ASPX page's code-behind. For example, you can access the selected category from the ListBox control on the Product List page via ListBox.SelectedItem.Value.

Business and data tiers

As with the J2EE version, the .Net-based ICBB application relies on a single business/data tier because no significant business functionality exists beyond data access. The single tier, again like the J2EE version, contains a stateless ProductManager class responsible for retrieving, deleting, and updating products.

To retrieve products, the ProductManager's GetProducts() method calls a stored procedure using ADO.Net classes. While GetProducts() could call inline SQL, I've designed it to call a stored procedure to improve performance and security.

To update a product, the ProductManager's SaveProduct() method also calls a stored procedure to save the product updates to the database.

For transactions, recall from Part 1 that the Common Language Runtime (CLR) supports both manual and automatic transactions. Automatic transactions are easier to program, but they don't perform as well as manual transactions.

Since the ICBB application need not support distributed transactions, I selected manual transactions. (Refer to the ProductManger.SaveProduct() method in the source code.)

Common services

Next, let's revisit a number of bread-and-butter tasks needed in enterprise application development to see how .Net supports them:

  • Exception handling: In Web-based applications, users will appreciate being redirected to a user-friendly error page when they encounter an unexpected error. To accomplish that goal in the ICBB .Net application, I configured ASP.Net to redirect to a specific error page (Error.aspx, for example) when an unhandled exception throws. See the <customErrors> in the web.config file to see how this is done.
  • Logging: In .Net, .Net Framework classes Trace and Debug handle logging. With the Debug class, you can print debugging information and check program logic with assertions without affecting the shipping product's performance or size because no executable code generates for Debug methods when doing a release-build.

    To instrument release-builds, use the Trace class. Unlike the Debug class, code generates for Trace methods for debug and release-builds. In addition, you can generate trace information related to the HTTP request by adding Trace="true" to the @Page directive (see ProductList.aspx). To view the trace output, developers use a special HTTP handler provided by ASP.Net (http://localhost/ICBB/trace.axd).

  • Configuration: ASP.Net reads configuration information from the web.config XML file. If any settings within this file change, ASP.Net automatically reloads the configuration information in memory without restarting the Web server. In addition to the ASP.Net settings, you can add your own application-specific application settings in the form of key/value pairs, such as a database connection string. You can then access the configuration information using a standard API in the .Net Framework.

    In the ICBB application, the ConfigurationSettings.AppSettings class reads the application's database connection string from the web.config file.

  • Authentication: ASP.Net supports several authentication schemes, including Windows-, Passport-, and Forms-based, to control access to Webpages. For ICBB, I chose Forms-based authentication to avoid creating separate Windows accounts for each user and relying on Microsoft's Passport service.

    With Forms-based authentication, ASP.Net automatically redirects unauthenticated users to a custom login page. The user then provides credentials as a username and password. If the user's credentials prove valid, ASP.Net issues an authentication cookie that allows the user to access parts of the site that require authentication. Note that ASP.Net entirely handles the redirection and cookie management. The developer merely validates the user's credentials.

    Check out the web.config file's <authentication> tag to see how I configured authentication.

  • Authorization: Once a user has been authenticated, you next determine what he or she is allowed to do. For example, in the ICBB application, only administrators should see the Product List page's Edit and Delete buttons. For everyone else, those buttons should be hidden. In addition, only administrators can save products; therefore, you should restrict nonadministrators from calling the ProductManager.SaveProduct() method.

    To solve the first problem, hide the Edit and Delete buttons via programmatic security checks contained in the Product List code-behind. These checks call the current principle object's IsInRole() method. In the ICBB application, the principal represents the authenticated user logged in to the system. Solve the second problem via CLR-enforced declarative security checks. In the ICBB application, a PrincipalPermissionAttribute ensures only administrators call the ProductManager.SaveProduct() method.

  • Session Management: ASP.Net, like its JSP counterpart, strongly supports session state management through an intuitive API; developers access session state via a session object (for example, Session["name"]). Similarly, ASP.Net can use cookies or URL rewriting (if cookies are unavailable) to locate the user's session state. You can also configure ASP.Net (via the web.config file) to store session state on a separate server, eliminating the need for sticky sessions in a Web-farm scenario.

    For the ICBB application, because the username appears on several pages throughout the application, session state holds the authenticated user's name.

.Net tools

You can build a .Net application using your favorite text editor and the appropriate .Net-language compiler. I advise against that choice, however, except for the simplest applications. You'd give up many productivity-enhancing features provided by Visual Studio.Net. For example, when you drag an ASP.Net control onto a Web form, Visual Studio.Net adds the appropriate tags to the ASPX page and generates code in the corresponding code-behind for that control. When you double-click the control within the designer, Visual Studio.Net generates an event handler in the code-behind class to handle the default event (for example, the clicked event for a button). The idea is to let Visual Studio.Net take care of the plumbing while the developer focuses on the business problems.

In addition to Visual Studio.Net, a number of tools address other parts of the software development problem. Here's a partial list:

  • NAnt: A free .Net build tool for compiling, packaging, and deploying .Net applications
  • NUnit: A free framework for writing repeatable tests in any .Net language
  • NDoc: A free documentation-generation tool for C# developers

Build the application

For detailed instructions on how to set up the .Net-based ICBB application, read the INSTALL.txt in the integrated download.

Application server selection and portability

When talking about application servers, you cannot easily draw a parallel between J2EE and .Net because the lines between Web servers, application servers, and operating systems are becoming increasingly blurry. In the .Net world, no product called an application server exists. Instead, many of the enterprise services an application server provides, such as distributed transaction management and object pooling, are embedded within Windows 2000 Server.

Data validation

Validating user input is a common requirement, yet one that's tedious to implement, especially when the validation must happen on the client using JavaScript and on the server. The task is further complicated by the difference in JavaScript support across browsers. Suddenly a seemingly trivial task has become a big headache.

Enter ASP.Net with its array of validation controls including required field, range, compare, and regular expression controls (developers can even write custom validation controls if one of the prebuilt controls does not suit their needs). Instead of writing client- and server-side validation logic for each input control, you tie one or more validation control to each input control using design-time properties. When a user submits a page, each validation control checks to see if the data its responsible for passes muster. If not, an error message displays on the Webpage. The validation controls and detects the requesting browser's capabilities, letting you focus on the business problem rather than worry about technical details.

In the .Net-based ICBB application, validation controls validate user input on the Edit Product page (EditProduct.aspx).

Caching strategies

Recall that for Web applications, caching stores previously constructed HTML fragments or retrieved objects to reduce the overall response time to users. With that in mind, let's examine .Net's built-in caching support:

  • Page caching: Rather than recreating dynamic pages with each request, ASP.Net can cache entire pages or parts of a page, thereby increasing scalability by reducing the server load. Microsoft calls this kind of caching dynamic output caching.

    Output caching works well for pages whose underlying content rarely changes or for those pages not requiring up-to-the-minute data synchronization, but what about pages whose content varies from one request to the next? For example, a search page shows a different result set based on the search criteria selected. ASP.Net solves the problem by varying the cached output by a set of parameters such as the query string. If the parameter value changes, ASP.Net caches a new copy of the output.

    In the ICBB application, output caching has been enabled on the Welcome page via an @OutputCache directive included in the ASPX page. To see the output cache in action, try refreshing the Welcome page. Notice how often the timestamp on the page updates.

  • Data caching: In classic ASP, developers often used the Application object to cache frequently requested but infrequently changing data. That works great until the underlying data changes. The .Net Framework solves the problem by providing a Cache object that behaves much like the Application object with a few added benefits, such as the ability to remove items from the cache when some dependency changes (for example, a file on disk).

    In the ICBB application, the ProductManager.GetCategories() method caches the product categories in the Cache with a timestamp dependency. The Cache object then evicts the data when the data expires. You can also evict cached data based on an update to the database.

And the winner is ...

Well, there you have it. Our two-part series has culminated in the building of the same Web-based application with both J2EE and .Net technologies.

Well, the rumble didn't turn out to be much of a rumble at all! .Net and J2EE are both here to stay. .Net will capture all current Microsoft developers, but will not receive waves of converts from the Java/J2EE community as reported elsewhere. Why not?

Because the two technology stacks serve different masters. .Net is Microsoft's solution for the Microsoft OS and Intel platform combination and will flourish there. .Net cannot run on non-Microsoft platforms. In contrast, J2EE's two lynchpins are open standards and cross-platform portability, enabled through the Java programming language and platform.

At any point in time, either camp can and will claim to have a better toolset, lower total ownership costs, better performance, and even better-looking developers! But those temporary circumstances will last for no more than three to six months on either side. In general, if you are investing in either J2EE or .Net right now, it's a safe bet. Disappointing conclusion? Well write us and disagree—we value reasoned debate!

Page 3 of 3
Humphrey Sheil, a Sun-certified Java architect with Cedar Enterprise Solutions, has worked on more than 25 enterprise Java projects in Europe and the US, from initial scoping right through to going live. He also researches the parallelization of neural network algorithms for compute clusters at University College in Dublin, Ireland. Michael Monteiro is a technical specialist at Sapient, a leading business and technology consultancy that helps Global 2000 clients achieve measurable business results through the rapid application and support of advanced technology. He has more than eight years of experience delivering mission-critical applications, many of which use Microsoft technologies. As a .Net early adopter, he has spent the last year working closely with .Net and with Microsoft. In his current role, he is part of a team providing .Net architectural guidance to Sapient.

Learn more about this topic