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

Expertise with Web services and SOA can be applied in the messaging domain. What is exciting about this strategy is that a developer can build a generic architecture agnostic to a specific JMS provider to successfully link Java and .NET applications. Similarly, one can apply this strategy to achieve interoperability between Java applications and MSMQ. Demonstration on how to send SOAP messages over a messaging infrastructure is provided in the following sections.

Scope

There can exist an integration problem of asynchronously and reliably connecting Java and .NET applications. Deployed in-house messaging solutions can help to address asynchronous, reliable inter-application communication. Web services and the basic messaging infrastructure are sufficient to connect Java EE and .NET environments, which is discussed in the next sections.

Solution

The key interoperability component in this strategy is a MQFaçade that abstracts out a message queue server. For instance, from the Java application the .NET MQFaçade directly accesses an MSMQ, while from a .NET application the Java MQFaçade accesses a JMS message queue. This Façade interfaces with a message queue, MSMQ or JMS provider, using Web Services technology such as SOAP over JMS [SoapMsmqWSE]. To integrate with MQFaçade, a developer has the option of either using Web Services or proxy classes, which are based on Java implementations of .NET Remoting APIs. The main advantage of the Web Services based integration with the MQFaçade includes loose coupling between Java and .NET components. Proxy classes yield tighter coupling between Java and .NET constituents as opposed to Web Services integration. Additionally, proxy classes are generated using third-party libraries, such as Ja.NET or JNBridge.

The main idea of this design is abstracting out the message queue. Figure 9-6 outlines the architecture of the high-level components of this design.

Figure 9-6. .NET MQ Façade Architecture

In the diagram, the .NET MQFaçade acts as a frontier to the MSMQ server. A Java application can invoke the .NET MQFaçade as a Java-based RPC call using proxy classes or as a JAX-RPC call using Java Web Services APIs. The .NET MQFaçade then creates a SOAP message out of this PO information and sends the request to the MSMQ server.

Should the messaging server be JMS-compliant, the design will look very similar, as in Figure 9-7:

Figure 9-7. .NET MQFaçade sending a request to the MSMQ server

Here the .NET application is faced with interoperability constraints. To overcome those constraints, Java MQFaçade is accessed to exchange messages with a JMS provider.

Some of the commercial solutions offer implicit support for SOAP over HTTP, thus simplifying design of the Java EE .NET interoperable solution. For instance, SonicMQ and SonicESB have direct support for inbound and outbound SOAP calls using a feature known as "HTTP Direct." With HTTP Direct, the message server itself can act as an HTTP listener or issue an HTTP request. Therefore a Java EE application can send a JMS message with a payload that is a SOAP-formatted XML message. The message server (broker) delivers this message to its destination as a SOAP message over HTTP protocol. Likewise, a message server can listen for HTTP requests and automatically place an incoming SOAP message onto a JMS queue or topic. Out-of-the-box MQ SOAP/HTTP support eliminates need for an extra layer known as an MQ Façade.

Next, the chapter looks into the design details of the Message Queue with Web services-based interoperability scenario.

Replenish Stock Use Case

Applying this strategy to the Replenish Stock scenario yields the following interaction among Java, .NET and a message queue server. Refer to Figure 9-8.

Figure 9-8. Sequence diagram for Java MQFaçade

The key component of this diagram is the Java MQFaçade, which integrates a .NET POValidator component with a JMS message queue.

If an integration infrastructure revolves around the MSMQ server, an analogous architecture can be constructed by creating a proxy that interfaces with the Java application. Figure 9-9 is a sequence diagram, similar to the previous one, with emphasis on MSMQ integration.

Figure 9-9. .NET MSMQFaçade integrates a Java Warehouse with MSMQ

This diagram highlights a .NET MQFaçade that integrates a Java Warehouse with the MSMQ system.

Should a SOAP message include session information, such as session id, user, and password, these data can be passed as part of the SOAP header. Commercial JMS solutions also provide a means to manage sessions.

Benefits

