YOUR FEEDBACK
Gregor Rosenauer wrote: well, not what's your take on this? Did I miss a second page of this article or...

SYS-CON.TV
TOP MICROSOFT .NET LINKS


Serving Multiple Platforms
Refactoring Logidex for .NET

With the release of Microsoft's .NET Framework and associated development tools in the fall of 2001, LogicLibrary saw a unique opportunity to expand market share by producing a fully .NET-compliant version of our Logidex solution designed to install seamlessly in Microsoft IT shops.

Logidex is an enterprise cataloging system for software development assets - Web services, components, patterns, and other key building blocks of application development - that provides extensive search and maintenance capabilities. It supports a thin-client interface as well as tightly integrated client-side IDE add-ins via a SOAP interface. Logidex was originally designed and implemented in a J2EE environment following a conventional three-tiered architecture.

Our goal for producing a .NET version of Logidex was to minimize time-to-market and ongoing maintenance overhead by using as much of our existing design and code as possible in the .NET product. A one-time migration from J2EE to .NET wasn't the answer for us. We wanted to preserve as much of our existing code base as possible so that we could more easily release future versions of Logidex on both platforms.

Logidex in Detail
Logidex is architected as a three-tiered application consisting of a data management tier, an application tier, and a presentation tier (see Figure 1).

 

Data Management Tier
The data management tier consists of a relational database supporting standard SQL queries and a programmatic interface through which the business logic in the application tier stores and retrieves data.

Application Tier
The application tier holds the business logic of the application and is made up of stateless components (stateless session beans, in J2EE terminology) with underlying object-oriented implementations.

Presentation Tier
The presentation tier of the application consists of the Web pages of the thin-client application and their supporting logic. The presentation tier also contains logic that presents the objects of the application tier as a set of SOAP services.

Additional Components
The architecture includes three additional elements, components that Logidex uses to provide standardized packages of functionality. These components are reusable in the sense that we did not write them, and other applications consume them in essentially the same form as Logidex does. They are also pluggable in the sense that different implementations of the component's functions can be adapted for use. These components provide functionality for discussion groups, e-mail, and user authentication.

How We Did It
Java and J#
Microsoft provides two major migration enablers for Java-based applications: the Java Language Conversion Assistant (JLCA) tool and the J# language. The JLCA tool is useful in performing a one-time conversion of Java source code to C# code. We were told to expect a 70-80% automated conversion rate, with the remaining code having to be manually migrated. Given our goal of preserving as much common code as possible, this approach was not practical for us, as it would result in two entirely separate code bases requiring ongoing dual maintenance.

Instead, we turned to the J# language. The J# compiler for .NET will compile Java source code directly into MSIL bytecodes. The J# compiler is not picky about file extensions and will parse files with the ".java" extension. The catch is that J# supports Java source only through JDK version 1.1.4. Given this limitation, our first step was to find places in our existing Java source where we had dependencies on post-JDK 1.1.4 features. This was easily accomplished by running the Java source through the J# compiler. In many cases, the dependencies on newer Java features were superficial and easily reimplemented to be J# compliant. In other cases, there was no straightforward equivalent to the feature in the J# language. To address these cases we applied the "Abstract Factory" design pattern (see Design Patterns: Elements of Reusable Object-Oriented Software, by Erich Gamma et al., from Addison-Wesley) to provide platform-specific implementations.

Using the Factory Pattern
The Abstract Factory pattern calls for the introduction of an abstract base class defining methods that provide the required functionality. A subclass is provided for each platform with unique implementations of the inherited base class methods. A static "factory method" is placed in the base class, allowing clients to request an object supporting the base class interface. The factory method instantiates the appropriate subclass based on a static configuration attribute, as shown in Figure 2. The Java subclass exists only in the Java product and can freely use post-JDK 1.1.4 features in its implementation. The .NET subclass exists only in the .NET product and is free to make use of the .NET Framework's standard library of classes.

 

