Page 1 of 1

docx4j and google app engine GAE

PostPosted: Sat Jun 25, 2011 5:14 am
by robm
I've been trying to make this work today and have hit what I suspected might be a critical problem. My environment is eclipse, GWT 2.3, GAE SDK 1.5. I wrote a simple servlet that takes no input, builds a new docx using parts of the supplied samples and then attempts to 'save' the output using some code found elsewhere on this forum like this:

SaveToZipFile saver = new SaveToZipFile(wordMLPackage);
try {
saver.save( response.getOutputStream() );
} catch (Docx4JException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

Somewhere in save(response.getOutputStream()) it accesses something which causes:

Code: Select all
java.security.AccessControlException: access denied (java.lang.RuntimePermission accessClassInPackage.com.sun.xml.internal.bind.marshaller)
   at java.security.AccessControlContext.checkPermission(AccessControlContext.java:374)
   at java.security.AccessController.checkPermission(AccessController.java:546)
   at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
   at com.google.appengine.tools.development.DevAppServerFactory$CustomSecurityManager.checkPermission(DevAppServerFactory.java:166)
   at java.lang.SecurityManager.checkPackageAccess(SecurityManager.java:1512)
   at java.lang.ClassLoader$1.run(ClassLoader.java:331)
   at java.security.AccessController.doPrivileged(Native Method)
   at java.lang.ClassLoader.checkPackageAccess(ClassLoader.java:329)
   at java.lang.ClassLoader.defineClass1(Native Method)
   at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
   at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
   at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
   at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
   at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
   at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
   at java.security.AccessController.doPrivileged(Native Method)
   at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
   at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
   at com.google.appengine.tools.development.IsolatedAppClassLoader.loadClass(IsolatedAppClassLoader.java:176)
   at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
   at org.docx4j.jaxb.NamespacePrefixMapperUtils.getPrefixMapper(NamespacePrefixMapperUtils.java:47)
   at org.docx4j.openpackaging.contenttype.ContentTypeManager.marshal(ContentTypeManager.java:738)
   at org.docx4j.openpackaging.io.SaveToZipFile.save(SaveToZipFile.java:139)



According to the GWT forums, this error means I'm trying to access a class that is not allowed while running on GAE - where this app will be hosted eventually.

Questions:
1. Is my analysis correct? Anyone have docx4j working on GAE?
2. Is there any way to modify the code to make it GAE compliant - ideas? Notice that the location of the error is org.docx4j.jaxb.Namespace... and jaxb is whitelisted.
3. I'm using the Java 6 'built in' JAXB, not the RI. There are some posts from a year ago that RI 2.2 doesn't work and you need to go back to RI 2.1.x. How can I specify which JAXB version to use from within docx4j?

Thanks in advance!
Rob

Re: docx4j and google app engine GAE

PostPosted: Sat Jun 25, 2011 10:49 am
by jason
I've previously run docx4j on GAE. But that was last year, starting 18 months ago.

I used my own version of JAXB ie I renamed the packages to something like gae.whatever.

Google have since claimed support for JAXb ie added it to the white(?)list. There is a GAE issue specifically on this. However, it didn't work for me when I tried it, though I didn't spend too long on it.

The main issue I had with GAE generally is initial startup; getting the JAXB context loaded before GAE terminates the process saying it is taking too long. Recent changes to GAE may have made this less of an issue.

Your error is in saving your pkg as a docx; so I take it you were able to either load or create one, which would mean you are mostly there. Perhaps you will need to remove docx4j's namespace mapping?

Basically, docx4j will use whichever JAXB it finds on the classpath; with Java 6 that means whatever is built in, unless the endorsed dir override mechanism is used. See also the org.docx4j.jaxb.Context source.

Re: docx4j and google app engine GAE

PostPosted: Sat Jun 25, 2011 11:06 am
by robm
Hi Jason
Thanks for responding so quickly. I'm not running on GAE quite yet, just on the development environment that simulates it.

Come to think of it, using JAXB has probably added a few seconds to startup in the dev environment, possibly 5-10. There are reports on the net of it taking 30 seconds to create a context (possibly for very large documents). This scared me off and I tried a non-JAXB approach this afternoon which looks promising and simpler. I control the docx 'template' and just need to add stuff to it. I'm going to add some unique tags and do string replacements, then use the java zip classes which are whitelisted to zip it up.

What do you mean by 'remove docx4j's namespace mapping'? Do you mean an xmlns= line in an xml file? I'll read the reference you gave me too. Thanks.

Rob

BTW - docx4j looks very thorough -great work.

Re: docx4j and google app engine GAE

PostPosted: Sat Jun 25, 2011 5:46 pm
by jason
Hi Rob,

Yes if your needs are that simple, you can avoid JAXB and docx4j altogether :-)

Fingers crossed you won't want HTML and/or PDF preview/output!

robm wrote:What do you mean by 'remove docx4j's namespace mapping'?


I meant delete org.docx4j.jaxb.NamespacePrefixMapperUtils et al and references thereto from the docx4j source tree.

All this does is give you nice namespace prefixes, eg 'w:', instead of say "ns1:'

cheers .. Jason

Re: docx4j and google app engine GAE

PostPosted: Tue Jun 28, 2011 3:30 am
by robm
Hi Jason

Oh, I'm sure the requirements will eventually include html preview and pdf generation.... But for now I can move forward this way. Ideally docx4j would work on GAE/GWT and GAE would maintain a cache of servlet containers pre-loaded with JAXB and docx4j and offer a conversion service so I don't incur the cost/time penalties of JAXB context initialization etc. From what I have found so far, docx4j is state of the art in this area (manipulating docx from java)

Have you ever considered making a client side version that used javascript and the browser for xml parsing rather than Java/JAXB? With the new ability for HTML5 browsers to save locally there might be more interest in client side solutions, especially since Windows 8 is pushing JS/HTML5/CSS3.

All the best
Rob