Click here to Skip to main content
15,440,714 members
Articles / Containers / Virtual Machine
Posted 7 Feb 2011


15 bookmarked

.NET/Java Interoperability using Service Interface and DTO Architecture Patterns

Rate me:
Please Sign up or sign in to vote.
4.73/5 (8 votes)
7 Feb 2011CPOL5 min read
This article shows you how to build a simple cross-platform interoperation solution between .NET and Java using the Service Interface and Data Transfer Object (DTO) architecture patterns


Interoperability between custom-developed distributed systems running on Java/Linux platform and .NET/Windows remains a challenge even to this day. RPC based solutions like the “COM-CORBA bridge” address it but introduce a major liability in terms of brittle coupling. Several propriety and open source solutions based on web services, database integration and remoting bridges also attempt to address this problem. However such solutions often comprise deep and (in some cases expensive) software stacks introducing accidental complexity, large resource footprint, steep learning curve and performance degradation.

In this article, I present an architectural solution for cross-platform interoperation. The architecturally significant aspect of this solution is to surface, define and govern the structure and exchange of data across the two platforms. The architecture is based on ServiceInterface and Data Transfer Object (DTO) patterns.

The reference implementation demonstrates using this architecture to integrate two business systems, “Fulfillment Center” running on Java/Linux tier and “CustomerOrderProcessing” running on .NET/Windows.


Service Interface

The service interface implements the contract between the consumer and provider. This contract allows them to exchange information even if they are on different systems. The service interface is responsible for all of the implementation details needed to perform this communication.

Image 1

Data Transfer Object

Data transfer object is a distribution pattern where you create a serializable object to transfer state between two systems. DTO has no behavior and its serialization/deserialization is handled by an assembler object.

Image 2


XML Schema or XSD provide constructs to express data types in a platform/language agnostic format. For example, a data type to define Customer Address information in XSD will look like:

<xs:complexType name="Address"> 
  <xs:element name="name" type="xs:string" /> 
  <xs:element name="zip" type="xs:integer" /> 
  <xs:element name="city" type="xs:string" /> 
  <xs:element name="country" type="xs:string" /> 


XXsd2Code is an open source code generator to generate serializable Java, C#, C++ and C++/CLI classes from XSD.


“Fulfillment Center” application is part of a warehouse management system that is written in Java and runs on RHEL. “CustomerOrderProcessing “ is part of a POS system written in .NET and running on Microsoft Windows 2008 server.

Use Case

Any new order processed by the CustomerOrderProcessing system needs to be sent to the "Fulfillment Center". Once the fulfillment system ships the order, it in turn notifies “CustomerOrderProcessing”.


Solution Outline

  • Based on the DTO pattern, create a schema that represents the structure of the data interchange between the two systems. This is the interface contract.
  • Model this contract as an XSD.
  • Use XXsd2Code to code generate platform specific contracts in C# and Java.
  • Create a service interface for the “Fulfillment Center” application using TCP/IP as transport.
  • Create a service gateway for the “CustomerOrderProcessing“ that connects to this service interface.

Structure (Class Diagram) design.pdf


Behaviour (Sequence Diagram) design.pdf


Solution Implementation

