147

With Jaxb (jaxb-impl-2.1.12), UI try to read an XML file

Only a few element in the XML file are interesting, so I would like to skip most of the elements.

The XML I'm trying to read:

<?xml version="1.0" encoding="UTF-8"?>
<!--Sample XML file generated by XMLSpy v2010 rel. 3 sp1 (http://www.altova.com)-->
<flx:ModeleREP xsi:schemaLocation="urn:test:mod_rep.xsd mod_rep.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:flx="urn:test:mod_rep.xsd">
<flx:DocumentHeader>
    <flx:Identification v="04489"/>
</flx:DocumentHeader>
<flx:TimeSeries>
    <flx:Identification v="test1a"/>
    <flx:BusinessType v="A01"/>
    <flx:Product v="123a"/>
    <flx:ResourceObject codingScheme="N" v="testa"/>
    <flx:Period>
        <flx:TimeInterval v="2011-07-02T00:00/2011-07-16T00:00"/>
        <flx:Resolution v="PT2H"/>
        <flx:Pt>
            <flx:P v="1"/>
            <flx:Q unitCode="String" v="1.0"/>
            <flx:A currencyIdentifier="String" v="195.0"/>
        </flx:Pt>
    </flx:Period>
</flx:TimeSeries>
<flx:TimeSeries>
    <flx:Identification v="test2a"/>
    <flx:BusinessType v="A01"/>
    <flx:Product v="a123b"/>
    <flx:ResourceObject codingScheme="N" v="test2"/>
    <flx:Period>
        <flx:TimeInterval v="2011-07-02T00:00/2011-07-16T00:00"/>
        <flx:Resolution v="PT2H"/>
        <flx:Pt>
            <flx:P v="1"/>
            <flx:Q unitCode="String" v="1.0"/>
            <flx:A currencyIdentifier="String" v="195.0"/>
        </flx:Pt>
        <flx:Pt>
            <flx:P v="2"/>
            <flx:Q unitCode="String" v="1.0"/>
            <flx:A currencyIdentifier="String" v="195.0"/>
        </flx:Pt>
    </flx:Period>
</flx:TimeSeries>
</flx:ModeleREP>

my class

@XmlRootElement(name="ModeleREP", namespace="urn:test:mod_rep.xsd")
public class ModeleREP {

  @XmlElement(name="TimeSeries")
  protected List<TimeSeries> timeSeries;

  public List<TimeSeries> getTimeSeries() {
  if (this.timeSeries == null) {
      this.timeSeries = new ArrayList<TimeSeries>();
  }
  return this.timeSeries;
  }

  public void setTimeSeries(List<TimeSeries> timeSeries) {
  this.timeSeries = timeSeries;
  }

}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "TimeSeries")
public class TimeSeries {

@XmlElement(name="ResourceObject")
protected RessourceObject resourceObject;

@XmlElement(name = "Period")
protected Period period;

public RessourceObject getResourceObject() {
    return this.resourceObject;
}

public void setResourceObject(RessourceObject resourceObject) {
    this.resourceObject = resourceObject;
}

public Period getPeriod() {
    return this.period;
}

public void setPeriod(Period period) {
    this.period = period;
}

}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "ResourceObject")

public class RessourceObject {
@XmlAttribute(name = "codingScheme")
protected String codingScheme;

@XmlAttribute(name = "v")
protected String v;

public String getCodingScheme() {
    return this.codingScheme;
}

public void setCodingScheme(String codingScheme) {
    this.codingScheme = codingScheme;
}

public String getV() {
    return this.v;
}

public void setV(String v) {
    this.v = v;
}
}