Listing 1 shows the Java/J# source for the CommonUtils base class. (The code referenced in this article can be downloaded from www.sys-con.com/ dotnet/sourcec.cfm.) Note the use of caching in the Factory method. Use of the CommonUtils class by clients is straightforward:

InputStream resourceStream = CommonUtils.create().getResourceAsStream(systemId);

The Factory pattern approach allows us to encapsulate language-specific code, thus minimizing the impact to calling code and maximizing the source code that is shared between the two products.

Session Beans and Components
The J2EE edition of Logidex uses stateless session beans to provide a clean partitioning between major business logic components, allowing for remote access and automated management of transactions. We found that COM+ ServicedComponents provide similar semantics in the .NET environment.

In order to isolate calling code from the specifics of the component model being used, we again applied the Abstract Factory pattern, as shown in Figure 3.

 

The methods on each session bean's remote interface were defined in an abstract interface. Platform-specific classes were provided that implement the abstract interface. These classes use another common pattern, called the Adapter pattern, and serve as delegates to the actual components, with their method implementations accessing the associated component and calling through to the corresponding component method. Calling code was converted to go through the appropriate factory method and adapter rather than accessing the components directly. With this approach, we were able to move the implementation logic from the components themselves into simple shared Java/J# classes. The remaining platform-specific code is simple call-through logic that delegates to the shared implementation classes.

Earlier, we described how the J2EE edition of Logidex relies on three standardized components for discussion group, e-mail, and user authentication support. Because Logidex defines abstract interfaces for these components, it was possible for us to use the Abstract Factory pattern again to substitute ASP.NET Forums for the discussion group component, System.web. mail for the e-mail component, and ActiveDirectory for the user authentication component.

Accessing the Data
The J2EE version of Logidex relies on Java's JDBC support to provide an interface to the underlying relational database. The JDBC interface consists primarily of a Connection class that encapsulates a specific database connection, a Statement class used for issuing queries and commands to the database, and a ResultSet to hold query results. Because Logidex can optionally assign internal "libraries" of software assets to different database connections, we also introduced our own ConnectionFactory class to create connections specific to a particular library.

Although J# supports an older version of JDBC, we found that this version did not support the concept of DataSources, which Logidex requires to encapsulate the specifics of database connections. In general, J# with JDBC is quite limited compared to Microsoft's ADO.NET. We introduced a simple database abstraction that allows Logidex to run with either JDBC or ADO.NET as the underlying database access technology. The classes that make up this abstraction are shown in Figure 4. It should be clear from the diagram that the familiar Abstract Factory pattern is again present.

 

Query Language
Since the J2EE edition of Logidex supports multiple RDB vendors, we had already ensured that all queries were ANSI SQL99-compliant. Since SQLServer supports SQL99 syntax, the only remaining issue was that of encoding parameters in query strings. JDBC uses a convention of encoding query parameters with the "?" character, while ADO.NET expects parameters to be encoded as incrementing digits. We handled this by converting the parameter encoding on the fly as the query strings come through the ADOConnection object.

Presentation Elements
At about the same time that we began the initiative to produce a .NET version of Logidex, we were also in the process of refactoring Logidex's presentation logic around Struts, the J2EE open-source implementation of the Model, View, Controller pattern. It became clear that the design principles driving the Struts refactoring would allow us to achieve our objective of maximizing a single-source code base for the presentation layer as well.

The Struts Framework introduces a number of key elements that we must briefly describe and discuss in terms of .NET (see Figure 5).

 

The Struts ActionServlet recognizes requests for pages under its control. It locates the correct "Form Bean" and "Action Class." It sets the state of the Form Bean from the request parameters and passes control to the Action Class. Based on the results of this call, it forwards or redirects to another URL. The association among the incoming request URL, the Action Class, the Form Bean, and the resulting URL is configured in an XML file. For .NET, we implemented this mechanism in a controller class that hooks the "Page_Load" ASP.NET event.

