Java EE and .NET Interoperability: Integration Strategies, Patterns, and Best Practices

Chapters 1, "Java EE Platform Interoperability Essentials," and Chapter 2, ".NET Platform Interoperability Essentials," covered the essentials of Java and .NET technologies and how they enable interoperability. Subsequent chapters (Chapters 3 through 12) introduced different integration and interoperability technologies. This section assesses what these integration and interoperability technologies can do and cannot do to make reliable, available, and scalable business applications.

Reliability

There are two essential reliability requirements that developers are concerned with. First, the service requests are reliably sent to the target recipient. Similarly, the processing results are reliably returned to the service requester. Second, the business data from one system should be accurately transmitted and delivered to another system without loss. This section discusses the current states of messaging interoperability technologies and how data types should be mapped between Java and .NET platforms.

JMS and MSMQ

Messaging technologies such as JMS and MSMQ are designed to allow business applications to exchange business data reliably. However, these messaging technologies are vendor-specific (they have different underlying data transport implementations), and they are not practically interoperable between two different vendor implementations. There may be a misunderstanding that both JMS and MSMQ are message queue-based technologies, and they can interoperate if a common queue name is used. Developers should not assume that a Java application using JMS can interoperate directly with a .NET application using MSMQ. For example, business data written to a JMS queue using Weblogic JMS implementation cannot be retrieved by using IBM WebSphere MQ JMS API or MSMQ because they use different underlying data transport and data formats.

MSMQ Interoperability

MSMQ is a reliable messaging mechanism available in the .NET platform. It is possible to wrap a WebSphere MQ client (or JMS client, architecturally speaking) by ActiveX Control, so that a WebSphere MQ client (which is a Java application) can exchange business data reliably with a MSMQ client (.NET application). In the case of WebSphere MQ, IBM provides MQ classes for .NET, which allows a .NET application to create some administrative commands (also known as Programmable Control Facility) to the WebSphere MQ Queue Manager using send and receive APIs. Refer to [DotNetMQ] for details.

Data Type Accuracy

Not all data types have identical data type mapping in Java and .NET. Business data will not be rendered correctly if the data types are wrongly mapped between Java and .NET applications. Data type accuracy is an important element in ensuring data reliability in Java EE .NET interoperability.

For example, unsigned integer type is supported in .NET but not in Java. Thus an XML schema with an unsigned integer type will not be interoperable without proper data mapping or data conversion. Array handling also varies in .NET, which will create only the header element if an empty array is serialized but will not serialize any XML element if a null array is serialized. In contrast, Java will serialize the XML element for both types of array. Thus when dealing with data types mapped to an XML schema, it is important to understand the differences between Java and .NET and their exceptions.

Table 14-1 depicts the data mapping between XML Schema, Java data types and .NET data types. Java SE (Java 2 Platform, Standard Edition) version 5.0 now supports a natural mapping of XML Schema to Java types using JAXB (Java Architecture for XML Binding), which is defined by JSR 31. The JAXB data types under the package javax.xml.datatype are prefixed by the namespace xs in Table 14-1. For example, the integer type int in an XML schema will be resembled by int in Java and Int32 in .NET. In other words, int (in Java) will have the same data type value as in Int32 (in .NET).

Table 14-1. Data Mapping Between XML Schema, Java Data Types, and .NET Data Types

Data Types in XML Schema

Java Data Type

.NET Data Type

int

int

Int32

long

long

Int64

short

short

Int16

nonPositiveInteger

integer

String

negativeInteger

integer

String

nonNegativeInteger

integer

String

unsignedLong

long

UInt32

positiveInteger

integer

UInt64

unsignedInt

integer

UInt32

unsignedShort

short

UInt16

unsignedByte

byte

Byte

double

double

Double

decimal

decimal

Decimal

float

float

Single

hexBinary

hexBinary

Byte[]

base64Binary

base64Binary

Byte[]

boolean

Boolean

Boolean or bool

string

string

String

anyURI

java.net.URL

System.Uri

Enterprise Service Bus

Enterprise Service Bus (ESB) provides reliable messaging features for interoperability. A business process (say, implemented by a .NET application using synchronous Web services) can issue a service request to another business process (for example, implemented by a Java application using asynchronous Web services) via the ESB. A typical synchronous service call does not generate receipt acknowledgement as in an asynchronous messaging protocol. If there is a service failure in the underlying data transport (for example, SOAP over HTTP), the synchronous service request is lost. Using the ESB, the multi-protocol messaging middleware can intercept a synchronous incoming service request and reliably route (bind to the underlying JMS for reliable message routing) to another business process, which only accepts service requests asynchronously. Some ESB implementations (such as Mule ESB) can also invoke a synchronous call asynchronously. Please refer to Chapter 9, "Messaging," for more details.