@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement(name = "Period")
public class Period {

@XmlElement(name = "TimeInterval")
protected TimeInterval timeInterval;

@XmlElement(name = "Pt")
protected List<Pt> pt;

public TimeInterval getTimeInterval() {
    return this.timeInterval;
}

public void setTimeInterval(TimeInterval timeInterval) {
    this.timeInterval = timeInterval;
}

public List<Pt> getPt() {
    if (this.pt == null) {
    this.pt = new ArrayList<Pt>();
    }
    return this.pt;
}

public void setPt(List<Pt> pt) {
    this.pt=pt;
}

}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "TimeInterval")
public class TimeInterval {

@XmlAttribute(name = "v")
private String timeIntervalPeriod;

public String getTimeIntervalPeriod() {
    return this.timeIntervalPeriod;
}

public void setTimeIntervalPeriod(String timeIntervalPeriod) {
    this.timeIntervalPeriod = timeIntervalPeriod;
}

}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Pt")
public class Pt {

@XmlElement(name = "P")
protected P p;

@XmlElement(name = "A")
protected A a;

public P getP() {
    return this.p;
}

public void setP(P p) {
    this.p = p;
}

public A getA() {
    return this.a;
}

public void setA(A a) {
    this.a = a;
}
}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "P")
public class P {
@XmlAttribute(name = "v")
protected String position;


public String getPosition(){
    return this.position;
}

public void setPosition(String position){
    this.position=position;
}
}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "A")
public class A {
@XmlAttribute(name = "v")
protected String calculatedAmount;

public String getCalculatedAmount() {
    return this.calculatedAmount;
}

public void setCalculatedAmount(String calculatedAmount) {
    this.calculatedAmount = calculatedAmount;
}
}

when I try to read the XML file, I get this error:

com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
Class has two properties of the same name "timeSeries"
    this problem is related to the following location:
        at public java.util.List testjaxp.ModeleREP.getTimeSeries()
        at testjaxp.ModeleREP
    this problem is related to the following location:
        at protected java.util.List testjaxp.ModeleREP.timeSeries
        at testjaxp.ModeleREP

I don't understand this error. And sometimes when I check my object, timeSeries is null.

How can I fix this error/prevent timeSeries from returning null?

TylerH
  • 20,799
  • 66
  • 75
  • 101
redfox26
  • 2,020
  • 4
  • 25
  • 33

18 Answers18

255

I set these properties when I faced this problem. Setting one or both of them may solve your issue:

@XmlRootElement(name="yourRootElementName")
@XmlAccessorType(XmlAccessType.FIELD)
TylerH
  • 20,799
  • 66
  • 75
  • 101
user2067376
  • 2,557
  • 1
  • 12
  • 4
  • 9
    I had the same issue. And even it works when we add only @XmlAccessorType(XmlAccessType.FIELD) – Ram Dutt Shukla Mar 11 '15 at 11:36
  • 3
    I solved the issue by _removing_ the `@XmlAccessorType(XmlAccessType.FIELD)` annotation – Hans Wouters Aug 07 '15 at 14:18
  • Sounds strange, but I also got rid of this exception by reducing pair of annotations \@XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) to only \@XmlRootElement – Alex InTechno Mar 09 '16 at 13:00
  • 1
    I had that issue with ```@XmlAccessorType(XmlAccessType.FIELD)``` and changing it to ```@XmlAccessorType(XmlAccessType.PROPERTY)``` solved the problem – Yevhenii Smyrnov Apr 20 '21 at 17:09
28

There are multiple solutions: If you annotate on variable declaration then you need @XmlAccessorType(XmlAccessType.FIELD), but if you prefer to annotate either a get- or set-method then you don't.

So you can do:

@XmlRootElement(name="MY_CLASS_A")
@XmlAccessorType(XmlAccessType.FIELD)
public class MyClassA
{
    @XmlElement(name = "STATUS")   
    private int status;
   //.. and so on
}

Or:

@XmlRootElement(name="MY_CLASS_A")
public class MyClassA
{
    private int status;
      
    @XmlElement(name = "STATUS")         
    public int getStatus()
    {
    }
}
Baked Inhalf
  • 3,375
  • 1
  • 31
  • 45
26

You didn't specified what JAXB-IMPL version are you using, but once I had the same problem (with jaxb-impl 2.0.5) and solved it using the annotation at the getter level instead of using it at the member level.

