Why does JAXB put @XmlRootElement sometimes but not always

3 篇文章 0 订阅

https://weblogs.java.net/blog/kohsuke/archive/2006/03/why_does_jaxb_p.html

Posted by kohsuke on March 3, 2006 at 4:21 PM PST

isusanin asked in the JAXB forum:

When trying to marshall an object I get this error message:

unable to marshal type "org.blah.MessageType" as an element
because it is missing an @XmlRootElement annotation

If I add the @XmlRootElement annotation to the MessageType, it works, but my question is why doesn't the JAXB compiler put this annotation in automatically. It's inconvenient because MessageType is automatically generated and I don't want to edit it every time I regenerate the java classes.

Is there any better way to resolve this problem?

XJC does try to put @XmlRootElement annotation on a class that we generate from a complex type. The exact condition is somewhat ugly, but the basic idea is that if we can statically guarantee that a complex type won't be used by multiple different tag names, we put @XmlRootElement. So for example, if the schema is as follows:


<schema>
  <element name="foo">
    <complextype>
      ...
    </complextype>
  </element>
</schema>

Then you'd get:

@XmlRootElement
class Foo {
  ...
}

But if the schema is as follows, then XJC can't eliminate the possibility that your type might be used in other schemas (that can be compiled separately and put together at runtime):


<schema>
  <element name="foo" type="bar">
  <complextype name="bar">
</complextype></element></schema>
So you'd get:
class Bar {
}
class ObjectFactory {
  JAXBElement<Bar> createFoo(Bar value) { ... }
}

Now, the crucial part in the above inference done by XJC is that "your schema might be used by other schemas that XJC isn't compiling right now". This is certainly true for some users (and we learned that the hard way), but it's also true that for many users this is too conservative an assumption. It's often the case that what you are compiling is indeed the whole thing, and you want XJC to know that so that it can optimize the generated code more aggressively.

Such notion isn't defined in the spec, but as an experiment we have such aggressive optimization mode in XJC, tentatively called "simple-minded binding mode". Consider the following schema that uses this mode (see that customization):


&lt;xs:schema xmlns:xs=&quot;
http://www.w3.org/2001/XMLSchema"<br
 /&gt;  xmlns:jaxb=&quot;
http://java.sun.com/xml/ns/jaxb"<br
 /&gt;  jaxb:version=&quot;1.0&quot;
  xmlns:xjc=&quot;
http://java.sun.com/xml/ns/jaxb/xjc"<br
 /&gt;  jaxb:extensionBindingPrefixes=&quot;xjc&quot;&gt;
  <xs:annotation>
    <xs:appinfo>
      <jaxb:globalbindings>
        <xjc:simple>
      </xjc:simple></jaxb:globalbindings>
    </xs:appinfo>
  </xs:annotation>
  
  <xs:element name="foo" type="bar">
  <xs:complextype name="bar">

</xs:complextype></xs:element>

From this you'll just get Foo class, since XJC now knows that only one element is using bar, and therefore there's no point in having two of them around (I just fixed a few issues wrt this, so if you want to try it, wait until tomorrow and download nightly.) Also note that this is an experimental mode and it is subject to change.

Now, that said, there's another way to work around this issue. If all you want is just to marshal an object without @XmlRootElement, then you can just do:

marshaller.marshal( new JAXBElement(
  new QName("uri","local"), MessageType.class, messageType ));

 

 

 

====

With a Maven build, you can add the @XmlRootElement annotation with the "jaxb2-basics-annotate" plug-in.

See more information :
http://codereview.stackexchange.com/questions/1877/jaxb-xjc-code-generation-adding-xmlrootelement-and-joda-datetime

http://azagorneanu.blogspot.be/2011/09/configure-maven-to-generate-classes.html

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值