{"id":201,"date":"2012-05-17T17:27:26","date_gmt":"2012-05-17T07:27:26","guid":{"rendered":"http:\/\/www.docx4java.org\/blog\/?p=201"},"modified":"2012-05-21T15:53:46","modified_gmt":"2012-05-21T05:53:46","slug":"jaxb-can-be-made-to-run-on-android","status":"publish","type":"post","link":"https:\/\/www.docx4java.org\/blog\/2012\/05\/jaxb-can-be-made-to-run-on-android\/","title":{"rendered":"JAXB can be made to run on Android"},"content":{"rendered":"<p>A customer asked me to prepare a sample Android project which converts docx to HTML.<\/p>\n<p>The result is <a href=\"https:\/\/github.com\/plutext\/AndroidDocxToHtml\">AndroidDocxToHtml<\/a><\/p>\n<p>Since docx4j relies heavily on JAXB, the key to getting it working was getting JAXB &#8211; the reference implementation &#8211; to run on Android.<\/p>\n<p>Android presents us with a number of challenges:<\/p>\n<ol>\n<li>it won&#8217;t let you add a jar which includes classes in the javax.xml namespace (which is where the JAXB API lives)<\/li>\n<li>JAXB uses JAXP 1.3 DatatypeFactory, but\u00a0Android doesn&#8217;t provide it<\/li>\n<li>JAXB uses javax.activation.DataHandler<\/li>\n<li>Dalvik has a limit of 65536 method references per dex file<\/li>\n<li>it doesn&#8217;t support package level annotations (which JAXB uses, and which in docx4j supply namespaces)<\/li>\n<\/ol>\n<p><strong>Ill-advised or mistaken usage of a core class (java.* or javax.*)<\/strong><\/p>\n<p>You&#8217;ll get this message if you try to add a jar containing classes in java.* or the following javax packages:<\/p>\n<div>\n<div>\n<div>\n<div><span style=\"font-family: 'Courier New';\">accessibility crypto imageio management naming<\/span><\/div>\n<\/div>\n<\/div>\n<\/div>\n<div>\n<div>\n<div>\n<div><span style=\"font-family: 'Courier New';\"> net print rmi security sound sql swing transaction<\/span><\/div>\n<\/div>\n<\/div>\n<\/div>\n<div>\n<div>\n<div>\n<div><span style=\"font-family: 'Courier New';\"> <strong>xml<\/strong><\/span><\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>Android doesn&#8217;t provide javax.xml.bind, and it won&#8217;t let you add it yourself. \u00a0It forces you to re-package it. \u00a0Just like on Google AppEngine, until Google eventually added it.<\/p>\n<p>OK, done that; see <a href=\"https:\/\/github.com\/plutext\/jaxb-2_2_5_1\/tree\/android2\">https:\/\/github.com\/plutext\/jaxb-2_2_5_1\/tree\/android2<\/a> (the 2 in android2 is meaningless)<\/p>\n<p>Repackaging is easy enough; the problem with it is that any library which uses the repackaged code, must also be changed. \u00a0In the case of docx4j, this means a new branch, and ongoing maintenance.<\/p>\n<p><strong>JAXB uses JAXP 1.3 DatatypeFactory, but\u00a0Android doesn&#8217;t provide it<\/strong><\/p>\n<p>com.sun.xml.bind invokes javax.xml.datatype.DatatypeFactory.newInstance, whereupon Android \u00a0throws\u00a0\u00a0javax.xml.datatype.DatatypeConfigurationException: Provider org.apache.xerces.jaxp.datatype.DatatypeFactoryImpl not found.<\/p>\n<p>Easy solution: jar it up and provide it.<\/p>\n<p><strong>JAXB uses javax.activation.DataHandler<\/strong><\/p>\n<p>Easy solution: use the activation and additionnal jars from <a href=\"http:\/\/code.google.com\/p\/javamail-android\/downloads\/list\">http:\/\/code.google.com\/p\/javamail-android\/downloads\/list<\/a><\/p>\n<p><strong>Dalvik \u00a0limit of 65536 method references per dex file<\/strong><\/p>\n<p>This is more an issue running docx4j on Android than one related to JAXB, but it is worth noting. \u00a0We&#8217;re running very close to this limit. \u00a0Vote for the issue at <a href=\"http:\/\/code.google.com\/p\/android\/issues\/detail?id=7147\">http:\/\/code.google.com\/p\/android\/issues\/detail?id=7147<\/a><\/p>\n<p>Also, you may need to give Eclipse more heap space\u00a0\u00a0(symptom is &#8216;you get Unable to execute dex: Java heap space&#8217;). \u00a0 In\u00a0eclipse.ini,\u00a0I used:<\/p>\n<p>-Xms256m<\/p>\n<p>-Xmx4096m<\/p>\n<p>In Eclipse, Windows &gt; Preferences &gt; General &gt; Show Heap Status gives you an entry on the bottom row which is useful.<\/p>\n<p><strong>Just when I thought it would all work&#8230;<\/strong><\/p>\n<p>I found that my XML was not unmarshalling, because it contains namespaces, and for some reason the objects in my JAXB were being read as not having any.<\/p>\n<p>The problem is that Android doesn&#8217;t support package annotations: <a href=\"http:\/\/code.google.com\/p\/android\/issues\/detail?id=16149\">http:\/\/code.google.com\/p\/android\/issues\/detail?id=16149<\/a> (vote), but JAXB needs to read them. \u00a0For example:<\/p>\n<div><span style=\"font-family: Consolas; color: #646464; font-size: x-small;\">@<\/span><span style=\"font-family: Consolas; font-size: x-small;\">javax.xml.bind.annotation.<\/span><span style=\"font-family: Consolas; color: #646464; font-size: x-small;\">XmlSchema<\/span><span style=\"font-family: Consolas; font-size: x-small;\">(namespace = <\/span><span style=\"font-family: Consolas; color: #2a00ff; font-size: x-small;\">&#8220;http:\/\/schemas.openxmlformats.org\/package\/2006\/relationships&#8221;<\/span><span style=\"font-family: Consolas; font-size: x-small;\">, elementFormDefault = javax.xml.bind.annotation.XmlNsForm.<\/span><span style=\"font-family: Consolas; color: #0000c0; font-size: x-small;\"><em>QUALIFIED<\/em><\/span><span style=\"font-family: Consolas; font-size: x-small;\">)<\/span><\/div>\n<p>I ended up devising a simple minded way to tell JAXB about these programmatically. \u00a0See <a href=\"https:\/\/github.com\/plutext\/docx4j\/blob\/android\/src\/main\/java\/org\/docx4j\/jaxb\/Context.java\">Context.java<\/a>. \u00a0 Hmmm, I probably should have created my own RuntimeInlineAnnotationReader implementation (Google &#8216;JAXBIntroductions&#8217;).<\/p>\n<p>That done, it more or less works (if you need support for other package level annotations, you&#8217;ve got a bit more to do). \u00a0 The re-packaged JAXB is <a href=\"https:\/\/github.com\/plutext\/jaxb-2_2_5_1\/tree\/android2\">here<\/a>. \u00a0You can build it using <strong>ant -f build-repackaged.xml dist<\/strong><\/p>\n<p>It should work on Android 3 or 4.<\/p>\n<p>To use it, where your code would otherwise import javax.xml.bind, use <strong>ae.<\/strong>java.xml.bind.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A customer asked me to prepare a sample Android project which converts docx to HTML. The result is AndroidDocxToHtml Since docx4j relies heavily on JAXB, the key to getting it working was getting JAXB &#8211; the reference implementation &#8211; to run on Android. Android presents us with a number of challenges: it won&#8217;t let you [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[83,84,16],"class_list":["post-201","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-android","tag-dalvik","tag-jaxb"],"_links":{"self":[{"href":"https:\/\/www.docx4java.org\/blog\/wp-json\/wp\/v2\/posts\/201","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.docx4java.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.docx4java.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.docx4java.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.docx4java.org\/blog\/wp-json\/wp\/v2\/comments?post=201"}],"version-history":[{"count":6,"href":"https:\/\/www.docx4java.org\/blog\/wp-json\/wp\/v2\/posts\/201\/revisions"}],"predecessor-version":[{"id":203,"href":"https:\/\/www.docx4java.org\/blog\/wp-json\/wp\/v2\/posts\/201\/revisions\/203"}],"wp:attachment":[{"href":"https:\/\/www.docx4java.org\/blog\/wp-json\/wp\/v2\/media?parent=201"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.docx4java.org\/blog\/wp-json\/wp\/v2\/categories?post=201"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.docx4java.org\/blog\/wp-json\/wp\/v2\/tags?post=201"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}