megathor
  • 479
  • 3
  • 7
  • That is correct I just removed the annotation from member and put it on setter level and it worked. – Varun Aug 03 '17 at 07:07
25

I've also seen some similiar issues like this.

I think, it's because of the place where we use the "@XMLElement" annotation in the (bean) class.

And I think, the JAXB (annotation processor) considers the member field & getter method of the same field element as different properties, when we use the @XMLElement annotation at the field level and throws the IllegalAnnotationExceptions exception.

Exception Message :

Class has two properties of the same name "timeSeries"

At Getter Method :

    at public java.util.List testjaxp.ModeleREP.getTimeSeries()

At Member Field :

    at protected java.util.List testjaxp.ModeleREP.timeSeries

Solution : Instead of using @XmlElement in the field, use it in the getter method.

Sri
  • 4,613
  • 2
  • 39
  • 42
20

just added this to my class

@XmlAccessorType(XmlAccessType.FIELD)

worked like a cham

Ismael ozil
  • 573
  • 5
  • 6
  • 1
    This just repeats the [top answer from March 2013](https://stackoverflow.com/questions/6768544/jaxb-class-has-two-properties-of-the-same-name/15330184#15330184) (except gives half as much information), 4 years prior. Please only add new answers when you have _new_ information to give. – TylerH Feb 13 '23 at 14:35
11

Your JAXB is looking at both the getTimeSeries() method and the member timeSeries. You don't say which JAXB implementation you're using, or its configuration, but the exception is fairly clear.

at public java.util.List testjaxp.ModeleREP.getTimeSeries()

and

at protected java.util.List testjaxp.ModeleREP.timeSeries

You need to configure you JAXB stuff to use annotations (as per your @XmlElement(name="TimeSeries")) and ignore public methods.

ptomli
  • 11,730
  • 4
  • 40
  • 68
10

"Class has two properties of the same name exception" can happen when you have a class member x with a public access level and a getter/setter for the same member.

As a java rule of thumb, it is not recommended to use a public access level together with getters and setters.

Check this for more details: Public property VS Private property with getter?

To fix that:

  1. Change your member's access level to private and keep your getter/setter
  2. Remove the member's getter and setter
Community
  • 1
  • 1
Naor Bar
  • 1,991
  • 20
  • 17
9

If we use the below annotations and remove the "@XmlElement" annotation, code should work properly and resultant XML would have the element names similar to the class member.

@XmlRootElement(name="<RootElementName>")
@XmlAccessorType(XmlAccessType.FIELD)

In case use of "@XmlElement" is really required, please define it as field level and code should work perfectly. Don't define the annotation on the top of getter method.

Had tried both the above approaches mentioned and got to fix the issue.

Tanorix
  • 230
  • 2
  • 16
8

You need to configure class ModeleREP as well with @XmlAccessorType(XmlAccessType.FIELD) as you did with class TimeSeries.

Have al look at OOXS

Nick
  • 2,827
  • 4
  • 29
  • 39
Mike
  • 121
  • 2
  • 8
8

Declare the member variables to private in the class you want to convert to XML.

TylerH
  • 20,799
  • 66
  • 75
  • 101
Tayab Hussain
  • 831
  • 9
  • 16
  • This should be the accepted solution. If you declare your member variable public, JABX will parse it in addition to getter/setter annotated methods and spit the exception. It's a great example where jabx library designer(s) went an extra mile on reflection trying to create flexibility and ended up facilitating invalid configurations. I fixed the problem on my own by changing one line of code at the time, tracing back to the member variable. – Vortex Oct 26 '16 at 04:36
7

These are the two properties JAXB is looking at.

public java.util.List testjaxp.ModeleREP.getTimeSeries()  

and

protected java.util.List testjaxp.ModeleREP.timeSeries

This can be avoided by using JAXB annotation at get method just like mentioned below.

@XmlElement(name="TimeSeries"))  
public java.util.List testjaxp.ModeleREP.getTimeSeries()
CoolBeans
  • 20,654
  • 10
  • 86
  • 101
