users@jersey.java.net

Re: [Jersey] Jersey - JAXB Marshalling Error - Field Name Similar to Method Name - Bug?

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

Hi Paul,

Thanks very much for the quick feedback - will give this a try and get back
to the group.

Cheers

James

On 4/20/09, Paul Sandoz <Paul.Sandoz_at_sun.com> wrote:
>
> Hi James,
> This is a JAXB configuration issue, the JAXB runtime thinks there are two
> properties to be serialized with the same name, one that is the protected
> and field and one which is the JavaBean property method.
>
> See here:
>
>
> https://jaxb.dev.java.net/tutorial/section_6_2_5-Controlling-Element-Selection-XmlAccessorType-XmlTransient.html
> #Controlling%20Element%20Selection:%20XmlAccessorType,%20XmlTransient
>
> "If JAXB binds a class to XML, then, by default, all public members will
> be bound, i.e., public getter and setter
> pairs, or public fields. Any protected, package-visible or private
> member is bound if it is annotated with a suitable
> annotation such as XmlElement or XmlAttribute."
>
> If you annotate your Artifact class with the annotation:
>
> @XmlAccessorType(XmlAccessType.FIELD)
>
> then you do not need to annotate the fields with @XmlElement and the
> setter/getter methods will be ignored.
>
> Paul.
>
> On Apr 20, 2009, at 12:13 PM, James Allchin wrote:
>
> 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
>
>
>