[Solved]: Exception in thread “main” com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 3 counts of IllegalAnnotationExceptions

This exception occur when you are using JAXB to marshal a java object (collection type) to xml format. The stack trace looks like this:

Exception in thread "main" com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
Class has two properties of the same name "employees"
	this problem is related to the following location:
		at public java.util.List com.howtodoinjava.jaxb.examples.list.Employees.getEmployees()
		at com.howtodoinjava.jaxb.examples.list.Employees
	this problem is related to the following location:
		at private java.util.List com.howtodoinjava.jaxb.examples.list.Employees.employees
		at com.howtodoinjava.jaxb.examples.list.Employees

	at com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException$Builder.check(Unknown Source)
	at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(Unknown Source)
	at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(Unknown Source)
	at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(Unknown Source)
	at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(Unknown Source)
	..... more

OR

Exception in thread "main" com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 3 counts of IllegalAnnotationExceptions
java.util.Map is an interface, and JAXB can't handle interfaces.
	this problem is related to the following location:
		at java.util.Map
		at private java.util.Map com.howtodoinjava.jaxb.examples.map.EmployeeMap.employeeMap
		at com.howtodoinjava.jaxb.examples.map.EmployeeMap
java.util.Map does not have a no-arg default constructor.
	this problem is related to the following location:
		at java.util.Map
		at private java.util.Map com.howtodoinjava.jaxb.examples.map.EmployeeMap.employeeMap
		at com.howtodoinjava.jaxb.examples.map.EmployeeMap
Class has two properties of the same name "employeeMap"
	this problem is related to the following location:
		at public java.util.Map com.howtodoinjava.jaxb.examples.map.EmployeeMap.getEmployeeMap()
		at com.howtodoinjava.jaxb.examples.map.EmployeeMap
	this problem is related to the following location:
		at private java.util.Map com.howtodoinjava.jaxb.examples.map.EmployeeMap.employeeMap
		at com.howtodoinjava.jaxb.examples.map.EmployeeMap
	......more
Random exceptions
Random exceptions

Reason

The above exception occurs mostly because of absence of @XmlAccessType annotation or invalid use of @XmlAccessType with @XxmlElement annotation. The correct usage is such that one java field should have only one effective JAXB annotation which represents its metadata.

By default JAXB includes all public fields and getters for marshalling. So if you have a field, and its getter that this will get included two times. This is error and needs to be solved with correct usage of annotations.

Solution : Use @XmlAccessType annotation

1) @XmlAccessorType (XmlAccessType.FIELD)

If you are using XmlAccessType.FIELD; then only all public fields (non-static) will be automatically included for marshalling. No getter will be considered. So, if will remove the duplicate problem. e.g. In below code, both employees and size fields will be included.

Note that “@XmlElement(name=”employee”)” is optional; I have used it to rename the xml nodes in output xml. If you remove it; there will not be any marshalling error or exception.

@XmlRootElement(name = "employees")
@XmlAccessorType (XmlAccessType.FIELD)
public class Employees 
{
	@XmlElement(name="employee")
	private List<Employee> employees = null;
	
	private Integer size;

	public List<Employee> getEmployees() {
		return employees;
	}
	public void setEmployees(List<Employee> employees) {
		this.employees = employees;
	}
	public Integer getSize() {
		return size;
	}
	public void setSize(Integer size) {
		this.size = size;
	}
}

2) @XmlAccessorType (XmlAccessType.NONE)

If you are using “XmlAccessType.NONE” then it means you must annotate all fields which you want to marshal in output XML. Any field left will not be included in JAXB context. So essentially, @XmlElement annotation is required on both “employees” and “size” fields. If any of both field is not annotated with @XmlElement, that will not be marshalled.

@XmlRootElement(name = "employees")
@XmlAccessorType (XmlAccessType.NONE)
public class Employees 
{
	@XmlElement(name="employee")
	private List<Employee> employees = null;
	
