users@jersey.java.net

Jersey - JAXB Marshalling Error - Field Name Similar to Method Name - Bug?

From: James Allchin <james.allchin_at_gmail.com>
Date: Mon, 20 Apr 2009 11:13:23 +0100

 Hi,

New to all web service frameworks in Java. But think I may have found a bug
with Jersey REST Web services and JAXB (I am using JAX-RS 2.1 with JDK 1.6)

I am using Jersey with Tomcat 6.0. I have a really simple web service which
returns an object called Artifact using a GET method.

I am using standard annotations to allow the the Artifact class to be
marshalled and serialized correctly into XML.

Here is my Artifact class:

@javax.xml.bind.annotation.XmlRootElement
*public* *class* Artifact {

    @javax.xml.bind.annotation.XmlElement
    *protected* *long* artifactId;

    @javax.xml.bind.annotation.XmlElement
    *protected* String artifactType;

    *public* Artifact() {

    }

    /**
     * @return the artifactId
     */
    *public* *long* getArtifactId() {
        *return* artifactId;
    }

    /**
     * @param artifactId the artifactId to set
     */
    *public* *void* setArtifactId(*long* artifactId) {
        this.artifactId = artifactId;
    }

    /**
     * @return the artifactType
     */
    *public* String getArtifactType() {
        *return* artifactType;
    }

    /**
     * @param artifactType the artifactType to set
     */
    *public* *void* setArtifactType(String artifactType) {
        this.artifactType = artifactType;
    }

}



As you can see the class has 2 fields artifactId and artifactType.

It also simple getter and setter accessor methods.

When trying to return this object in the web service - I get the following
error:

java.io.IOException: Error marshalling JAXB object of type "class
com.knowledgemill.entities.Artifact".
        com.sun.jersey.impl.provider.entity.AbstractRootElementProvider.writeTo(AbstractRootElementProvider.java:117)



The hint in the error messages is:

com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts of
IllegalAnnotationExceptions
Class has two properties of the same name "artifactId"
        *this* problem is related to the following location:
                at *public* *long* com.knowledgemill.entities.Artifact.getArtifactId()
                at com.knowledgemill.entities.Artifact
        *this* problem is related to the following location:
                at *protected* *long* com.knowledgemill.entities.Artifact.artifactId
                at com.knowledgemill.entities.Artifact
Class has two properties of the same name "artifactType"
        *this* problem is related to the following location:
                at *public* java.lang.String
com.knowledgemill.entities.Artifact.getArtifactType()
                at com.knowledgemill.entities.Artifact
        *this* problem is related to the following location:
                at *protected* java.lang.String
com.knowledgemill.entities.Artifact.artifactType
                at com.knowledgemill.entities.Artifact



Basically the framework seems to think that artifactId and artifactType are
declared twice.

If I rename the get methods so that they do not read as getArtifactId and
getArtifactType then it works fine:

getArtifactId -> getArtId
getArtifactType -> getArtType

The code now looks like this:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

*package* com.knowledgemill.entities;

/**
 *
 * @author km
 */
@javax.xml.bind.annotation.XmlRootElement
*public* *class* Artifact {

    @javax.xml.bind.annotation.XmlElement
    *protected* *long* artifactId;

    @javax.xml.bind.annotation.XmlElement
    *protected* String artifactType;

    *public* Artifact() {

    }

    /**
     * @return the artifactId
     */
    *public* *long* getArtId() {
        *return* artifactId;
    }

    /**
     * @param artifactId the artifactId to set
     */
    *public* *void* setArtifactId(*long* artifactId) {
        this.artifactId = artifactId;
    }

    /**
     * @return the artifactType
     */
    *public* String getArtType() {
        *return* artifactType;
    }

    /**
     * @param artifactType the artifactType to set
     */
    *public* *void* setArtifactType(String artifactType) {
        this.artifactType = artifactType;
    }

}



With the methods renamed it now works fine. This looks some kind of bug to
me?

Can anyone help? - I would like to keep my accessor methods with a
meaningful name. It's a pretty nasty workaround.

Cheers

James