Service Contract

  1. Defining the Contract

    Using any XSD editor, create the following data contract. I created this XSD using Microsoft VS 2005.


  2. Code generates C# classes

    Assuming the XXsd2Code.exe is in the same folder as the .xsd file, execute the following command:

    XXsd2Code.exe .\/.\/C# 

    This will code generate C# bindings for the xsd contract:

    namespace CustomerOrderAndFulfillment
    namespace Contract
    public class FulfillmentRecord : ICloneable
    public string FulfillmentRecordID;
    public bool IsBackOrder; 
    public FuzzyCondition StorageTemperature;
    public class CustomerOrder : ICloneable
    public string OrderNumber;
    public CreditRating Rating;
    public Address AddressInfo;
    public List<OrderItem> Orders;
    public CreditCardDetails CcInfo;
  3. Code generate Java classes

    Execute the following command:

    XXsd2Code.exe .\/.\/Java 

    This will code generate Java bindings for the xsd contract:

    package CustomerOrderAndFulfillment.Contract; 
    public class FulfillmentRecord implements Cloneable
    public String FulfillmentRecordID;
    public boolean IsBackOrder;
    public FuzzyCondition StorageTemperature; 
    package CustomerOrderAndFulfillment.Contract; 
    public class CustomerOrder implements Cloneable
    public String OrderNumber;
    public CreditRating Rating;
    public Address AddressInfo;
    public java.util.List<OrderItem> Orders;
    public CreditCardDetails CcInfo;


  1. .NET TCP/IP Client

    Use the TcpClient and NetworkStream to write a simple TCP/IP client

    TcpClient client = new TcpClient(server,port);
    NetworkStream stream = client.GetStream(); 
    //Send Message
    Byte[] data = System.Text.Encoding.UTF8.GetBytes(message);
    stream.Write(data, 0, data.Length)
    //Receive response – blocking call
    byte[] buffer = new byte[1024];
    stream.Read(buffer, 0, buffer.Length);
    return buffer;
  2. Java TCP/IP Server

    Using ServerSocket, BufferedReader and DataOutputStream write a simple TCP/IP deamon on port 1111.

    ServerSocket welcomeSocket = new ServerSocket(1111);
    Socket connectionSocket = welcomeSocket.accept();
    BufferedReader inFromClient = new BufferedReader(new 
    DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
    //get request message
    String request = inFromClient.readLine();
    //Send response

Data Transfer Object

  1. Write an assembler class to Serialize and DeSerialize .NET service interface contract classes using XMLSerializer.

    Serialize method transforms the CustomerOrder object into a stream of bytes so that it is sent to the FulfillmentCenter server.

    static string SerializeCustomerOrder(CustomerOrder order)
    XmlSerializer serializer = new XmlSerializer(typeof(CustomerOrder));
    using (MemoryStream memoryStream = new MemoryStream())
    serializer.Serialize(memoryStream, order);
    return Encoding.UTF8.GetString(memoryStream.ToArray());

    DeSerialize converts the response from the FulfillmentCenter server into a strongly typed FulfillmentRecord object:

    static FulfillmentRecord DeSerializeFulfillmentRecord(byte[] stream)
    XmlSerializer serializer = new XmlSerializer(typeof(FulfillmentRecord));
    using (MemoryStream memoryStream = new MemoryStream(stream))
    return serializer.Deserialize(memoryStream) as FulfillmentRecord;
  2. Write an assembler class to Serialize and DeSerialize Java service interface contract classes using xstream.

    DeSerialize converts the request from the CustomerOrderProcessing into a strongly typed CustomerOrder object.

    static CustomerOrder DeSerializeCustomerOrder(String request)
    XStream serializer = new XStream();
    return (CustomerOrder) serializer.fromXML(request);

    Serialize transforms the FulfillmentRecord object into a stream of bytes so that it can be sent back to the CustomerOrderProcessing system.

    static String SerializeFulfillmentRecord(FulfillmentRecord 
    XStream serializer = new XStream();
    return serializer.toXML(fulfillmentRecord); 

    XMLSerializer and xstream XML compatibility.

    To make sure xstream generates XML that is compatible with XMLSerializer, use the following code:

    xs.aliasType("CustomerOrder", CustomerOrder.class);
    xs.aliasType("OrderItem", OrderItem.class);
    xs.aliasType("FulfillmentRecord", FulfillmentRecord.class); 
    xs.aliasType("Address", Address.class); 

XStream Emun Serialization

To force xstream serialize enums correctly write an Enum Converter:

public class EnumSingleValueConverter< T extends Enum<T> > extends 
EnumConverter implements SingleValueConverter 
    private Class<T> enumType;
    public static <V extends Enum<V>> SingleValueConverter create(Class<V> 
    enumClass) { return new EnumSingleValueConverter<V>(enumClass); }
    private EnumSingleValueConverter(Class<T> newEnumType) 
    { this.enumType = newEnumType; }
    public boolean canConvert(Class type) { return type == enumType; }
    public Object fromString(String str) {
    Object r = null;
    Method m = enumType.getMethod("fromValue", String.class);
    r = m.invoke(null, str); 
    public String toString(Object obj) { return obj.toString(); } 

Using the Reference Implementation

Download and unzip the reference implementation, then follow these steps:

  1. Run the GenerateCrossPlatformDataBindings.bat.
  2. Open .\CustomerOrderProcessing-DotNetClient\CustomerOrderProcessing.sln and compile it.
  3. Open .\FulfillmentCenterSimple-JavaTcpIpServer using Eclipse or Netbeans.
  4. Export a runnable jar and name it FulfillmentCenterApplication.jar.
  5. Run the jar file using this command:
    java -jar FulfillmentCenterApplication.jar 
  6. Now run CustomerOrderProcessing using this command:
    CustomerOrderProcessing.exe 1111 

Note: If you modify the xsd (interface contract), then make sure to run the GenerateCrossPlatformDataBindings.bat again.

Integration Test

I used Eclipse Ganymede to create a runnable jar. To test my “Fulfillment Center” server application, I used Ubuntu 10.10 running as a VirtualBox guest on windows 7 host. Make sure to add a bridge network adaptor for the VM so that the Windows .NET app can reach the Java server running on the Ubuntu guest. Now run Java/Linux “Fulfillment Center” server application.


Now run the “CustomerOrderProcessing” .NET application. Make sure you point to the IPAddress of the Linux Virtual machine.



The architectural solution described in the article enable you to:

  • Decouple interoperation/communication plumbing from the business applications using the Service Interface pattern.
  • Minimize number of calls between the two systems using the Data Transfer Object pattern.
  • Surface, define, govern and ensure compile time enforcement of the service contract by
    • creating platform agnostic data types using XSD
    • then code generating platform specific data types using XXS2Code


  • 7th February, 2011: Initial post


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Written By
Architect Cisco
United States United States
I work as a senior solutions software architect at Cisco.

Here is my work.

Comments and Discussions

GeneralNice. Gets my 5. Pin
amplifity8-Feb-11 9:43
Memberamplifity8-Feb-11 9:43 
GeneralRe: Nice. Gets my 5. Pin
asheesh goja8-Feb-11 10:43
Memberasheesh goja8-Feb-11 10:43 
GeneralMy vote of 5 Pin
Burak Ozdiken8-Feb-11 1:43
MemberBurak Ozdiken8-Feb-11 1:43 
GeneralRe: My vote of 5 Pin
asheesh goja10-Feb-11 11:30
Memberasheesh goja10-Feb-11 11:30 
GeneralComparison with SOAP Pin
Robert Rohde7-Feb-11 22:10
MemberRobert Rohde7-Feb-11 22:10 
GeneralRe: Comparison with SOAP Pin
asheesh goja8-Feb-11 6:16
Memberasheesh goja8-Feb-11 6:16 
GeneralRe: Comparison with SOAP Pin
Arndt Faulhaber8-Feb-11 6:21
MemberArndt Faulhaber8-Feb-11 6:21 
GeneralRe: Comparison with SOAP Pin
JavierCanillas14-Feb-11 8:21
MemberJavierCanillas14-Feb-11 8:21 
GeneralRe: Comparison with SOAP Pin
asheesh goja14-Feb-11 9:38
Memberasheesh goja14-Feb-11 9:38 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.