A central assumption in this guide is that your existing applications are designed according to best practice recommendations for application design on each application’s host wenvironment, whether it is .NET Framework or J2EE. Unfortunately, this is not always the case, because many application design specifications have developed over time or even evolved from previous architectures. Additionally, application designs rarely include interoperability as a factor. However, you can still apply the interoperability strategies described in this chapter to an existing application even if the application does not follow architectural best practice, although this makes implementing interoperability more of a challenge.
Before describing implementing interoperability, it is important to review recommended application architecture for multi-tier applications in both .NET Framework and J2EE. For recommended practices for distributed and multi-tiered .NET Framework application architecture, see Application Architecture for .NET: Designing Applications and Services on MSDN (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/distapp.asp). Figure 6.1 is from this guide and represents the recommended best practice for .NET Framework application design.
Figure 6.1: .NET Framework application architecture best practice design
Sun also provides best practices for J2EE application architecture, but this design applies equally well to J2EE applications.
As Figure 6.1 shows, it is recommended best practice to divide multi-tiered applications into three logical layers:
Data (or Resource) tier
The following sections discuss the functions of the components within each tier and correlate them with the components implemented in both the .NET Framework and J2EE versions of XBikes.
For more details about each of the elements within the recommended application architecture, including best practices for implementing them, see Application Architecture for .NET: Designing Applications and Services on MSDN.
The Presentation tier contains the necessary elements to enable user interaction with the application. The components of this tier can make up different types of applications, including the following:
Web applications — ASP.NET or JSPs and servlets.
Desktop applications — Windows Forms or Java’s Swing or Abstract Windowing Toolkit (AWT).
Smart Clients — Such as Pocket PCs and mobile phones.
This chapter considers the Presentation tier as a Web application, although this may not always be the case. However, this choice does not affect the interoperability architecture strategies that you implement.
The Presentation tier can consist of two types of components:
User interface (UI) components
User interface process components
In its simplest form, the Presentation tier can contain UI components, such as an ASP.NET Web Form or a JSP Web page. These components are only responsible for rendering the UI and handling direct interaction with the user. For more complex user interactions, you can design UI process components to orchestrate the user interface elements and control the user interaction. UI process components are useful when the user interaction follows a predictable flow of steps, such as when a user starts a wizard to complete a task.
The Java version of XBikes implements its Presentation tier as a combination of JSPs and Struts. Struts is part of the Apache Jakarta Project and provides a flexible control layer based on standard Java technologies. It also gives you a framework to underpin the Presentation tier. While the JSPs and servlets act as UI components, Struts provides the functionality of UI process components.
The .NET Framework version of XBikes Presentation tier uses ASP.NET, implementing a number of ASP.NET Web Forms that allow the user to interact with the application. This interaction then causes the initiation of one or more of the six use cases. There are no UI process components in the .NET Framework Presentation tier.
The Business tier contains the necessary elements to implement the business logic and processing that the Presentation tier requests and consumes. Business tier components can then exchange data with the Data tier or any external services. Within the Business tier are programmatic elements that execute the business logic.
A Business tier can consist of the following elements:
In a simple Business tier implementation, business components encapsulate and implement the functionality of a particular task or use case. In J2EE, these are also referred to as use case components or commands.
You could implement these components as classes or methods in a .NET Framework component library, or as COM+ ServicedComponents in a .NET Framework application. In a J2EE application, these could be plain ordinary Java objects or Enterprise JavaBeans (EJB) session beans. A Presentation tier client can then call these Business tier objects synchronously or asynchronously.
Using separate business components to implement individual use cases enables you to separate the functions within the Business tier logic, allowing the updating of individual use cases without affecting the remainder of the application. This provides useful change protection and reduces the risk associated with making changes to production applications. Implementing business components for each use case also makes it easier for large software teams to collaborate when developing applications.
The Business tier of XBikes implements business components for each of the six use cases that the application supports. To keep consistent with the functionality they implement, both the .NET Framework and J2EE versions of XBikes refer to these components as use case commands. These commands take the corresponding use case names with the word “Command” as a suffix, as in the following examples:
Both versions of XBikes implement the use case business components through the Command design pattern, common in J2EE architectures. The developers of XBikes decided to use the Command design pattern in the .NET Framework version of XBikes to keep the interfaces for each use case consistent.
For more information about the Command design pattern, see Design Patterns: Elements of Reusable Object-Oriented Software, by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides (ISBN 0-201-63361-2).
The J2EE version of XBikes implements the use case commands as plain ordinary Java objects. The .NET Framework version of XBikes has separate .NET Framework classes for each use case. Each use case command implements a common IUseCaseCommand interface the developers defined as part of the Command pattern.
Business workflows are usually only a requirement if you have long-running transactions or procedures that involve multiple steps that need to be orchestrated. Typically, business workflows involve the use of an orchestration product such as Microsoft BizTalk Server. Other orchestration or workflow product vendors have equivalent products.
XBikes does not implement business workflows; it is only a demonstration application and does not require the additional functionality.
In multi-tier applications, data passes back and forth across the Application tiers. Business entities are objects that represent data within the application. Entities contain “snapshot” data, acting as an effective local cache of information. Other Business tier or Presentation tier elements can connect to business entities.
The data that business entities represent is typically not tied to a particular database table. A business entity usually incorporates a schema that is a de-normalization of the underlying database schemas. They can also represent data aggregated from many sources.
Chapter 3, “Interoperability Fundamentals,” described complex data types made up from simple data types and used to store information about a particular business object. An example was where you design a custom complex data type to represent data about a customer, named CustomerData. The object can store data such as the name, address, and zip code of a customer. This CustomerData object would be considered a business entity component when implemented within the architecture of a multi-tiered application.
There are many data formats that you can use for defining a business entity in both .NET Framework and J2EE. Common formats include the following:
An XML document.
DataSet (.NET Framework only).
Typed DataSet (.NET Framework only).
Entity beans (J2EE only).
A custom object with properties that map to data fields, and methods that perform data modifications through data access logic components, known as the Value Object pattern in J2EE applications.
Custom business entity components are not a mandatory part of all applications. Many solutions (especially ASP.NET applications and .NET Framework business components) do not use custom representations of business entities; instead they use datasets or XML documents because they provide all the required information and the development model is more task and document oriented rather than object-oriented.
Both versions of the XBikes application define the following business entities to represent the data that the six use cases require:
CustomerData — Contains data representing a customer.
CategoriesData — Contains data representing product categories.
ProductsData — Contains data representing store products.
OrderData — Contains data representing an order and its order details.
Deciding on a data format to represent the business entities in XBikes was one of the first tasks that the XBikes developers faced. As explained in Chapter 3, agreeing on a common data format for exchanging data across platforms is one of the fundamental requirements for implementing interoperability. There were several choices considered for the data formats on both the .NET Framework and J2EE versions of the application.
The ideal situation is where you develop both the .NET Framework and J2EE applications from scratch. Chapter 3 described how you could generate a custom data type object on each platform from a common XML Schema. The two environments could then exchange the serialized XML version of these objects. However, this situation rarely occurs.
The interoperability scenarios that Chapter 1 presents show a more realistic approach to interoperability projects, such as the following:
Integrating .NET Framework components at the Presentation tier.
Integrating .NET Framework components at the Business tier.
The first scenario integrates a new .NET Framework ASP.NET application on the Presentation tier that communicates with the existing J2EE Business tier. The second involves having an existing J2EE-based JSP and servlet Presentation tier communicate with a new .NET Framework Business tier. Both scenarios share the common feature in that a new .NET Framework application operates alongside an existing J2EE application.
Within these scenarios, there are factors that can make it difficult to agree on a common format for exchanging data between the platforms:
Lack of ability to modify or change the data types used in the existing application.
Application developers not able to work together or to establish a process for agreeing on a common data format.
Non-ideal data type mapping with common XML Schemas.
An example of the last case might be in .NET Framework, where using a dataset or typed dataset is recommended over a custom data type. This is because datasets provide richer functionality at the Presentation tier level where you can use data binding to populate a data grid with the contents of the dataset with very little code.
Based on these factors, the XBikes developers decided to use the data format best suited for the given platform in each version of XBikes. Hence each version of XBikes uses data types specific to the platform on which it is built. To exchange data between the .NET Framework and Java versions, some extra components (interoperability adapters and service interfaces) were necessary to convert the data types into a common format. This chapter discusses these components in a later section.
The J2EE version of XBikes uses custom Java classes to implement the four business entities. The developers implemented these custom Java classes using the Value Object design pattern. This design pattern is common in J2EE applications when implementing business entity components.
For more information about the Value Object pattern, see Core J2EE Patterns Best Practices and Design Strategies by Deepak Alur, Dan Malks, and John Crupi, (ISBN 0 13-064884-1).
The .NET Framework version of XBikes uses typed datasets to implement the four business entities. Typed datasets are a feature of ADO.NET. A typed ADO.NET dataset is a class with an associated XML Schema, rather than an untyped dataset that is a class and has no associated schema. The typed dataset class derives from a dataset class, which inherits all of the methods, events, and properties of a dataset. This allows your application to use some of the rich features provided by a dataset, such as data binding.
Additionally, a typed dataset provides strongly typed methods, events, and properties meaning you can access tables and columns by name, instead of iterating through collections. A typed dataset also incorporates table and column names into the statement completion feature of Visual Studio. This lets you create code that is easier to write and read. Additionally, with a typed dataset, you can catch type mismatch errors when compiling the code rather than at run time. Creating or modifying a typed dataset is a very easy process using the XML Schema designer in Visual Studio .NET 2003.
For these reasons, you are recommended to use typed datasets to implement business entity components in a .NET Framework application. For more information about implementing typed datasets in .NET Framework, see “Creating XML Schemas and Datasets” on MSDN.
While datasets and typed datasets are recommended for use within a .NET Framework application, it is generally not recommended that you use them to exchange data with Java applications. The main reason for this recommendation is because there is no equivalent data type in J2EE to which you can map a dataset. Also, while you can serialize datasets into XML format, this XML format is specific to the .NET Framework, so a J2EE client cannot understand how to properly de-serialize them.
In XBikes, the developers used Java collections on J2EE and typed datasets on .NET Framework. This decision requires the use of interoperability layers to enable the two platforms to exchange data.
However, you can use the typed dataset’s GetXML method to generate an XML document based on the schema associated with the typed dataset and containing data from the typed dataset. The typed dataset’s ReadXML method takes an XML document formatted according to the XML Schema associated with the typed dataset and populates the typed dataset with the contents of that document. Chapter 7 and 8 show how the developers used these methods to enable cross-platform data transfer in XBikes.
A service interface is a software element that handles mapping and transformation services to allow communication with a service, while also enforcing a process and a policy for communication. For example, you could have a service interface that exposes your business functionality as a Web service.
The .NET Application Architecture best practice design covered earlier in this chapter includes service interfaces as one of the elements in the Business tier. Service interfaces are useful if you plan to expose your business functionality as a service. They provide a client entry point that abstracts the implementation of your Business tier. They can also be extremely useful for implementing interoperability.
Most application architectures implement a service interface as a fa ade.
Service interfaces can also act as a gatekeeper to your business components, handling more complex tasks such as authentication, validation, or caching. However, service interfaces should not implement business logic. Using a service interface in this manner enables you to concentrate any policy related code, such as auditing or validations, into one place. A simple service interface that implements the Fa ade design pattern can act as a pass through class. This class then implements member methods that call each of the underlying business components directly, aggregating them into a single interface.
In the Web service example, you would expose your business functionality through a Web service service interface (WS service interface). The WS service interface then handles the implementation details of the Web service itself. However, your interoperability scenario may require you to expose your business functionality through different interoperability mechanisms, such as message queuing or .NET Remoting.
Your application may also need to expose its business functionality through different communication channels, which you should implement as a simple service interface or fa ade. This service interface then aggregates your underlying business components into a single interface. It also consolidates policy-related code so that you can reuse this code across multiple service interfaces that handle different interoperability mechanisms. A later section covers how you can use multiple service interfaces in interoperability scenarios.
Using the Fa ade design pattern to encapsulate Business tier functionality is a popular and recommended practice for J2EE applications. You can apply this pattern to both .NET Framework and J2EE applications to abstract multiple business components within a Business tier. The Fa ade design pattern provides a single client interface to access the Business tier functionality.
You may see references to fa ades that encapsulate business functionality as service fa ades.
You should implement a fa ade for a core set of business functionality that you want to expose as a single interface. A simple application may have one fa ade that encapsulates all of your core business functionality. Larger applications may contain multiple fa ades that expose different sets of business functionality.
For more information about the Fa ade design pattern, see Design Patterns: Elements of Reusable Object-Oriented Software.
Both the .NET Framework and J2EE versions of XBikes implement a business fa ade, named the business service fa ade, to encapsulate the functionality of the Business tier into a single interface. The business service fa ade provides an interface for the Presentation tier components at its front end redirecting calls from the JSP/Struts application in J2EE or the ASP.NET application in .NET Framework to the relevant use case command in the Business tier logic.
For example, in the J2EE version of XBikes, when the user logs on to the XBikes Web site, the JSP Presentation tier components make a call to the business service fa ade, which redirects the call to the AuthenticateCustomer use case command. The AuthenticateCustomer use case command then makes a call to the Data tier to check for the existence of the user’s log on name and to verify the password. The same application flow occurs when a user logs into the XBikes Web site of the .NET Framework version.
In the J2EE version of XBikes, the developers implemented the business service fa ade as an EJB session bean. Using an EJB to implement the business service fa ade provides additional enterprise functionality such as session state, caching, and object pooling. Calls to the business service fa ade session bean create calls to the underlying use case commands that are implemented as plain ordinary Java objects.
For details about how to implement a fa ade in J2EE, see the Session Fa ade design pattern in Core J2EE Patterns: Best Practices and Design Strategies.
In the .NET Framework version of XBikes, the developers implemented the business service fa ade as a COM+ ServicedComponent. This approach provides the benefits of the enterprise features of Windows Server Component Services such as just-in-time activation, object pooling, role-based security, and transactional support. The business service fa ade ServicedComponent makes calls into the underlying use case command classes which then run as part of the fa ade’s COM+ application process.
In XBikes, the developers implemented the business service fa ade as a ServicedComponent to demonstrate how to create a service fa ade in an enterprise-class application. However, XBikes uses COM+ for demonstration purposes only and does not use the additional features.
Almost all applications need to access or store data in some sort of data store or database. The Data Access Logic tier contains the elements necessary to access data from data sources and returns it to the Business tier. In Chapter 5, “Interoperability Technologies: Data Tier,” the section “Sharing Data between ADO.NET and JDBC” looked at implementing a Data Access Logic layer within your application in order to abstract the functionality accessing the Database from the Business tier. Abstracting your database access code from the Business tier is a recommended best practice for both .NET Framework and J2EE applications.
The Data Access Logic tier can contain the following elements:
Data Access Logic Components
Data Access Logic Service Fa ade
The next sections describe each of these elements.
Data Access Logic Components provide simple access to database functionality such as queries and data operations, and they return both simple and complex data structures. They hide invocation and format idiosyncrasies of the data store from the business components and user interfaces that consume them. Implementing your Data Access Logic in Data Access Logic Components allows you to encapsulate all the Data Access Logic for the entire application in a single, central location, making the application easier to maintain or extend.
Chapter 5 also described how the implementation of a Data Access Logic tier is different between .NET Framework and J2EE applications. J2EE applications use the Data Access Object (DAO) design pattern in conjunction with Java entity beans to implement components that encapsulate create, read, update and delete (CRUD) database operations for a particular business entity. In .NET Framework applications, Data Access Logic Components handle the CRUD operations for a particular business entity, possibly with the addition of database helper classes such as the Microsoft Data Access Application Block (DAAB) to handle direct communications with the database.
For simplicity, this book uses the term Data Access Logic Components from the .NET Framework architecture to refer to the J2EE entity bean components that implement the DAO design pattern.
While you implement Data Access Logic Components differently on each platform, the principles of this abstraction layer are similar for both platforms. In general, you should implement Data Access Logic Components to handle database operations for each business entity.
The Java version of XBikes implements five data access logic components using entity beans. Each of these entity beans contains the logic to call the individual areas within the SQL Server database. These five entity beans are the following:
An XML deployment descriptor provides the mapping between the entity beans and the SQL database tables. These deployment descriptors refer to a JNDI name for the database (XBikesDB).
The XBikes design uses Container Managed Persistence (CMP), so the Data Access Logic container handles all the SQL processing. This is in contrast to bean managed persistence (BMP), where the developer must write the SQL code. The container configuration contains the information to connect to SQL Server. The container passes this connection information, manages connection pooling and sends the native SQL call to the database to retrieve the necessary data.
The .NET Framework version of XBikes implements four data access logic components. These four components correspond to the four business entities defined in the XBikes application, as follows:
The Data Access Logic components in .NET Framework implement the interfaces necessary to perform CRUD operations on the business entities’ data. Chapter 5 covers how you can use the Microsoft-provided DAAB for .NET Framework to encapsulate all of the common code for accessing a database. The .NET Framework version of XBikes uses the DAAB to provide this encapsulation. Each of the Data Access Logic Components makes calls into the DAAB to access the database.
The Data Access Logic service fa ade handles calls from the use case commands in the Business tier and sends them to the Data Access Logic Components or entity beans in the Data Access Logic tier. For example, in the .NET Framework version, the Data Access Logic service fa ade passes calls from the GetCustomerOrders use case command to the OrderData Data Access Logic Component.
Implementing a fa ade for the Data Access Logic provides the equivalent functionality of implementing a fa ade in the Business tier. You can implement a Data Access Logic service fa ade to encapsulate the underlying Data Access Logic Components in the Data Access Logic tier into a single interface that business components in the Business tier can consume.
You should implement a Data Access Logic service fa ade for your Data Access Logic tier if you intend to expose your Data Access Logic tier as a service. In most applications, the business components within the Business tier call the Data Access Logic components directly. However, it is not as common to expose your Data tier functionality as a service as it is with the Business tier.
Both versions of the XBikes application implemented a Data Access Logic service fa ade to support the different interoperability scenarios. The J2EE version of XBikes implements the Data Access Logic service fa ade as an EJB session bean. The .NET Framework version of XBikes implements the Data Access Logic service fa ade as a regular .NET Framework component.
At the root of any application’s Data Access Logic tier is a database, normally relational in nature. The XBikes design uses SQL Server 2000 to implement the database for both the Java and .NET Framework versions. This sharing is possible because both the .NET Framework and J2EE version store their application data using the same database schema. Chapter 5 covered how you can share a database between applications built on different platforms.
Chapter 5 also looks at using message queuing services to implement interoperability. Normally, you use message queuing to implement asynchronous connectivity between components running in a single environment. Asynchronous connectivity is desirable when you have long running transactions, or portions of your application (particularly at the client end) that are not always online or available.
A good example of this scenario is when a user places an order at an online store. When the user places an order, there are a number of items that need processing and these items can take some time. Because orders directly affect the profitability of the Web site and can be long running, you need to be able to run the order process asynchronously, so that the user can continue with other operations while the order process checks stock levels, authorizes payment details, and (importantly) takes other orders.
In order to support these scenarios, you can implement asynchronous connectivity through message queuing. When a user places an order, it goes into a queue until the order processing application can receive it. In the meantime, the application that placed the order on the queue can continue operating without interruption.
Both versions of the XBikes applications implement asynchronous message queuing to support placing an order on the Web site. Although they differ in actual implementation, the basic concepts are similar. The PlaceOrder use case command in both the .NET Framework and J2EE Business tiers calls a message queue component which places OrderData message objects onto a queue.
While the XBikes applications implement message queuing to demonstrate asynchronous connectivity, they do not actually do any processing with the order and orders are simply placed onto a queue. Both applications have sample console applications that read order messages from a queue and insert the order into the database through the Data Access Logic tier.
The J2EE version of XBikes uses IBM WebSphere MQ for message queuing services. This design allows the developers to address the WebSphere MQ component either using the Java Message Service (JMS) API or through IBM’s WebSphere MQ API.
XBikes uses the JMS API.
The .NET Framework version of XBikes uses MSMQ for message queuing services. MSMQ provides the equivalent asynchronous support for the .NET Framework design.
This section provides a summary of the architecture of the two XBikes applications without considering the interoperability components. The composition of the three tiers of the XBikes application is as follows:
Presentation tier (JSP/Struts or ASP.NET)
Business tier, consisting of:
Business service fa ade
Business components that implement logic for the six use cases
Data tier, consisting of:
Data Access Logic service fa ade
Data Access Logic Components (five in the J2EE version, and four in the .NET Framework version)
The DAAB (.NET Framework version only)
SQL Server 2000 database
IBM WebSphere MQ Queue (J2EE) or MSMQ (.NET Framework)
Figure 6.2 shows the architecture of the .NET Framework version of XBikes.
Figure 6.2: Application architecture for .NET Framework version of XBikes
Compare this to Figure 6.3, which shows the architecture of the J2EE version.
Figure 6.3: Application architecture for J2EE version of XBikes
Figures 6.2 and 6.3 show how similar the application architectures are.
You can now link the architectural elements from the reference design to build up a table of component equivalence. Table 6.1 shows how the elements in the .NET Framework architectural best practice correspond with the components in both the .NET Framework and J2EE version of XBikes.
|.NET Framework Application Architecture||XBikes .NET Framework Implementation||XBikes J2EE Implementation||Comments|
|UI components/UI process components||ASP.NET client||JSP/Struts||No equivalent of UI process components|
|service interfaces||Business service fa ade (implemented as a serviced component)||Business service fa ade (implemented as an EJB session bean)||None|
|Business workflows||Not applicable||Not applicable||Business workflows not implemented due to application simplicity|
|Business components||Use case commands implemented as .NET Framework components||Use case commands implemented as session beans||None|
|Business entities||.NET Framework typed datasets||Custom Java objects (using Value Object design pattern)||None|
|Data Access Logic Components||Data Access Logic service fa ade Data Access Logic Components DAAB||DAO pattern Entity beans with CMP||None|
|Data sources||SQL Server||SQL Server||None|
There is not direct equivalence at all levels between the two architectures. However, there is broad functional and conceptual equivalence.
The next section looks at how to implement interoperability between Java and .NET Framework enterprise-class applications, with reference to the implementation of the two versions of XBikes.