Not all ESB products support .NET platform. For example, IONA Artix (www.iona.com/products/artix/features.htm) and Sonic ESB (www.sonicsoftware.com/products/docs/sonic_esb.pdf) support both Java and .NET platforms, but Mule ESB (http://mule.codehaus.org/) only supports Java platform and does not support .NET client. Mule ESB version 1.1 is capable of orchestrating Web services generated from a .NET application. Developers may want to research specific vendor product implementation details.

WS-Reliability and WS-ReliableMessaging

WS-Reliability is an OASIS standard specification (www.oasis-open.org/committees/tc_home.php?wg_abbrev=wsrm) that provides a standard and interoperable way to guarantee message delivery to business applications or Web services. This includes guaranteed message delivery (such as acknowledgement messages or resending messages), no duplicates of messages sent or delivered, and guaranteed message ordering using a sequence number mechanism. Currently, RM4GS is a sample software implementation produced by Fujitsu, Hitachi, and NEC (refer to http://xml.coverpages.org/ni2004-03-11-a.html), but there is no .NET implementation yet. There is a summary of the WS-Reliability specification available at [LuefPichler].

WS-ReliableMessaging is a similar Web services specification from Microsoft, IBM, BEA, and TIBCO for supporting SOAP messages to be sent and received reliably over different data transport mechanisms, particularly SOAP over HTTP. There are two major components: core messaging protocol and a related policy assertion specification. WS-ReliableMessaging uses a unique identifier (aka URI) for each message sequence to ensure message ordering and no duplication of messages. It also supports message acknowledgement. However, it leaves message persistence to the responsibility of the design implementation. Several implementations are available in both .NET and Java platforms, for example, Microsoft WSE version 3.0 (http://msdn.microsoft.com/webservices/webservices/building/wse/default.aspx?pull=/library/en-us/dnwse/html/newwse3.asp) and Apache Sandesha (http://ws.apache.org/sandesha/).

Reliability by Integration Strategies

Table 14-2 summarizes the reliability features by comparing synchronous integration, asynchronous integration, and bridge integration strategies. The reliability features are also discussed in Chapter 11.

Table 14-2. Reliability Features by Different Integration Strategies

Reliability Features

Synchronous Integration

Asynchronous Integration

Bridge Integration

Reliable deliverydata transport

N/A

Supported by the messaging technologies such as MSMQ or JMS

Supported by the bridge technology

Receipt acknowledgement

N/A

Supported by the messaging implementation

Supported by the bridge technology

Message delivered once to the recipient, not multiple deliveries

Yes[**]

A feature of publishsubscribe or queuebased messaging model

Yes[**]

Message delivered in order

N/A

Yes[*]

Yes[*]

Message routing

N/A

Java Business Integration (JBI), BPEL (Business Process Execution Language)

Yes[*]

Exceptions converted to local platform

Yes[**]

Yes[**]

Yes[**]

Accuracy of data types/values

Yes[**]

Yes[**]

Yes[**]

Shared logging

Yes[**]

Yes[**]

Bridge can provide shared logging

Supported by security

Web services security, WS-MEX

Web services security, WS-MEX

Web services security, WS-MEX

[**] Need to customize.

[*] Implementation-dependent.

Reliable delivery is often a feature provided by asynchronous integration and bridge integration strategies. The synchronous integration strategy does not provide reliable delivery of messages. It also does not have a message ordering mechanism.

Receipt acknowledgement is a mechanism used in asynchronous integration strategy to ensure that messages or service requests are sent to the recipient reliably. Synchronous integration strategy does not use receipt acknowledgement (because the service requester communicates with the service provider in a "block" mode and exits from the interaction when a return value is received). Some bridge integration implementations also support receipt acknowledgement.

Exception handling (such as mapping Java exceptions to .NET exceptions), data type mapping (such as converting an unsigned integer from .NET to an integer in Java), and shared logging (such as centrally storing the log messages for both Java and .NET applications) usually require customization by all integration strategies. Bridge integration implementation usually provides a shared logging mechanism for both Java and .NET applications.

Application security is always a complex design issue for interoperable solutions. Web services security (www.oasis-open.org/committees/tc_home.php?wg_abbrev=wss) provides a standard mechanism for Java EE .NET interoperability using Web services. This applies to all integration strategies. To achieve single sign-on, the recent Web Services Metadata Exchange (WS-MEX) specification addresses specific Java EE .NET interoperability requirements. Please refer to Chapter 13, "Java EE .NET Security Interoperability" for details.

Availability

To ensure the service provider is highly available to provide the business system functionality, developers can usually consider the following availability design options:

  • Configure clustering for both the Java and .NET applications The objective of clustering technology is to enable multiple instances of the business applications to serve incoming service requests so that when one instance dies, another instance is still available. Another objective is to enable session failover, which means that if a business application (or a hardware node) fails, the session information (or session state) can be made available after the business application instance is recovered from failure. Details of Java EE application server and .NET support clustering are discussed in the next section.

  • Create a shared session state database to store session information A customized database schema can be created to store shared session information or session state for both Java and .NET applications (acting as an integration point). Figure 14-1 depicts the sequence of how the shared session state database works. In this sample scenario, a .NET client is issuing a service request to access the URL, www.javadotnetinterop.com/index.aspx in Step 1. The HttpModule in the ASP.NET server redirects the service request to a registration page written in JSP (first-time registration only) in Step 2. Then the Java application associates the ASP.NET session id and the current Java session id and creates an entry in the shared session state database in Step 3. Upon successful registration, the Java application redirects the client request to the target URL, which is currently served by the ASP.NET server (Step 4). Guest discusses in detail an example of a shared session state database in [GuestKit], pages 430 through 445. This sample scenario assumes that the shared session state database, the Java application, and the .NET application are highly available and resilient and that there may be multiple instances of the business application available to enable high availability.

    Figure 14-1. Shared session state database

  • Use the bridge infrastructure to store shared application and session information This is similar to storing the shared application and session information in a shared session state database. As long as the Java EE .NET bridge middleware is highly available, either the Java or .NET client can be customized to retrieve the session information after the service failure. However, there is no standard mechanism in the container level (for example, a Java EE application server) to handle recovering the session information from the bridge after service failure.

  • Utilize Web SSO for managing session information If the purpose of maintaining session information is to achieve single sign-on for both Java and .NET applications, it may be more sensible to utilize the session management features of vendor products that support Web SSO. Identity management products (such as Sun Java System Access Manager) that support Web SSO usually have the capability to persist session information and make the security service highly available.

Java EE Application Server Cluster

The Java EE application server supports clustering of application server instances and can allow session information (such as HttpSession) to be persisted and failed over in case of a service failure.

Figure 14-2 depicts a logical architecture using Sun Java System Application Server Enterprise Edition version 8.1 as an example. A cluster of three application server instances is created and is administered by an administration server (Domain Administration Server). A Java EE application can be deployed to all application server instances under the same cluster via the Domain Administration Server, without the need to deploy the business application individually to each server instance.

Figure 14-2. Sample Java EE application server cluster logical architecture

A service request from either a .NET client or a Java EE client is routed to different application server instances via a load balancer (or using a Web server load balancer plug-in). An application cluster provides the benefit of session failover. Although each Java EE application server vendor implements the cluster and the session failover slightly differently, they all achieve the same result.

.NET Session Failover

Compared to Java EE application clustering, .NET application has a different approach (also known as a database-centric approach) to handle session failover. Developers can create session information and session states and store them in SQL Server. The SQL Server is deployed as a highly available relational database and is shared by multiple machines running Windows 2003 Server cluster. It is possible to create shared session states in the SQL Server so that the shared session between .NET and Java applications can be available. Refer to [NETStateManagement] and [NETSessionFailover] for details.

End-to-End Availability

Although developers can utilize the clustering and session failover in both Java and .NET platforms, this does not necessarily mean that end-to-end availability can be achieved. For example, consider a scenario of a clustered Java EE application server, clustered ASP.NET server, and a highly available SQL Server. A .NET application issues a service request (say, purchase order) for the Java EE application to process. The Java EE application supports high availability in a cluster environment, which denotes that if an application instance fails, the session information can be recovered by another application instance in the same cluster.

The end-to-end availability design needs to be considered for multiple architectural components. The design complexity may exist for the following scenarios:

  • If the .NET client crashes in the middle of the purchase order creation, will the purchase order be recoverable from the session?

  • If the Java EE application server instance crashes and the session failover takes place, does the .NET application have to reconnect to the Java EE application explicitly in order to recover the session state regarding the purchase order?

There is also an operating overhead associated with high availability (for example, additional system overhead to synchronize the session data between the application server instances). What's more, if the Java EE application does not persist session information, it seems that there is no obvious benefit of using Java EE application server clustering for high availability and session failover.

Availability of Integration Strategies

Table 14-3 summarizes the availability features by comparing synchronous integration, asynchronous integration, and bridge integration strategies. The availability features are also discussed in Chapter 11.

Table 14-3. Availability Features by Different Integration Strategies

Availability Features

Synchronous Integration

Asynchronous Integration

Bridge Integration

Detection of availability status

WS-Management

WS-Management

Depending on the bridge implementation

Persistence

Need to customize

Uses JMS or MSMQ

Depending on the bridge implementation

End-to-end availability

Hardware system level clustering

Hardware/system level clustering

Depending on the bridge implementation

 

Java EE Application Server cluster

Java EE Application Server cluster

 
 

ASP.NET stores session states in SQL Server to ensure availability.

ASP.NET stores session states in SQL Server to ensure availability.

 

Up-time

N/A

N/A

N/A

Middleware

N/A

N/A

N/A

It is noted that both synchronous and asynchronous integration strategies share similar availability features because they both utilize the underlying infrastructures (such as the clustering capability from the Java EE application server container). Typically, messaging technologies (such as JMS or MSMQ) and bridge middleware support high availability. Business transactions can also be persisted using messaging technologies or bridge middleware so that they can be recovered after service failure.

With the availability of WS-Management technology (refer to Chapter 15, "Managing Java EE .NET Interoperability Applications," for more details), the capability to detect availability status has become more important in proactive service management. The detection of availability status allows design of some preventive actions to facilitate availability of the business applications (for example, restart the server instance when certain exception is met). WS-Management can support both synchronous and asynchronous integration strategies. For bridge integration, the detection of availability status and any remedial action to ensure availability depends on the vendor implementation.

Scalability

The scalability of the interoperable solutions implies that the solution can be deployed on large configurations. It is important to remember that deploying business applications on faster CPUs or adding more CPUs and physical memory does not necessarily make the interoperable solution scalable. Moreover, because Java and .NET applications are likely to run on different hardware machines, there needs to be a consistent system performance measurement methodology (for example, measuring the performance of a round-trip from a .NET client to a Java application) to consider several performance enhancement design options. This puts the benchmarking and performance statistics into the proper context instead of using an apple-to-orange metric. The following section introduces some options to measure Java and .NET application performance.

Measuring Performance

There are a few options to measure the performance of a Java and .NET application. These timing functions are provided by the Java and .NET platforms. To measure the end-to-end performance throughout, developers need to aggregate the timing statistics from these basic timing functions for measurement.

  • Adding a timer function in the business application (for example, a client application that invokes the business functions) before and after your function calls. This timer function can be used to measure the total response time required to run an interoperability operation. Refer to Figures 14-3 and 14-4 for Java and .NET program excerpts.

  • Using a testing software package (for example, a stress test package) to measure the end-to-end, total response time and performance. Empirix (www.empirix.com/default.asp?action=category&ID=40) and Mercury LoadRunner (www.mercury.com/us/products/performance-center/) are possible choices.

  • Employing an external testing company to measure the end-to-end performance in a dedicated network or public Internet.

Listing 14-1 shows an example of how to add a timer function in Java applications. This approach applies to all integration strategies but requires a central place to store the time statistics.

Listing 14-1. Java Program Excerpt to Measure System Performance

[View full width]

package com.interop.performance; public class Foo { ... public static void main(String args[]) { long time = System.nanoTime(); // call your remote method or functions System.out.println("Foo took " + (System.currentTimeMillis()- time) + "mill-seconds to run"); } }

Listing 14-2 shows a .NET sample program excerpt that performs a timer function to measure system performance.

Listing 14-2. .NET Program Excerpt to Measure System Performance

... Counter q = new Counter(); ... long startCounting = q.Value; long stopCounting = q.Value; float totalTime = q.TimeElapsed(startCounting, stopCounting); ...

Listing 14-3 shows an alternative .NET sample program excerpt that performs a timer function to measure system performance. The difference is that Listing 14-2 uses the Counter() function, while Listing 14-3 uses the Environment.TickCount package to achieve similar objectives.

Listing 14-3. Another .NET Program Excerpt to Measure System Performance

... int startTicks = Environment.TickCount; // // insert your function here DoSomething(); int stopTicks = Environment.TickCount; Console.WriteLine("Elapsed time = {0} milliseconds", stopTicks - startTicks); ...

When measuring the performance of a Java EE .NET interoperable solution, it is not helpful to take a measurement of individual Java or .NET application alone. The end-to-end application performance (such as round trip from the .NET client to the Java EE application server) needs to be measured. For example, in a scenario where a .NET application creates a purchase order and submits to a Java EE application server, a timer function can be customized to measure from the creation of a purchase order (from the .NET client) to the completion of processing the purchase order (return the processing result from the Java EE application server).

When benchmarking the performance of a Java EE .NET interoperable solution, one should compare different integration strategies for the same set of business requirements and environment constraints. This gives a better assessment of the interoperable solution. It is also useful to measure the resource utilization such as CPU and network. In the sample Supply Chain scenario discussed earlier in the chapter, performance architects may consider benchmarking the application performance of using different integration strategies. It is plausible that asynchronous integration strategy is optimal for Java applications running on a slow entry-level hardware platformwhen compared to using a synchronous integration strategy.

Micro-Tuning

The performance of an application can be tuned and enhanced in two general directions: (1) a top-down approach; (2) a bottom-up approach. In the top-down tuning approach, performance engineers can scale the solution on a high-end machine with more CPUs, more physical memory, and larger data storage without examining each technical component in detail. If the interoperable solution does not scale as expected, performance analysis architects can drill down and identify bottlenecks. In analyzing the performance of a Java EE .NET interoperable solution, performance architects should also consider changing the integration strategy (say, from a synchronous to asynchronous strategy) based on the application.

In the bottom-up tuning approach, performance architects perform a fine-grained analysis of the application and make changes to a specific technical component. For example, they increase the hardware depending on the application requirements for resources (such as CPU and memory). They are referred to as micro-tuning strategies here.

[HansenLai] makes a few generalizations regarding micro-tuning strategies for XML Web services based on a vendor-specific JMS benchmarking. These generalizations can serve as general guidelines for tuning Java applications.

  • Adding more CPUs to synchronous Web services has a non-linear scalability in improving system performance. For example, a specific customer benchmarking exercise shows that RPC-based Web service applications improve performance by adding up to eight CPUs (these quantities are specific customer scenarios and should be interpreted as references, not specific business rules).

  • Adding more physical memory to synchronous Web services has a linear scalability in improving system performance.

  • Adding more CPUs to asynchronous Web services has a slightly linear scalability in improving system performance.

  • Adding more physical memory to asynchronous Web services appears to improve system performance until a certain number of physical memory is reached. After the ceiling is reached, the system performance remains constant.

  • Adding more CPUs to achieve slightly linear scalability for business applications that require intensive XML parsing and XML encryption/decryption.

Rammer and Turner in [RammerTurner] provide an interesting discussion on improving .NET application performance by changing the underlying integration strategies. Rammer and Turner's summary is also a good guideline for choosing the appropriate .NET integration strategies.

  • ASMX (ASP.NET version 2.0) has more than adequate system performance for business transactions and is a preferred choice of .NET technology due to its benefit of better interoperability.

  • Enterprise Services/COM+ components are appropriate for performance-critical applications and are well integrated with Microsoft Windows Communication Foundation (WCF) or formerly Indigo technology.

  • .NET Remoting performs well when using binary serialization over TCP. However, its performance diminishes when remoting components are hosted on Internet Information Server (IIS) and/or when sending and receiving SOAP messages.

Scalability by Integration Strategies

Table 14-4 summarizes the scalability features by comparing synchronous integration, asynchronous integration, and bridge integration strategies. The memory and CPU factors are relatively more prominent than other factors in enhancing the system performance of an interoperable solution. The scalability features are also discussed in Chapter 11.

Table 14-4. Scalability Features by Different Integration Strategies

Scalability Features

Synchronous Integration

Asynchronous Integration

Bridge Integration

Memory factor

Potentially slight linear scalability

Potentially slight linear scalability

Depending on the bridge implementation

CPU factor

XML parsing and encryption will be usually accelerated by faster CPU

XML parsing and encryption will be usually accelerated by faster CPU

Depending on the bridge implementation

Interface factor

N/A

N/A

N/A

Multi-threading factor

Java supports multi-threading

Java supports multi-threading

Depending on the bridge implementation

Distributed architecture factor

Depends on the distributed architecture design

Asynchronous messaging facilitates distributed architecture design

Bridge becomes a hub-centric or bus-centric architecture model

Категории