barbitoff programmer`s blog

Здесь я публикую заметки из программерской жизни: грабли, на которые мне случилось наступить, проблемы, для которых было найдено элегантное (или не очень) решение, а также все, с чем мне пришлось столкнуться и чем хотелось бы поделиться =)
PS Если хотите меня поблагодарить - на странице есть 3 места, чтобы это сделать =)

пятница, 28 декабря 2012 г.

com.sun.istack.internal.SAXException2: unable to marshal type as an element because it is not known to this context

Проблема:

Есть набор классов, сгенерированных wsimport`ом. Расположены эти классы в пакете "my.package". В проекте в этот же пакет добавлен ещё один класс "MyExtraClass", и есть желание выполнить его маршаллизацию:
MyExtraClass obj = new MyExtraClass();
...
JAXBContext jc = JAXBContext.newInstance("my.package");
Marshaller marshaller = jc.createMarshaller();
StringWriter xmlWriter = new StringWriter();
marshaller.marshal(obj, xmlWriter); 
Однако, последний вызов валится с исключением:
com.sun.istack.internal.SAXException2: unable to marshal type "my.package.MyExtraClass" as an element because it is not known to this context
Т.е., по-видимому, JAXB этого класса по какой-то причине не видит.

Причина:

wsimport, помимо классов, соответствующих XML-типам, сгенерировал в пакете my.package также класс ObjectFactory, определяющий, какие классы будут известны JAXB-контексту. Естественно, эта ObjectFactory о новом классе MyExtraClass ничего не знает, поэтому ничего о нем не знает и JAXB-контекст.

Решение:

Т.к. ObjectFactory менять не хочется, он ведь генерируется при компиляции автоматически, нужно добавить наш MyExtraClass в JAXB-контекст каким-то другим способом. Для этого подойдет такой вариант:
  1. Создать в пакете "my.package" файл "jaxb.index"
  2. Записать в этот файл название нашего класса, без указания пакета, т.е. просто:
    MyExtraClass
Все, теперь класс будет маршаллизироваться без проблем.

Комментариев нет:

Отправить комментарий