David's profileWebbert SolutionsBlogLists Tools Help

Blog


    March 08

    Interoperable Testing between .NET Service and Java Client

    I have recently complete interoperable testing between .NET Web Services and a Java client using 2 different frameworks ( Axis / XFire ).  I am blogging my results in order to help myself remember the next time I have to do this as well as save others time in tracking down similar issues.

     

    Both Axis and XFire are experiencing different flavors of the same issue, Inheritance.  Both frameworks seem to be addressing the base type instead of the type of the object instantiated.

    The next 7 blogs will contain the source code and the tests to perform in order to experience the issues first hand.

      • The .NET Web Service    ( Part 1 and 2 )
      • Client code using Axis  ( Part 1 and 2 )
      • Client code using XFire ( Part 1 and 2 )
      • Tests and results

    Web Service - Part 1

    Here is the source code for the .NET Web Service as described in the previous blog.

    Save the following code into a file named SimpleAsmxService.asmx and place it in C:\Inetpub\wwwroot for IIS to use.



    <%@WebService Language="C#" Class="MyService.Simple.SimpleAsmxService" %>

     

    using System.Web.Services;

    using System.Collections.Generic;

    using System.Xml.Serialization;

           

    namespace MyService.Simple

    {

        [WebService( Namespace = "urn:emp:service" )]

        public class SimpleAsmxService : WebService

        {

            [WebMethod]

            public Person GetPerson( Person person )

            {

                Person newPerson = new Person();

           

                CreatePerson( person, newPerson );

           

                return ( newPerson );

            }

           

            [WebMethod]

            public List<Address> GetAddressList()

            {

                List<Address> addressList = new List<Address>();

           

                HomeAddress home = new HomeAddress();

                home.HouseNumber = "211 Pine Street";

           

                addressList.Add( home );

           

                return ( addressList );

            }

           

            [WebMethod]

            public List<HomeAddress> GetHomeAddress()

            {

                List<HomeAddress> addressList = new List<HomeAddress>();

           

                WorkAddress work = new WorkAddress();

                work.HouseNumber = "234 State Avenue";

                work.PhoneNumber = "555-1212";

           

                addressList.Add( work );

           

                return ( addressList );

            }

           

            //[WebMethod]

            //public List<WorkAddress> GetMatchingTypes()

            //{

            //    List<WorkAddress> addressList = new List<WorkAddress>();

           

            //    WorkAddress work = new WorkAddress();

            //    work.HouseNumber = "234 State Avenue";

            //    work.PhoneNumber = "555-1212";

           

            //    addressList.Add( work );

           

            //    return ( addressList );

            //}

     

    Web Service - Part 2

            /// <summary>

            ///

            /// </summary>

            /// <param name="oldPerson"></param>

            /// <param name="newPerson"></param>

            private void CreatePerson( Person oldPerson, Person newPerson )

            {

                Address address;

           

                if ( oldPerson.Address is WorkAddress )

                    address = new WorkAddress();

                else

                    address = new HomeAddress();

           

                newPerson.Name = oldPerson.Name;

                newPerson.Address = address;

           

                if ( oldPerson.Address != null )

                {

                    if ( oldPerson.Address is HomeAddress )

                    {

                        ( newPerson.Address as HomeAddress ).HouseNumber =

                            ( oldPerson.Address as HomeAddress ).HouseNumber;

           

                        if ( oldPerson.Address is WorkAddress )

                        {

                            ( newPerson.Address as WorkAddress ).PhoneNumber =

                                ( oldPerson.Address as WorkAddress ).PhoneNumber;

                        }

                    }

                    else

                    {

                        ( newPerson.Address as HomeAddress ).HouseNumber =

                            "Service Receive object type of: " + oldPerson.Address.GetType().Name;

                    }

                }

                else

                {

                    ( newPerson.Address as HomeAddress ).HouseNumber = "987654 ELM STREET";

                }

            }

        }

           

        /// <summary>

        ///

        /// </summary>

        [XmlRoot( Namespace = "urn:emp:data" )]

        public class Person

        {

            public string Name;

            public Address Address;

        }

           

        /// <summary>

        ///

        /// </summary>

        [XmlRoot( Namespace = "urn:emp:data" )]

        [XmlInclude( typeof( HomeAddress ) )]

        [XmlInclude( typeof( WorkAddress ) )]

        public abstract class Address

        {

        }

           

        /// <summary>

        ///

        /// </summary>

        [XmlRoot( Namespace = "urn:emp:data" )]

        [XmlInclude( typeof( WorkAddress ) )]

        public class HomeAddress : Address

        {

            public string HouseNumber;

        }

           

        /// <summary>

        ///

        /// </summary>

        [XmlRoot( Namespace = "urn:emp:data" )]

        public class WorkAddress : HomeAddress

        {

            public string PhoneNumber;

        }

    }

    Java Client using Axis - Part 1

    Here is the source code for the Java client using Axis.



    /**

     *

     */

    import service.emp.*;

    import data.emp.*;

     

    /**

     * @author

     *

     */

    public class SimpleAsmxAxisClient

    {

     

        /**

         * @param args

         */

        public static void main(String[] args)

        {

            GetPerson();

            GetAddress();

            GetWorkAddress();

        }

       

        /**

         *

         */

        public static void GetPerson()

        {

            Person person;

            Person newPerson;

     

            try

            {

                // Create Proxy Class

                SimpleAsmxServiceSoapProxy service = new SimpleAsmxServiceSoapProxy();

               

                // Create Person

                person = new Person();

                person.setName( "Bob the Builder" );

     

                //

                // DO NOT SEND THE ADDRESS

                //

                System.out.println( "\nDo NOT send Address to Service..." );

                newPerson = service.getPerson( person );

                Print( newPerson );

               

                //

                // SEND THE ADDRESS

                //

                System.out.println( "\nSend Address to Service..." );

                HomeAddress homeAddress = new HomeAddress();

                homeAddress.setHouseNumber("456 Long and Winding Road ");

                person.setAddress(homeAddress);

               

                newPerson = service.getPerson( person );

                Print( newPerson );

            }

            catch ( Exception ex )

            {

                System.err.println(ex);

            }

        }

    Java Client using Axis - Part 2

        /**

         * @param newPerson

         */

        public static void Print( Person newPerson )

        {

            Object o;

           

            if ( newPerson != null )

            {

                System.out.println( "    Name: " + newPerson.getName() );

               

                o = newPerson.getAddress();

                if ( o != null)

                {

                    System.out.println( "    Addr: " + ( (HomeAddress)newPerson.getAddress() ).getHouseNumber() );

                }

                else

                {

                    System.out.println( "    Addr: is null"  );

                }

            }

        }

       

        /**

         *

         */

        public static void GetAddress()

        {

            try

            {

                Address[] listOfAddress;

               

                // Create Proxy Class

                SimpleAsmxServiceSoapProxy service = new SimpleAsmxServiceSoapProxy();

                listOfAddress = service.getAddressList();

               

                System.out.println( "\nStarting GetAddress()..." );

                Print( listOfAddress );

            }

            catch ( Exception ex )

            {

                System.err.println(ex);

            }   

        }

       

        /**

         *

         */

        public static void GetWorkAddress()

        {

            try

            {

                HomeAddress[] listOfAddress;

               

                // Create Proxy Class

                SimpleAsmxServiceSoapProxy service = new SimpleAsmxServiceSoapProxy();

                listOfAddress = service.getHomeAddress();

               

                System.out.println( "\nStarting GetWorkAddress()..." );

                Print( listOfAddress );

            }

            catch ( Exception ex )

            {

                System.err.println(ex);

            }   

        }

     

        /**

         * @param newPerson

         */

        public static void Print( Address[] listOfAddress )

        {

            if (( listOfAddress != null ) && ( listOfAddress.length > 0))

            {

                for ( int index = 0; index < listOfAddress.length; index++)

                {

                    System.out.println( "    House Number: " +

                        ((HomeAddress)listOfAddress[index]).getHouseNumber() );

                   

                    if ( listOfAddress[index] instanceof WorkAddress )

                    {

                        System.out.println( "    Phone Number: " +

                            ((WorkAddress)listOfAddress[index]).getPhoneNumber() );

                    }

                }

            }

        }

    }

    Java Client using XFire - Part 1

    Here is the source code for the Java client using XFire.



    /**

     *

     */

    import java.util.List;

    import emp.service.*;

    import emp.data.*;

     

    /**

     * @author delliott

     *

     */

    public class SimpleAsmxXFireClient

    {

     

        /**

         * @param args

         */

        public static void main(String[] args)

        {

            GetPerson();

            GetAddress();

            GetWorkAddress();

        }

       

        /**

         *

         */

        public static void GetPerson()

        {

            Person person;

            Person newPerson;

     

            try

            {

                // Create Proxy Class

                SimpleAsmxServiceClient service = new SimpleAsmxServiceClient();

               

                // Create Person

                person = new Person();

                person.setName( "Bob the Builder" );

     

                //

                // DO NOT SEND THE ADDRESS

                //

                System.out.println( "\nDo NOT send Address to Service..." );

                newPerson = service.getSimpleAsmxServiceSoap().getPerson( person );

                Print( newPerson );

               

                //

                // SEND THE ADDRESS

                //

                System.out.println( "\nSend Address to Service..." );

                HomeAddress homeAddress = new HomeAddress();

                homeAddress.setHouseNumber("456 Long and Winding Road ");

                person.setAddress(homeAddress);

               

                newPerson = service.getSimpleAsmxServiceSoap().getPerson( person );

                Print( newPerson );

            }

            catch ( Exception ex )

            {

                System.err.println(ex);

            }

        }

     

        /**

         * @param newPerson

         */

        public static void Print( Person newPerson )

        {

            Object o;

           

            if ( newPerson != null )

            {

                System.out.println( "    Name: " + newPerson.getName() );

               

                o = newPerson.getAddress();

                if ( o != null)

                {

                    System.out.println( "    Addr: " + ( (HomeAddress)newPerson.getAddress() ).getHouseNumber() );

                }

                else

                {

                    System.out.println( "    Addr: is null"  );

                }

            }

        }

    Java Client using XFire - Part 2

      

        /**

         *

         */

        public static void GetAddress()

        {

            try

            {

                ArrayOfAddress listOfAddress;

               

                // Create Proxy Class

                SimpleAsmxServiceClient service = new SimpleAsmxServiceClient();

                listOfAddress = service.getSimpleAsmxServiceSoap().getAddressList();

               

                System.out.println( "\nStarting GetAddress()..." );

                Print( listOfAddress );

            }

            catch ( Exception ex )

            {

                System.err.println(ex);

            }   

        }

       

     

        /**

         * @param listOfAddress

         */

        public static void Print( ArrayOfAddress listOfAddress )

        {

            if ( listOfAddress != null )

            {

                List<Address> addressList = listOfAddress.getAddress();

               

                for ( int index = 0; index < addressList.size(); index++)

                {

                    System.out.println( "    House Number: " +

                        ((HomeAddress)addressList.get( index ) ).getHouseNumber() );

                }

            }

        }

     

       

        /**

         *

         */

        public static void GetWorkAddress()

        {

            try

            {

                ArrayOfHomeAddress listOfAddress;

               

                // Create Proxy Class

                SimpleAsmxServiceClient service = new SimpleAsmxServiceClient();

                listOfAddress = service.getSimpleAsmxServiceSoap().getHomeAddress();

               

                System.out.println( "\nStarting GetWorkAddress()..." );

                Print( listOfAddress );

            }

            catch ( Exception ex )

            {

                System.err.println(ex);

            }   

        }

       

        /**

         * @param listOfAddress

         */

        public static void Print( ArrayOfHomeAddress listOfAddress )

        {

            HomeAddress address;

           

            if ( listOfAddress != null )

            {

                List<HomeAddress> addressList = listOfAddress.getHomeAddress();

               

                for ( int index = 0; index < addressList.size(); index++)

                {

                    address = addressList.get( index );

                   

                        System.out.println( "    House Number: " +

                            ((WorkAddress)address).getHouseNumber() );

                        System.out.println( "    Phone Number: " +

                            ((WorkAddress)address).getPhoneNumber() );

                }

            }

        }   

    }

    Interoperability Testing

    SimpleAsmxClient

     

     

    Test 1: 

    Step 1: Run Java Client

     

    Results: 3 of the 4 Prints are successful

     

    Send Address to Service...

     

    System.Web.Services.Protocols.SoapException: Server was unable to read request. --->

    System.InvalidOperationException: There is an error in XML document (1, 337). --->

    System.InvalidOperationException:

    The specified type is abstract: name='Address', namespace='urn:emp:data', at

    <Address xmlns='urn:emp:data'>.

     

    Test 2:

    Step 1: Modify Person.java

    Change all instance of

    data.emp.Address

    To

    data.emp.HomeAddress

     

    Step 2: Run Java Client

     

    Results: 4 of the 4 Prints are successful

     

     

     

     

    SimpleAsmxXFireClient

     

     

    Test 1: 

    Step 1: Run Java Client

     

    Results: 3 of the 4 Prints are successful

      

                Starting GetWorkAddress()...

                java.lang.ClassCastException: emp.data.HomeAddress

     

     

    Test 2:

      

    Step 1: Modify SimpleAsmxService.asmx

    Change

    [WebMethod]

    public List<HomeAddress> GetHomeAddress()

    To

    // [WebMethod]

    public List<HomeAddress> GetHomeAddress()

     

    Step 2: Rebuild Java Proxy Classes

     

    Step 3: Comment out code in Java Client

    GetWorkAddress();

     

    public static void GetWorkAddress()

    {

    ...

    }

     

    public static void Print( ArrayOfHomeAddress listOfAddress )

    {

    ...

    }

     

    Step 4: Run Java Client

     

    Results: 2 of the 3 Prints are successful

    public static void GetAddress() fails to retrieve data

     

    org.codehaus.xfire.XFireRuntimeException: Could not invoke service..

    Nested exception is org.codehaus.xfire.fault.XFireFault: Could not unmarshall type.

     

    Test 3:

    Step 1: Restore original files

    ·         SimpleAsmxService.asmx

    ·         SimpleAsmxXFireClient.java

     

    Step 2: Modify SimpleAsmxService.asmx

    Uncomment the following method

     

    [WebMethod]

    public List<WorkAddress> GetMatchingTypes()

    {

    ...

    }

      

     

    Step 3: Rebuild Java Proxy Classes

     

    Step 4: Run Java Client

     

    Results: 4 of the 4 Prints are successful