owlike/genson

Genson ArrayIndexOutOfBoundsException when using @XmlAccessorType with simple class

KyleMoser opened this issue · 2 comments

I very thoroughly tested and it looks as though any time I use the annotation @XmlAccessorType(javax.xml.bind.annotation.XmlAccessType.PROPERTY), I get an ArrayIndexOutOfBoundsException with Genson. I am using a ResourceConfig to configure Genson with the JAXB bundle and my full JSON test class (which is extremely simple) is shown.

Exception stack trace:

java.lang.ArrayIndexOutOfBoundsException: 0
    at com.owlike.genson.reflect.BeanPropertyFactory$StandardFactory.createMutator(BeanPropertyFactory.java:115)
    at com.owlike.genson.reflect.BeanPropertyFactory$CompositeFactory.createMutator(BeanPropertyFactory.java:87)
    at com.owlike.genson.reflect.BaseBeanDescriptorProvider.provideMethodMutators(BaseBeanDescriptorProvider.java:232)
    at com.owlike.genson.reflect.BaseBeanDescriptorProvider.provideBeanPropertyMutators(BaseBeanDescriptorProvider.java:119)
    at com.owlike.genson.reflect.AbstractBeanDescriptorProvider.provide(AbstractBeanDescriptorProvider.java:98)
    at com.owlike.genson.reflect.BeanDescriptorProvider$CompositeBeanDescriptorProvider.provide(BeanDescriptorProvider.java:60)
    at com.owlike.genson.convert.BasicConvertersFactory.provide(BasicConvertersFactory.java:104)
    at com.owlike.genson.convert.BasicConvertersFactory.create(BasicConvertersFactory.java:69)
    at com.owlike.genson.convert.BasicConvertersFactory.create(BasicConvertersFactory.java:51)
    at com.owlike.genson.reflect.AbstractBeanDescriptorProvider$ContextualFactoryDecorator.create(AbstractBeanDescriptorProvider.java:75)
    at com.owlike.genson.reflect.AbstractBeanDescriptorProvider$ContextualFactoryDecorator.create(AbstractBeanDescriptorProvider.java:64)
    at com.owlike.genson.convert.ChainedFactory.create(ChainedFactory.java:88)
    at com.owlike.genson.convert.ChainedFactory.create(ChainedFactory.java:75)
    at com.owlike.genson.convert.ChainedFactory.create(ChainedFactory.java:88)
    at com.owlike.genson.convert.ChainedFactory.create(ChainedFactory.java:75)
    at com.owlike.genson.convert.CircularClassReferenceConverterFactory.create(CircularClassReferenceConverterFactory.java:55)
    at com.owlike.genson.convert.CircularClassReferenceConverterFactory.create(CircularClassReferenceConverterFactory.java:19)
    at com.owlike.genson.Genson.provideConverter(Genson.java:148)
    at com.owlike.genson.convert.DefaultConverters$CollectionConverterFactory.create(DefaultConverters.java:239)
    at com.owlike.genson.convert.DefaultConverters$CollectionConverterFactory.create(DefaultConverters.java:231)
    at com.owlike.genson.convert.BasicConvertersFactory.provide(BasicConvertersFactory.java:97)
    at com.owlike.genson.convert.BasicConvertersFactory.create(BasicConvertersFactory.java:69)
    at com.owlike.genson.convert.BasicConvertersFactory.create(BasicConvertersFactory.java:51)
    at com.owlike.genson.reflect.AbstractBeanDescriptorProvider$ContextualFactoryDecorator.create(AbstractBeanDescriptorProvider.java:75)
    at com.owlike.genson.reflect.AbstractBeanDescriptorProvider$ContextualFactoryDecorator.create(AbstractBeanDescriptorProvider.java:64)
    at com.owlike.genson.convert.ChainedFactory.create(ChainedFactory.java:88)
    at com.owlike.genson.convert.ChainedFactory.create(ChainedFactory.java:75)
    at com.owlike.genson.convert.ChainedFactory.create(ChainedFactory.java:88)
    at com.owlike.genson.convert.ChainedFactory.create(ChainedFactory.java:75)
    at com.owlike.genson.convert.CircularClassReferenceConverterFactory.create(CircularClassReferenceConverterFactory.java:55)
    at com.owlike.genson.convert.CircularClassReferenceConverterFactory.create(CircularClassReferenceConverterFactory.java:19)
    at com.owlike.genson.Genson.provideConverter(Genson.java:148)
    at com.owlike.genson.Genson.serialize(Genson.java:272)
    at com.owlike.genson.ext.jaxrs.GensonJsonConverter.writeTo(GensonJsonConverter.java:85)

web.xml:

<servlet>
    <servlet-name>rest</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
      <param-name>javax.ws.rs.Application</param-name>
      <param-value>genson.test.JerseyResourceConfig</param-value>
    </init-param>
    <load-on-startup>2</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>rest</servlet-name>
    <url-pattern>/rest/*</url-pattern>
  </servlet-mapping>

Genson Configuration:

package genson.test;

import org.glassfish.jersey.server.ResourceConfig;
import com.owlike.genson.Genson;
import com.owlike.genson.GensonBuilder;
import com.owlike.genson.ext.jaxb.JAXBBundle;
import com.owlike.genson.ext.jaxrs.GensonJaxRSFeature;

public class JerseyResourceConfig extends ResourceConfig {
    public JerseyResourceConfig() {     
        Genson genson = new GensonBuilder()
                .withBundle(new JAXBBundle())
                .useConstructorWithArguments(true)
                .setSkipNull(true)
                .create();

        register(new GensonJaxRSFeature().use(genson));
        packages("genson.test");
      }
}

REST endpoint:

package genson.test;

import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import genson.test.json.GensonTest;

@Path("/test/")
public class RestTest {

    @GET
    @Path("employees")
    @Produces(MediaType.APPLICATION_JSON)
    public List<GensonTest> getEmployees() {
        List<GensonTest> employees = new ArrayList<>();
        GensonTest emp = new GensonTest();
        emp.setWaiterName("Jack");
        employees.add(emp);
        return employees;
    }
}

JSON test class that gets serialized:

package genson.test.json;
import javax.xml.bind.annotation.XmlAccessorType;

@XmlAccessorType(javax.xml.bind.annotation.XmlAccessType.PROPERTY)
public class GensonTest {

    public String waiterName;

    public String getWaiterName() {
        return waiterName;
    }

    public void setWaiterName(String waiterName) {
        this.waiterName = waiterName;
    }
}


Thank you for reporting this, indeed it is a bug :/
I will try to find some time to fix it. But if you feel your self of contributing, help is very welcome ;)
In the mean time, to avoid it, you can just remove the annotation as by default Genson will use the get/set methods.

I added a fix on master. Can you give it a shot? To build genson you just need java 7 or less and maven installed.