Kondal Kolipaka
  • 3,471
  • 22
  • 28
3

It will work when you put your annotation before the getters, and remove it from the protected attributes:

protected String codingScheme;

@XmlAttribute(name = "codingScheme")
public String getCodingScheme() {
    return this.codingScheme;
}
Lilia
  • 462
  • 6
  • 22
  • I too am running into the same problem. I too have observed that when the annotation is marked over the attributes I see this. Does this mean that always it should be placed before the getters?. – Pavan Dittakavi Apr 15 '18 at 16:35
  • @Pavan Yes I think so. Otherwise, it causes me the same problems than you – Lilia May 13 '18 at 11:52
2

The source of the problem is that you have both XmlAccessType.FIELD and pairs of getters and setters. The solution is to remove setters and add a default constructor and a constructor that takes all fields.

TylerH
  • 20,799
  • 66
  • 75
  • 101
Slava Imeshev
  • 1,360
  • 10
  • 14
2

A quick and simple way to fix this issue is to remove the @XmlElement(name="TimeSeries") from the top of the variable declaration statement protected List<TimeSeries> timeSeries; to the top of its getter, public List<TimeSeries> getTimeSeries().

Thus your ModeleREP class will look like:

@XmlRootElement(name="ModeleREP", namespace="urn:test:mod_rep.xsd")
public class ModeleREP {


  protected List<TimeSeries> timeSeries;

  @XmlElement(name="TimeSeries")
  public List<TimeSeries> getTimeSeries() {
    if (this.timeSeries == null) {
      this.timeSeries = new ArrayList<TimeSeries>();
    }
    return this.timeSeries;
  }

  public void setTimeSeries(List<TimeSeries> timeSeries) {
    this.timeSeries = timeSeries;
  }
}
TylerH
  • 20,799
  • 66
  • 75
  • 101
1

I had a service class with a signature as below:

@WebMethod
public FetchIQAStatusResponseVO fetchIQAStatus(FetchIQAStatusRequest fetchIQAStatusRequest) {

On run I got the same error for FetchIQAStatusResponseVO fields. I just added a line on top of FetchIQAStatusResponseVO:

@XmlAccessorType(XmlAccessType.FIELD) //This line added
public class FetchIQAStatusResponseVO {

and this resolved the issue.

TylerH
  • 20,799
  • 66
  • 75
  • 101
S Agrawal
  • 11
  • 2
1

ModeleREP#getTimeSeries() have to be with @Transient annotation. That would help.

Armer B.
  • 753
  • 2
  • 9
  • 25
0

Annotating with @XmlTransient resolves that issue

@XmlTransient
public void setTimeSeries(List<TimeSeries> timeSeries) {
   this.timeSeries = timeSeries;
}

Look at http://docs.oracle.com/javase/8/docs/api/javax/xml/bind/annotation/XmlTransient.html for more details

kmaziarz
  • 154
  • 5
  • 1
    I think this is more a hack than a solution. This tells jaxb to ignore the method, instead of making it aware that it is the same thing. – Hans Wouters Aug 07 '15 at 14:20
  • Hack or not this IS the best solution to get around something that can't be described as anything short of a bug, I used @XmlAccessorType(XmlAccessType.FIELD) which was mostly ignored and adding @XmlTransient to each property was the only way to repair this problem. Thanks! – Ralph Ritoch Sep 02 '16 at 12:36
0

Many solutions have been given, and the internals are briefly touched by @Sriram and @ptomli as well. I just want to add a few references to the source code to help understand what is happening under the hood.

By default (i.e. no extra annotations used at all except @XmlRootElement on the root class), JABX tries to marshal things exposed via two ways:

  1. public fields
  2. getter methods that are named following the convention and have a corresponding setter method.

Notice that if a field is (or method returns) null, it will not be written into the output.

Now if @XmlElement is used, non-public things (could be fields or getter methods) can be marshalled as well.

But the two ways, i.e. fields and getter-methods, must not conflict with each other. Otherwise you get the exception.

wlnirvana
  • 1,811
  • 20
  • 36