The advantage of this design entails flexibility of using Web services and a message queue to achieve interoperability. There is no proprietary and custom off-the-shelf solution involved to achieve the Java-.NET application interoperability. From a cost standpoint, this strategy is the one to consider. For example, Sun Java System Message Queue [SunJSMQ], Platform Edition is a free, commercial-grade Java Message Service (JMS) implementation. There are open source implementations of JMS standards available as well.

Manageability

Web services provide an ideal way to expose business functionality as easily reusable interfaces. Web services help leverage existing software investments by allowing a business process wrapped in a Web service interface to be replaced without impacting the consumers of the service.

Performance and Scalability

An additional benefit of this strategy is the ability to exchange rich documents and complex data types with negligible overhead, as most commercial messaging servers feature a high degree of scalability. Thus this strategy has a clear advantage over RPC-style Web services integration, which facilitates a remote method call execution. Similar to the RPC-style, agreeing on a WSDL for data structures exchanged between Java EE and .NET applications helps to provide a consistent message interchange.

Limitations

There are a few drawbacks to this design. One pertains to the fact that integration with messaging is not as transparent as it is using the bridging strategy. Developers have to manually create initial integration points.

Reliability

Because the main application does not exchange messages with a message queue server directly, the reliability of the entire message flow has vulnerability at the MQFaçade point. It is not a problem with proxy classes, that is, the .NET Remoting Proxy, because integration between an MQFaçade and the main application is tightly coupled, and an RPC call will not succeed if one of the building blocks is down or if there is a network failure. With Web services on the other hand, SOAP over HTTP does not guarantee reliable message delivery. Therefore, it is important to leverage a call back mechanism or use other means to achieve reliability across the entire component chain.

Performance and Scalability

The MQFaçade may become a bottleneck when there are multiple messages in the queue to process. For high-volume transactions, the MQFaçade should be designed as a multi-threaded component to alleviate the scalability problem. The MQFaçade may also turn into a single point of failure, thus its availability is critical to successful message processing.

Having the SOAP support built into the message brokers, the SonicMQ solution mitigates this risk. Performance and scalability can be achieved through the clustering capabilities that are built into the message broker.

Manageability

One of the challenges with this approach is maintaining two environments, Java and .NET, to maintain the interoperability logic. In this respect, this approach is more demanding compared to the bridging strategy.

Related Patterns

Both Java MQFaçade and .NET MQFaçade patterns are instances of the Façade pattern. They represent the Façade pattern applied in the specific context of Java EE-.NET integration. Actually in this example it is applied in the context of Java-.NET integration, although an enterprise application may easily employ message-driven beans.

Java MQFaçade and .NET MQFaçade

Both of these patterns naturally augment the Java EE-.NET asynchronous integration with messaging. They provide a layer of abstraction to the diverse messaging infrastructures and encapsulate intricacy of the technology interoperability. Depending on the actual implementation of these patterns, one can apply best practices from Web services or .NET Remoting technologies.

For the Web services strategy, two sets of code samples are demonstrated. The first example deploys a JMS provider, in our case FioranoMQ, and integrates a .NET application using the Java MQFaçade component. The second example deploys the MSMQ solution and interoperates with a Java application via the MQFaçade component. Each of the examples comes with the Readme.doc file that outlines individual classes and instructions on how to run the code.

Example 1: JMS MQFaçade Accesses JMS Provider and .NET Web Services

In the first example, the Warehouse and WarehouseCallback classes access the JMS provider with a traditional way of using JMS APIs. You can take a look at those classes and gain comfort with their pure Java implementation. Therefore we skip the Java EE Retailer System discussion and move on with the Manufacturer system implementation.

Building Manufacturer System

Interoperability challenges occur after the message crossed the JMS message queue boundaries, specifically these challenges are embraced in the Java MQFaçade and POValidator classes that are focused on. For receiving the Purchase Order, MQFaçade invokes Java POValidator object to access the queue, retrieve the PurchaseOrder message, and then post the message to the .NET Web service. These series of events are shown in the receivePO() method of MQFaçade class, see Listing 9-22:

Listing 9-22. Receiving JMS Message

private InputStream receivePO(String poQName) { InputStream inputStream = null; try { validator = new POValidator(); validator.init(poQName); String receivedPO = validator.receivePO(); inputStream = validator.postPOToWebService(receivedPO); } catch(Exception e) { e.printStackTrace(); } return inputStream; }