Form Beans adapt application-tier objects to the framework. Because Form Beans implement the Bean pattern they can be manipulated using reflection. The controller sets the properties of the selected Form Bean using the parameters of the request it is processing. That is how the state of the system is updated to respond to user input. The pages retrieve the properties of the Form Bean to populate the Web page with content that reflects the current state of the system. Because of the design of the controller class and the page controls, Form Beans are platform independent.

Action Classes are primarily responsible for sequencing. They tell the controller the next URL to forward or redirect to. They also carry out any changes to the system state associated with the URL transition. Because of the design of the controller class, Action Classes are platform independent.

Typically, the controller forwards the incoming request to a URL that represents a page to display. In the Struts Framework, such a page is a JSP, which uses a set of "Custom Tags" to access the current state of the system through the Form Bean. The Struts Framework provides a set of Custom Tags that display, iterate, and test conditions using the state of the Form Bean. The .NET equivalent to a JSP is an ASP, and the .NET equivalent to a Custom Tag is the user-defined Control. We implemented a set of user-defined Controls equivalent to the Struts Custom Tags. In many cases, we were able to extend existing .NET Controls for this purpose.

Although each Logidex page has a platform-specific JSP and equivalent ASP file, because the page logic has been factored out to the Form Beans and Action Classes, the resulting JSP/ASPs are easily cross-ported. In theory, we could write a tool to generate one from the other, though we haven't found this step necessary yet. Factoring the layout details to a cascading style sheet serves to further simplify the JSP/ASP set.

Listing 2 is a sample from a typical Web page that shows which code is platform independent and which is specific to .NET. (The .NET-specific code is in bold.) The .NET controls (tagged as <app:...> elements) correspond to the Custom Tags provided by Struts.

SOAP
Logidex's J2EE edition uses Java's JAX-RPC support for SOAP communication. On the server side, JAX-RPC is configured to instantiate adapter classes that invoke the session beans that implement the Web service interface. Microsoft's built-in support for Web services in .NET provides equivalent functionality to JAX-RPC, allowing us to use the same component-based implementation approach. However, since the methods on the J2EE Web service adapters are required to extend the Remote interface, we had to provide an alternative set of adapter classes for the .NET product that do not have dependencies on Remote or RemoteException.

On the client side, both JAX-RPC and .NET provide the ability to generate strongly typed stub classes for invoking remote Web services. Since the generated stub classes have platform-specific dependencies, a factory/adapter approach was used to encapsulate the actual stub classes, thereby providing a platform-neutral client interface.

The lack of standardization and support for SOAP attachments was one difficult compatibility issue that we encountered. Logidex can upload files through its Web service API. JAX-RPC supports attachments but is implemented using MIME encoding. At the time we built our .NET product, .NET had no direct support for attachments. We worked around this by encoding binary data using base64 encoding and treating it as a parameter in the SOAP method call. With the recent introduction of the WS-Attachments standard, we anticipate being able to leverage standardized support for SOAP attachments as it becomes available on the J2EE and .NET platforms.

Conclusion
Our objective was to refactor Logidex in a way that would allow our team to deliver future Logidex versions to both the J2EE and .NET platforms with a minimum of busywork. At the same time, we had time and resource constraints on the delivery of the Logidex 3.0.NET edition. To address these multiple challenges, we decided that the best use of our resources was to refactor the product for multiplatform as opposed to porting it.

We spent about 40 person-months over the course of 11 months of real time on Logidex 3.0. The application and data tiers of the resulting application consist of 103,064 lines of platform-independent code, 20,025 lines of .NET-specific code, and 26,756 lines of J2EE-specific code. For the presentation tier, we wrote 16,108 lines of code to implement the Struts Framework on .NET. This enabled 63,955 lines of common logic. We dual-sourced 40,675 lines of ASP code and 60,490 lines of JSP code. Images, the cascading style sheet, and a small amount of HTML are common.

