vadbch / orika

Automatically exported from code.google.com/p/orika
0 stars 0 forks source link

Usage of paranamer leads to different mapping results on developement and production environments #180

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
As far as I understand it paranamer accesses the debug information in the byte 
code to read out the parameter names. This works fine on development 
environments where we usually have debug info enabled. In production 
environments this feature is normally disabled (at least in my case). As a 
result Orika is not able to determine how to corectly order the list of 
parameters if a parameter type is used more than once. There is no exception or 
warning if paranamer won't find any parameter names. The best matching 
constructor is choosen and invoked. However the allocation of identical 
parameter types is a gambling game.

The following test works depending on whether the byte code contains debug 
information or not.

public class ConstructorResolverTest {

    @Test
    public void test() throws Exception {
        DefaultMapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
        mapperFactory.classMap(A.class, B.class).byDefault().register();
        BoundMapperFacade<A, B> a2bMapper = mapperFactory.getMapperFacade(A.class, B.class);

        B b = a2bMapper.map(new A("Max", "Muster"));
        assertThat(b.getFirstname(), is("Max"));
        assertThat(b.getLastname(), is("Muster"));
    }

    public static class A {
        private final String firstname;
        private final String lastname;

        public A(String firstname, String lastname) {
            this.firstname = firstname;
            this.lastname = lastname;
        }

        public String getFirstname() {
            return firstname;
        }

        public String getLastname() {
            return lastname;
        }
    }

    public static class B {
        private final String firstname;
        private final String lastname;

        public B(String lastname, String firstname) {
            this.firstname = firstname;
            this.lastname = lastname;
        }

        public String getFirstname() {
            return firstname;
        }

        public String getLastname() {
            return lastname;
        }
    }
}

The main problem is that there is no warning or exception when Orika is not 
100% sure that it invokes the constructor correctly. The issue pops up when you 
look at your mapped objects in production and realize that something is strange 
:D

Regards Maxim

Original issue reported on code.google.com by maxim.mo...@googlemail.com on 14 Nov 2014 at 7:15