	@XmlElement(name="size")
	private Integer size;

	public List<Employee> getEmployees() {
		return employees;
	}
	public void setEmployees(List<Employee> employees) {
		this.employees = employees;
	}
	public Integer getSize() {
		return size;
	}
	public void setSize(Integer size) {
		this.size = size;
	}
}


Happy Learning !!

Was this post helpful?

Join 7000+ Fellow Programmers

Subscribe to get new post notifications, industry updates, best practices, and much more. Directly into your inbox, for free.

15 thoughts on “[Solved]: Exception in thread “main” com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 3 counts of IllegalAnnotationExceptions”

  1. I just wanted to mention that the annotation @XMLTransient actually lists in it’s description this very situation. That is, a collision between the getter and the field name.
    By annotating the field with @XMLTransient you will cause JAXB to ignore it during the marshalling process.
    That eliminates this error by giving the marshall process only one “field” with that name.

    Open Declaration javax.xml.bind.annotation.XmlTransient

    @Target(value={FIELD, METHOD, TYPE})
    @Retention(value=RUNTIME)

    Prevents the mapping of a JavaBean property/type to XML representation.
    The @XmlTransient annotation is useful for resolving name collisions between a JavaBean property name and a field name or preventing the mapping of a field/property. A name collision can occur when the decapitalized JavaBean property name and a field name are the same. If the JavaBean property refers to the field,then the name collision can be resolved by preventing the mapping of either the field or the JavaBean property using the @XmlTransient annotation.

    When placed on a class, it indicates that the class shouldn’t be mapped to XML by itself. Properties on such class will be mapped to XML alongwith its derived classes, as if the class is inlined.

    Usage

    The @XmlTransient annotation can be used with the following program elements:
    • a JavaBean property
    • field
    • class

    @XmlTransientis mutually exclusive with all other JAXB defined annotations.

    See “Package Specification” in javax.xml.bind.package javadoc for additional common information.

    Example: Resolve name collision between JavaBean property and field name
    // Example: Code fragment

       public class USAddress {
    
           // The field name "name" collides with the property name
           // obtained by bean decapitalization of getName() below
           @XmlTransient public String name;
    
           String getName() {..};
           String setName() {..};
       }
    

    Since:JAXB2.0

    Reply
  2. xmlrootelement xmlaccessortype xmltype what is the proper order.

    because when I remove xmltype then I am getting proper xml but I want in the proper order.

    please help me on this

    Reply
  3. @XmlElementWrapper(name=”Users”)
    @XmlElement(name=”User”)
    @XmlAttribute(name=”id”)

    the above annotation is throwing exeception [com.sun.xml.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:102),.

    As soon as I remove the @XmlAttribute(name=”id”) the error goes off. but I want the output like

    Reply
  4. I am getting the following exeception [com.sun.xml.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:102),

    Reply
  5. [9/8/14 16:02:55:768 EDT] 0000000b WadlApplicati W 3 counts of IllegalAnnotationExceptions
    com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 3 counts of IllegalAnnotationExceptions
    javax.xml.namespace.QName does not have a no-arg default constructor.
    this problem is related to the following location:
    at javax.xml.namespace.QName
    at protected javax.xml.namespace.QName com.sun.research.ws.wadl.Param.type
    at com.sun.research.ws.wadl.Param
    at protected java.util.List com.sun.research.ws.wadl.Response.param
    at com.sun.research.ws.wadl.Response
    at public com.sun.research.ws.wadl.Response com.sun.research.ws.wadl.ObjectFactory.createResponse()
    at com.sun.research.ws.wadl.ObjectFactory
    @XmlAttribute/@XmlValue need to reference a Java type that maps to text in XML.
    this problem is related to the following location:

    Reply

Leave a Comment

HowToDoInJava

A blog about Java and its related technologies, the best practices, algorithms, interview questions, scripting languages, and Python.