Most of the lessons we learned were positive. First and foremost, we believe that this exercise validated the original architecture of Logidex. Our application was already structured around clearly defined interfaces, used classical design patterns, and made use of componentization. This architecture allowed us to apply the Factory pattern very effectively and in many different parts of the product. Separating the logic behind the thin-client pages from the structure, as dictated by the Struts Framework, allowed us to leverage work done on difficult presentation logic problems, and it provided a framework for the architecture of the .NET Web application. Separating structure from layout with cascading style sheets allowed us to use JSPs and ASPs that were simple enough to be mechanically portable. SOAP provided a vehicle for adapting the application logic to client-side add-in components for both VS.NET and WSAD.

To experience a read-only version of Logidex for .NET, explore the MSDN Logidex .NET Library at http://lab.msdn.microsoft.com/logidex.

About Tim Graser
Tim Graser, business process architect at LogicLibrary, is responsible for the middle and database tiers of the Logidex application. His experience in object-oriented and component-based software design includes 10 years at IBM, where he held technical leadership positions in the SanFrancisco and WebSphere Business Component projects. Tim has been issued 12 U.S. software patents and is the coauthor of the book SanFrancisco Design Patterns: Blueprints for Business Software.

About Paul Tamminga
As a senior software engineer and team leader with LogicLibrary, Paul Tamminga is responsible for the architecture and implementation of the presentation layer of thin-client applications as well as the access and security logic for Logidex. Paul has been with LogicLibrary since its founding. Prior to joining LogicLibrary, he had a long and varied career at IBM, including assignments in Shop Floor Control Systems, Quality Assurance, AS400 development, and the SanFrancisco Object-Oriented Framework for business applications.

MICROSOFT .NET LATEST STORIES
At the end of this month, at its Professional Developers Conference, Microsoft intends to unveil something that CEO Steve Ballmer yesterday referred to as "Windows Cloud." Ballmer explained that "Just like Windows Server looked a lot like Windows but with new properties, new characteri...
Come see a no-slides, code-only presentation that starts with a blank directory and builds a data-driven, AJAX enabled, ASP.NET web application from scratch that implements common AJAX patterns with the rich set of AJAX Control Toolkit, accesses data with LINQ, and implements standards...
GigaSpaces Technologies and GoGrid have announced the availability of the GigaSpaces eXtreme Application Platform (XAP) on GoGrid's enterprise-grade cloud computing service for Windows and Linux. The two companies’ joint offering enables enterprises to migrate existing and new Java, ...
Many of today's (and tomorrow’s) development projects lend themselves nicely to RIA application patterns. Silverlight offers a compelling RIA development experience that works on Linux, the Mac and windows as well as all major browsers. With HD video, vector based graphics and a rich...
With all of the hype surrounding Cloud computing, Microsoft's upcoming Cloud OS and current efforts around Live Mesh, I thought I would take a trip on the WABAC machine to look at where it all started. Back when I was in junior high school, the best type of connectivity that I could ho...
SUBSCRIBE TO THE WORLD'S MOST POWERFUL NEWSLETTERS
SUBSCRIBE TO OUR RSS FEEDS & GET YOUR SYS-CON NEWS LIVE!
Click to Add our RSS Feeds to the Service of Your Choice:
Google Reader or Homepage Add to My Yahoo! Subscribe with Bloglines Subscribe in NewsGator Online
myFeedster Add to My AOL Subscribe in Rojo Add 'Hugg' to Newsburst from CNET News.com Kinja Digest View Additional SYS-CON Feeds
Publish Your Article! Please send it to editorial(at)sys-con.com!

Advertise on this site! Contact advertising(at)sys-con.com! 201 802-3021


SYS-CON FEATURED WHITEPAPERS

ADS BY GOOGLE
BREAKING NEWS FROM THE WIRES
Slalom Consulting, ranked one of the best consulting firms to work for in the United States by Consu...