As can be seen here, the logic of accessing the message queue and retrieving the message is hidden in the POValidator class, which is explored next. This class initializes the message queue components and retrieves the message from the message queue. The POValidator's recievePO() method uses the JMS QueueReceiver to receive the incoming message:

TextMessage pOrder =(TextMessage) receiver.receive();

A more interesting method of this class is the postPOToWebSerivce(), which generates SOAP Request and invokes the Web service endpointsee Listing 9-23:

Listing 9-23. Posting SOAP Request to a Web Service

public InputStream postPOToWebService(String pOMessage) { byte[] soapRequest = getSoapRequest(pOMessage); String soapAction = "http://tempuri.org/ValidatePO"; return executeWebMethod(soapRequest,soapAction); }

The logic of creating a SOAP Request is encompassed in the getSoapRequest() method. Listing 9-24 lists the SOAP Request content that includes Purchase Order id along with necessary SOAP envelope attributes:

Listing 9-24. SOAP Request String

strSoapRequest = "<?xml version='1.0' encoding='UTF-8'?> <soap:Envelope xmlns:xsi=\'http://www.w3.org/2001/XMLSchema- instance\' xmlns:xsd=\'http://www.w3.org/2001/XMLSchema\' xmlns:soap=\'http://schemas.xmlsoap.org/soap/envelope/\'> <soap:Body> <ValidatePO xmlns=\'http://tempuri.org/\'> <id>"+id+"</id> </ValidatePO> </soap:Body> </soap:Envelope>";

Marshaling and unmarshaling of the XML messages sent over the message queue have already been discussed. The getSoapRequest method, from the POValidator class, performs unmarshaling of the PurchaseOrder string retrieved from the queue and creates a SOAP Request, just shown. This SOAP request can easily be extended with the rest of the PurchaseOrder attributes. Listing 9-25 shows this method:

Listing 9-25. Get PurchaseOrder SOAP Request

