users@jersey.java.net

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

From: Felipe Gaúcho <fgaucho_at_gmail.com>
Date: Mon, 20 Apr 2009 13:17:47 +0200

problem is: by default the serialization uses the properties instead
of the fields.. so you finish with two properties with same name :(
this is tricky and confuse at first moment, but there is a simple
solution: to define what type of atributes accessor the serialization
should use:


@XmlAccessorType(XmlAccessType.FIELD)
@javax.xml.bind.annotation.XmlRootElement
public class Artifact {
...
}


I also use another annotation to define the order of the elements in
my serialized types:

@XmlRootElement(namespace = "blah.blah.your.ns")
@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)
@XmlAccessorType(XmlAccessType.FIELD)
public class Artifact {
...
}



On Mon, Apr 20, 2009 at 12:13 PM, James Allchin <james.allchin_at_gmail.com> 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



-- 
Please help to test this application:
http://fgaucho.dyndns.org:8080/cejug-classifieds-richfaces