Vassilis Virvilis created CXF-4534:
--------------------------------------

             Summary: SortedMap is returned as HashMap
                 Key: CXF-4534
                 URL: https://issues.apache.org/jira/browse/CXF-4534
             Project: CXF
          Issue Type: Bug
          Components: Aegis Databinding
    Affects Versions: 2.6.2
         Environment: debian wheezy/testing, unstable
            Reporter: Vassilis Virvilis


We have recently upgraded to 2.6.2 and revisit our test suite. Looks like all 
bugs submitted by use have been fixed. Very impressive, thanks a lot.

In our test suite there is a bug that has not been submitted in JIRA. A 
discussion about that bug can be found at

http://comments.gmane.org/gmane.comp.apache.cxf.user/12388

I decided to submit this bug anyway for documentation purposes.

The problem:
------------

The problem is when the interface declares a SortedMap as an argument or as a 
returned value. Here is the relevant snippets.

Interface
---------

    // fail -- throws exception in the server
    public boolean testSortedMapArgument(SortedMap<Integer, Integer> map);

    // fail -- puts data into a hashmap instead of a SortedMap
    public SortedMap<Integer, Integer> testSortedMapResult();

    // fail -- puts data into a hashmap instead of a SortedMap
    public Map<String, SortedMap<Integer, Integer>> 
testDirectComplexTreeMapResult();


Implementation
--------------

    @Override
    public boolean testSortedMapArgument(SortedMap<Integer, Integer> map) {
        final Class map_class = map.getClass();
        final Collection<Class> klasses = Arrays.asList(map_class.getClasses());
        log.info(String.format("Classes of %s are %s", map_class, klasses));
        return klasses.contains(SortedMap.class);
    }

    @Override
    public SortedMap<Integer, Integer> testSortedMapResult() {
        final SortedMap<Integer, Integer> result = new TreeMap<Integer, 
Integer>();
        result.put(1, 3);
        result.put(0, 2);
        return result;
    }

    @Override
    public Map<String, SortedMap<Integer, Integer>> 
testDirectComplexTreeMapResult() {
        final Map<String, SortedMap<Integer, Integer>> result = new 
HashMap<String, SortedMap<Integer, Integer>>();
        final TreeMap<Integer, Integer> map1 = new TreeMap<Integer, Integer>();
        map1.put(1, 3);
        map1.put(0, 2);
        result.put("key1", map1);
        return result;
    }

Test Client:
------------

    @Test
    public void testSortedMapArgument() {
        final SortedMap<Integer, Integer> map = new TreeMap<Integer, Integer>();
        map.put(1, 3);
        map.put(0, 2);
        Assert.assertTrue(TestServiceFactory.getService()
                .testSortedMapArgument(map));
    }

    @Test
    public void testSortedMapResult() {
        final Class map_class = ((Object) TestServiceFactory.getService()
                .testDirectComplexTreeMapResult()).getClass();
        final Collection<Class> klasses = Arrays.asList(map_class.getClasses());
        log.info(String.format("Classes of %s are %s", map_class, klasses));
        Assert.assertTrue(klasses.contains(SortedMap.class));
    }

    @Test
    public void testDirectComplexTreeMapResult() {
        final Class map_class = ((Object) TestServiceFactory.getService()
                .testDirectComplexTreeMapResult().get("key1")).getClass();
        final Collection<Class> klasses = Arrays.asList(map_class.getClasses());
        log.info(String.format("Classes of %s are %s", map_class, klasses));
        Assert.assertTrue(klasses.contains(SortedMap.class));
    }


The result:
-----------

In cases 2 and 3 I get a hashmap instead of a SortedMap. This is very dangerous 
since it changes program semantics in a very subtle way.

In case 1 I get an exception. Here is the server side part:

    @Test
    public void testSortedMapArgument() {
        final SortedMap<Integer, Integer> map = new TreeMap<Integer, Integer>();
        map.put(1, 3);
        map.put(0, 2);
        Assert.assertTrue(TestServiceFactory.getService()
                .testSortedMapArgument(map));
    }

    @Test
    public void testSortedMapResult() {
        final Class map_class = ((Object) TestServiceFactory.getService()
                .testDirectComplexTreeMapResult()).getClass();
        final Collection<Class> klasses = Arrays.asList(map_class.getClasses());
        log.info(String.format("Classes of %s are %s", map_class, klasses));
        Assert.assertTrue(klasses.contains(SortedMap.class));
    }

    @Test
    public void testDirectComplexTreeMapResult() {
        final Class map_class = ((Object) TestServiceFactory.getService()
                .testDirectComplexTreeMapResult().get("key1")).getClass();
        final Collection<Class> klasses = Arrays.asList(map_class.getClasses());
        log.info(String.format("Classes of %s are %s", map_class, klasses));
        Assert.assertTrue(klasses.contains(SortedMap.class));
    }

Expected result:
----------------

To safely transfer a SortedMap both ways.

I would understand if due to WSDL  constraints reliably transferring a 
sortedMap is not possible. What it would be nice is at least during the deploy 
time an error / warning is issued stating that fact.

Right now we are getting incorrect results in a silent way or a the best case 
an exception at run time.


--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

Reply via email to