private byte[] getSoapRequest(String POMessage) { String strSoapRequest=null; try { JAXBContext context = JAXBContext.newInstance("org.j2eedotnet.po"); // unmarshal from ShippingNotice xml string coming Unmarshaller unmarshaller = context.createUnmarshaller(); PurchaseOrder pOrder = (PurchaseOrder) unmarshaller.unmarshal(new StreamSource(new StringReader(POMessage))); String id = pOrder.getId(); strSoapRequest = "<?xml version='1.0' encoding='UTF-8'?> <soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"> <soap:Body> <ValidatePO xmlns=\"http://tempuri.org/\"><id>"+id+"</id> </ValidatePO> </soap:Body> </soap:Envelope>"; } catch(Exception e) { System.out.println("Error reading XML:"+e.getMessage()); } return strSoapRequest.getBytes(); }

The SOAP Request byte array and the SOAP Action, ValidatePO, are sent to the POValidator's executeWebMethod:

String soapAction = "http://tempuri.org/ValidatePO"; return executeWebMethod(soapRequest,soapAction);

The executeWebMethod() is responsible for sending request to the ValidatePO Web Method. The executeWebMethod uses the Web service URL to open the URL connection:

URL endpoint = new URL(webServiceURL); URLConnection con = endpoint.openConnection();

After setting up the URL connection parameters, such as setDoInput and setDoOutput, one can now write out the SOAP Request:

OutputStream out = con.getOutputStream(); out.write(soapRequest);

The return of executeWebMethod is an InputStream that reflects the Web Method return value. Listing 9-26 shows the entire executeWebMethod() content:

Listing 9-26. executeWebMethod

private InputStream executeWebMethod ( byte[] soapRequest, String soapAction) { InputStream inputStream = null; try { URL endpoint = new URL(webServiceURL); URLConnection con = endpoint.openConnection(); con.setDoInput(true); con.setDoOutput(true); con.setUseCaches(false); con.setAllowUserInteraction(false); con.setRequestProperty("Content-Length", Integer.toString(soapRequest.length)); con.setRequestProperty("Content-Type", "text/xml"); con.setRequestProperty("SOAPAction", "\"" + soapAction + "\""); OutputStream out = con.getOutputStream(); out.write(soapRequest); out.flush(); out.close(); inputStream = con.getInputStream(); } catch(Exception e) { e.printStackTrace(); } return inputStream; }

The ASP.NET Web service, DotNetWebApp.asmx, deployed under IIS, offers a single Web method, ValidatePO, that takes input string as a parameter and returns this string back to keep things simple:

[WebMethod(Description = "POValidator Web Service")] public string ValidatePO(string id) { return id; }

This method can easily be tested by typing any string value in the ValidatePO text field, as shown in Figure 9-10:

Figure 9-10. ValidatePO Web service

The result of this method is shown in Figure 9-11:

Figure 9-11. ValidatePO result

It's now time to test this Web service programmatically via a Java client represented with POValidator's executeWebMethod(). Listing 9-27 lists the SOAP Response output, reformatted for ease of readability, from the ValidatePO method:

Listing 9-27. ValidatePO Web Service, SOAP Response

<?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http ://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSche ma-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <soap:Body> <ValidatePOResponse xmlns="http://tempuri.org/"> <ValidatePOResult>8736</ValidatePOResult> </ValidatePOResponse> </soap:Body> </soap:Envelope>

As a quick recap, the Purchase Order ID submitted by POValidator to the Web service endpoint originated from the Java Retailer system. The Warehouse class, as part of Retailer system, submitted the Purchase Order request to the JMS message queue. The message was then received by the POValidator and sent to the Web method.

The next logical step is to generate a ShippingNotice. This might bring up the question of how the SOAP Response was received in the preceding example. This is actually part of the ShipNotice.java that reads results of the Web service, ValidatePO method, from the InputStream of the Web service URL connection. Here is the logic of the readSNFromWebSrevice() method:

int i = -1; while((i = instream.read()) > -1) soapResponse +=((char) i);

The ShipNotice class parses the SOAP Response that it read from the InputStream and retrieves the PO id. To perform this task, the javax.xml.parsers.DocumentBuilderFactory class is used to obtain a parser in the form of javax.xml.parsers.DocumentBuilder and to generate a DOM object from an XML document. In this case the XML parser takes an InputStream corresponding to the ValidatePO Web service URL connection, as an input source (refer to Listing 9-28):

Listing 9-28. Parsing XML Document in Java

DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = docFactory.newDocumentBuilder(); Document document = builder.parse(strStream);

The original Web service can always be checked to determine the structure of the SOAP Response XML file to obtain the right element. In this case the structure is shown in Listing 9-29:

Listing 9-29. SOAP Response, XML Document

<?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema- instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <ValidatePOResponse xmlns="http://tempuri.org/"> <ValidatePOResult>string</ValidatePOResult> </ValidatePOResponse> </soap:Body> </soap:Envelope>

To obtain the ValidatePOResults, the XML tree needs to be traversed from SoapEnvelope to ValidatePOResult, that is, SoapEnvelope-->SoapBody-->ValidatePOResponse-->ValidatePOResult. This is shown in Listing 9-30:

Listing 9-30. Parsing SOAP Response XML Document

Node responseElem = document.getFirstChild().getFirstChild() .getFirstChild().getFirstChild(); String responseID = responseElem.getFirstChild().getNodeValue();

Purchase Order id, in this case a responseId variable, is set as part of the ShippingNotice XML document. The ShipNotice class populates the rest of the values as shown in Listing 9-31:

Listing 9-31. Creating ShippingNotice Object

ObjectFactory objFactory = new ObjectFactory(); ShippingNotice sNotice = objFactory.createShippingNotice(); sNotice.setPONumber(111); sNotice.setShipmentID(222); sNotice.setDescription(responseID);

After the data are populated, the next step is to marshal the ShipNotice into the OutputStream by using the already familiar JAXB APIs. This logic is shown in Listing 9-32:

Listing 9-32. Marshaling ShippingNotice

JAXBContext context = JAXBContext.newInstance("org.j2eedotnet.sn.xsd"); Marshaller marshaller = context.createMarshaller(); marshaller.marshal(sNotice, writer);

Listing 9-33 is the complete listing of the getXMLShipNotice() method that has been discussed:

Listing 9-33. Preparing XML ShippingNotice

private String getXMLShipNotice(String soapResponse) { StringWriter writer = new StringWriter(); try { StringBufferInputStream strStream = new StringBufferInputStream(soapResponse); DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = docFactory.newDocumentBuilder(); Document document = builder.parse(strStream); //SoapEnvelope-->SoapBody-->ValidatePOResponse-- >ValidatePOResult Node responseElem = document.getFirstChild().getFirstChild(). getFirstChild().getFirstChild(); String responseID = responseElem.getFirstChild().getNodeValue(); ObjectFactory objFactory = new ObjectFactory(); ShippingNotice sNotice = objFactory.createShippingNotice(); sNotice.setPONumber(111); sNotice.setShipmentID(222); sNotice.setDescription(responseID); JAXBContext context = JAXBContext.newInstance("org.j2eedotnet.sn.xsd"); // marshal to outputStream Marshaller marshaller = context.createMarshaller(); marshaller.marshal(sNotice, writer); } catch(Exception e) { System.out.println("Invalid SOAP Response:" + e.getMessage()); } System.out.println(writer.toString()); return writer.toString(); }

Listing 9-34 shows the output of the XML ShippingNotice that is created by the getXMLShipNotice() method of the ShipNotice class:

Listing 9-34. Shipping Notice XML Document

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <shippingNotice xmlns="http://j2eedotnet.org/sn/xsd"> <PONumber>111</PONumber> <ShipmentID>222</ShipmentID> <Description>8736</Description> </shippingNotice>

Finally, it's time to send the ShippingNotice to the JMS provider. The ShipNotice's sendSN() method performs this task:

TextMessage jmsMsg = session.createTextMessage(); jmsMsg.setText(shipNoticeMessage); sender.send(jmsMsg);

Coming back to the Retailer system, the WarehouseCallback retrieves the ShippingNotices.

In summary, this example integrates Java and .NET applications using a JMS message queue. To interoperate between JMS provider and .NET application, this example has developed an MQFaçade. MQFaçade communicates with the message queue using standard JMS APIs and communicates with the .NET application using java.net libraries to access a .NET Web service endpoint, as shown in Figure 9-12.

Figure 9-12. Java MQFaçade overview

All of the MQFaçade interoperability logic is embraced by the Manufacturer system and is implemented in Java. The interoperability is completely transparent to the Retailer system. As a reminder, it is important to explicitly ensure reliability between MQFaçade and the Web service.

The next adventure is to implement similar functionality with MSMQ and .NET-based MQFaçade.

Example 2: MSMQ Façade Accessing Web Services

In this example most of the focus is concentrated on investigating interoperability within the Retailer system, as Java-based Retailer system has to access the MSMQ message queue. The Manufacturer system remains the same as discussed in the bridging strategy.

Building Retailer System

As can be imagined, the Warehouse and the WarehouseCallback components cannot directly send messages to MSMQ, given incompatibility of APIs between Java and .NET. To address this challenge, ASP.NET Web service is implemented, acting as MSMQ MQFaçade to bring Java and .NET systems in harmony with each other. This MQFaçade is represented via the DotNetWebAppFaçade.asmx ASP.NET file. The MQFaçade Web service is similar to the Web service implemented in the preceding example, Example 1. The only additional functionality added to this service is access to MSMQ. The ValidatePO method starts with initializing two messages, poValidator queue for outgoing messages and shippingNoticeQueue for incoming messages. This is shown in Listing 9-35:

Listing 9-35. Initializing MSMQ Queues

MessageQueue ValidatePOQueue = new MessageQueue(@"aseem\private$\replenishstock"); MessageQueue shippingNoticeQueue = new MessageQueue(@"aseem\private$\shippingnotice");

Next is to set the Recoverable property of the ValidatePOQueue to true to ensure that a transaction rolls back in case of failure. The ActiveXMessageFormatter is also initialized to pass XML messages to MSMQ.

ValidatePOQueue.DefaultPropertiesToSend.Recoverable = true; ValidatePOQueue.Formatter = new ActiveXMessageFormatter();

For simplicity, a string id is sent to MSMQ:

ValidatePOQueue.Send(id);

Once the Manufacturer system processes the request, a ShippingNotice is received back. Here for simplicity, once again a string ID is exchanged:

Message message = shippingNoticeQueue.Receive(); message.Formatter = new ActiveXMessageFormatter(); string sNotice = message.Body.ToString();

The next code snippet, Listing 9-36, lists the DotNetWebApp.asmx WebMethod, ValidatePO() that acts as an MSMQ Façade:

Listing 9-36. MSMQ MQFaçade Represented as .NET Web Service

[WebMethod(Description = "POValidator Web Service")] public string ValidatePO(string id) { MessageQueue ValidatePOQueue = new MessageQueue(@"aseem\private$\replenishstock"); MessageQueue shippingNoticeQueue = new MessageQueue(@"aseem\private$\shippingnotice"); ValidatePOQueue.DefaultPropertiesToSend.Recoverable = true; ValidatePOQueue.Formatter = new ActiveXMessageFormatter(); try { ValidatePOQueue.Send(id); Console.WriteLine("Sent the message"); } catch(Exception ex) { Console.WriteLine(ex.Message); } Message message = shippingNoticeQueue.Receive(); message.Formatter = new ActiveXMessageFormatter(); string sNotice = message.Body.ToString(); Console.WriteLine("Received shippingNotice"); return sNotice; }

When deploying the DotNetWebServiceFaçade, a familiar screen is revealed in Figure 9-13:

Figure 9-13. Deploying .NET WebService MQFaçade

The main Java application, Java_EEApp.java, initiates request to the MQFaçade by invoking the sendPO() method. The core logic of this method relies on the Warehouse's postPOToWebService() method:

poSender = new Warehouse(); String pOrder = poSender.getPO(); inputStream = poSender.postPOToWebService(pOrder);

Interestingly enough, a majority of the logic required for this sample is identical to the Web services Example 1 that was developed earlier in this section. It described postPOToWebService method, so it won't be scrutinized here again. The InputStream is returned from the poSender.postPOToWebService() operation back to the main() method of Java EEApp.java.

On the receiving end, the InputStream received from postPOToWebServer() method is passed to the Java EEApp's receiveShippingNotice() method. This method creates an instance of the WarehouseCallback class to retrieve the ShippingNotice :

snReceiver = new WarehouseCallback(); ShippingNotice sNotice = (ShippingNotice)snReceiver.getSNFromWebService(instream);

As has already been mentioned, C# classes including Manufacturer, ShipNotice, and POValidator remain nearly the same as ones implemented in the bridging strategy.

Developer's Note

The Java EEApp synchronously invokes Warehouse and WarehouseCallback components. To implement asynchronous communication between .NET Web service and the Java program, you may leverage automatic callback strategy, demonstrated in Chapter 8, "Asynchronous Web Services Integration."

At a higher level, the .NET MQFaçade is integrated with Java and MSMQ using the following APIs, see Figure 9-14.

Figure 9-14. .NET Web Services MQFaçade overview

The last two examples explained how to implement interoperability using Web services and messaging. Web services is the weakest link in the integration chain from a reliable messaging standpoint; therefore, before making a decision on this strategy it's best to explore an alternative integration with proxy classes, which is examined next.

Example 3: Accessing MSMQ from Java Using Proxy Classes

From a messaging interoperability standpoint, the overall flow of the sample remains the same. The only difference is that instead of a Web services-based Façade, proxy classes are used. For more details on this, refer to Chapter 5, "NET Remoting for Synchronous Intregration." When it comes to Messaging integration with proxy, there are online resources available that demonstrate MSMQ access from Java using a third-party proxy library. For example, Intrinsyc's J-Integra solution, [JIntegraMSMQ], offers a bi-directional way to seamlessly access the MQMQ from Java. This solution utilizes Java proxy classes that are mapped from COM components API. To preview and run the example, refer to the following link, http://j-integra.intrinsyc.com/com/doc/other_examples/Java_from_MSMQ.htm.

In summary, depending on interoperability requirements and existing infrastructure, the MQFaçade strategy can become an effective solution to a Java-.NET interoperability problem.

Категории