3

I built a simple Spring3, Hibernate3/(JPA2), RESTful service, hosted on Tomcat6, that uses JAXB2 to marshal the results. (It uses annotated pojos.) I needed to use specific namespace prefixes, so I wrote a custom com.sun.xml.bind.marshaller.NamespacePrefixMapper. I included the JAXB2 RI jars with my application and everything worked fine.

Then someone said that's great, we need to host it under WebLogic 11g (10.3.3) too. No problem, I created the special weblogic deployment descriptors to prefer the application jars, renamed my persistence.xml, and wrapped the WAR in an EAR with the JPA2 jars. It worked great, almost.

Unfortunately, our WebLogic server runs a custom security realm that also uses JAXB and causes conflicts with my application. So I dropped the JAXB jars from the app and it runs fine in WebLogic. Of course it no longer runs under Tomcat unless I add the JAXB jars to Tomcat. I'd like to avoid that.

So my questions... I've read quite a few posts on stackoverflow that contain a lot of opinions/disagreements regarding the use of the sun "internal" JAXB2 implementation vs. packaging the RI with your app. Is there not yet a clean solution to this problem? Does my stack support another way to custom map my namespace prefixes without including the JAXB2 RI? Can I safely use the Java6 "internal" JAXB NamespacePrefixMapper, or will that come and go with various Java releases? Does Spring3 offer another solution? What's the true story on the Java6 JAXB2 implementation? Is it only there for Sun's (Oracle's) internal use?

Thanks.

John
  • 101
  • 1
  • 7
  • JAXB 2.1 is included with JDK 6 since JDK 6 Update 4. If the application server is running JDK 6, why do you need to add the JAXB2 RI jars to your application? – Chin Huang Jan 04 '11 at 23:20
  • @Chin: When you use the RI, you can also safely use the `com.sun.xml` classes that come with it, like `NamespacePrefixMapper`. If you use the built-in Java6 JAXB, you have to use the `com.sun.xml.internal` packages, which is highly inadvisable. – skaffman Jan 04 '11 at 23:42
  • @John: See the accepted answer to this question for a possible solution: http://stackoverflow.com/questions/1982977/is-it-possible-to-customize-the-namespace-prefix-that-jaxb-uses-when-marshalling – skaffman Jan 04 '11 at 23:46
  • http://stackoverflow.com/questions/2326107/what-happened-to-jaxbs-namespaceprefixmapper-in-jdk6u18/2326480#2326480 – Bozho Jan 05 '11 at 09:15
  • 1
    @skaffman: Thanks, but I can't see http://www.func.nl/community/knowledgebase/customize-namespace-prefix-when-marshalling-jaxb from work. (It's blocked.) Can you give me the gist? Does it avoid the NamespacePrefixMapper altogether? – John Jan 05 '11 at 12:36
  • @John: Ok, I've parroted it as an answer. – skaffman Jan 05 '11 at 12:42
  • @Bozho: Thanks. It's been nearly a year since you wrote: "there is no better way to do this, and this is an essential feature." I hoped that by now, someone at "Sun" would have sorted this out. – John Jan 05 '11 at 19:27

2 Answers2

0

As mentioned in the comments, I'll summarise what is mentioned in http://www.func.nl/community/knowledgebase/customize-namespace-prefix-when-marshalling-jaxb.

Note: I haven't tried this myself, so it may not work.

Essentially, you configure the JAXB marshaller to use an XMLStreamWriter when marshalling, and you configure that to map prefixes, e.g.

XMLStreamWriter xmlStreamWriter = XMLOutputFactory.newInstance().createXMLStreamWriter(writer);
xmlStreamWriter.setPrefix("func", "http://www.func.nl");

JAXBContext context = JAXBContext.newInstance(object.getClass());
Marshaller marshaller = context.createMarshaller();

marshaller.marshal(object, xmlStreamWriter);

The idea is that if JAXB hasn't been given a prefix mapper, then it'll leave it up to the XMLStreamWriter to handle the prefixes, and by doing the above, you're telling it how to do it.

Again: I'm just repeating the content from the website that's blocked from your network, so I take no credit for it being right, and no blame for it being wrong.

skaffman
  • 398,947
  • 96
  • 818
  • 769
  • 1
    Thanks skaffman. I hadn't tried the XMLStreamWriter. It requires a lot more code than just "return myPojo;", but if it avoids including the JAXB2 RI or using "internal" packages it would at least let the same application run in both Tomcat and WebLogic. I'd still like to know the answers to my questions. – John Jan 05 '11 at 13:28
  • I tried this solution, but ran into some problems because it prevents the marshaller from defining the namespaces and prefixes in the opening document element. So I got a friend to open the link and email me the contents of the entire post, and this solution also requires rolling a custom marshaller too. (My friend hasn't sent the code to me yet.) I really don't think this is what the creators had in mind. But thank you so much for your efforts. – John Jan 05 '11 at 17:37
  • Does anyone from "Sun" or SpringSource ever participate in this forum? This is a remarkable problem. So far, I have a small collection of workaround hacks, but no proper solution. Perhaps I can include the JAXB2 RI in my app, but somehow not cause a conflict with my security realm in WebLogic. – John Jan 05 '11 at 17:40
  • 1
    @John: It was worth a try. It's not really a big problem, though, since namespace prefixes shouldn't matter. Cosmetics aside, anything that requires a specific prefix is kinda broken. – skaffman Jan 05 '11 at 17:41
  • I completely agree that the prefixes should be completely arbitrary... in theory. In practice unfortunately, they are not. In my case, the difference between ns1, ns2,... and rdf, georss, etc... is the difference between IE, Firefox, and my client seeing an ordinary XML document and seeing an RSS feed. Again, I appreciate the lead. – John Jan 05 '11 at 17:48
0

The EclipseLink JAXB (MOXy) will use the namespace prefixes as declared in the @XmlSchema annotation.

For more information see:

Community
  • 1
  • 1
bdoughan
  • 147,609
  • 23
  • 300
  • 400