Skip to main content

Using JAXB annotations to map a Map of Lists

2 replies [Last post]
jmcdowall
Offline
Joined: 2006-01-30
Points: 0

Hi,

I am new to JAXB. I am trying to annotate a class which has a field which Map of Lists. I tried a simpler class containing a Map of Strings using an extension of XmlAdapter (copied from an example) and that worked fine, but now when I try to use instances of ArrayList as the value for items in my Map I get this error at runtime:

javax.xml.bind.JAXBException: java.util.ArrayList nor any of its super class is known to this context

Can anybody help?

Thanks,

John

Here is my code:

------------
Config.java

package jaxbtrial;

import java.util.*;

import javax.xml.bind.annotation.*;

@XmlAccessorType(AccessType.FIELD)
@XmlType(propOrder={"lists"})
@XmlRootElement(name = "Config")
public class Config
{
@XmlJavaTypeAdapter(jaxbtrial.NameListPairAdapter.class)
@XmlElement(name = "Lists")
private HashMap> lists;

public Config()
{
lists = new HashMap>();
List list = new ArrayList();
lists.put("list0", list);
list.add("foo");
list.add("bar");
}
}

------------
NameListPairAdapter.java

package jaxbtrial;

import java.util.*;
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.*;
import jaxbtrial.*;

public class NameListPairAdapter
extends XmlAdapter>>
{

@Override public Map unmarshal(NameValuePair[] pairs)
{
Map map = new HashMap();
for (NameValuePair pair : pairs)
{
map.put(pair.name, pair.value);
}
return map;
}

@Override public NameValuePair[] marshal(Map> map)
{
NameValuePair[] pairs = new NameValuePair[map.size()];
int i = 0;
for(Map.Entry> entry : map.entrySet())
{
pairs[i++] = new NameValuePair(entry.getKey(), entry.getValue());
}
return pairs;
}
}
------------
NameListPair.java

package jaxbtrial;

import java.util.*;

import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.*;

public class NameListPair
{
@XmlElement
public String name;

@XmlElement
public List list;

public NameListPair()
{
}

public NameListPair(String name, List list)
{
this.name = name;
this.list = list;
}
}

------------
jaxb.index

Config

-----------
A main method

public static void main(String[] args)
{
Config config = new Config();

try
{
JAXBContext jaxbContext = JAXBContext.newInstance("jaxbtrial");
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, new Boolean(true));
marshaller.marshal(config, new FileOutputStream("c:\\jaxbOutput.xml"));
}
catch (Exception ex)
{
ex.printStackTrace();
}
}

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
kohsuke
Offline
Joined: 2003-06-09
Points: 0

It would be great if you can file this as an issue on http://jaxb.dev.java.net/ issue tracker. That would make it much easier for us to see the problem.

When you do that, please also attach the stack trace you are seeing.

Thanks!

yahamid
Offline
Joined: 2006-05-18
Points: 0

I had also the same error when my root object was composed of several List objects. Even though I changes the implementation from ArrayList to Vectors, I still had the same error. Then I realized that instead of using the addAll() method to add lists to my root object, I was using the add() method.
The latter method takes Object as argument, and while the List is also an Object, the addAll() is designed for adding Collection objects. This iss not a bug of JAXB but I will attribute it to the java compiler.