Tags

, , , ,

In this post I will explain the changes you have to do to get JAXB running on GAE.

This has been discussed in one of the Google appengine developer forums and I think now GAE developers have included JAXB in  JRE whitelist too. But below I am going to tell the changes I have done to get my JAXB running on GAE (though it is not required for most of you as now there’s is a support already but for the interested ones below are the changes I had done)

Issues :

  1. FileOutputStream in com.sun.xml.bind.v2.runtime.MarshallerImpl and javax.xml.bind.helpers.AbstractMarshallerImpl
  2. use of AWT in com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl
  3. java.util.logging.ConsoleHandler, which is also not supported by Google App

Engine’s Java runtime environment, but used in javax.xml.bind.ContextFinder

Steps :

  1. Download JAXB source code from

https://jaxb.dev.java.net/2.1.11/jaxb-ri-2_1_11.src.zip

Put it in an Eclipse project at ~/workspace/jaxb-ri-2_1_11

2.    Build the runtime as we need to do this so that generated source gets generated.

3.    In com.sun.xml.bind.v2.model.impl.ReferencePropertyInfoImpl.java

Change

boolean isRequired(XmlElementRef ref)

to always return true.

As it deals with something related to compatibility issues in 2.2 API.

The same issue stops xjc subproject from building, but we don’t care about that.

To avoid that I changed the compile task in build.xml to read:

<target

depends=”init-standalone”

description=”compile runtime, and xjc sub-projects”>

<ant dir=”apgen”               target=”compile” />

<ant dir=”runtime”             target=”compile” />

<ant dir=”runtime-fi”          target=”compile” />

<ant dir=”runtime-staxex”      target=”compile” />

<ant dir=”runtime-deprecated”  target=”compile” />

<!–    <ant dir=”xjc”                 target=”compile” />

<ant dir=”tools”               target=”compile” /> –>

</target>

4.    Copy runtime/src and runtime/build/src to your GAE project [here called myproj] src dir

runtime/src$ cp com /home/dev/workspace/myproj/src/ -rR

runtime/build/src$ cp * /home/dev/workspace/myproj/src/ -rR

5. Find jaxb-api-src.zip in tools/lib/redist. It contains javax.xml.bind

Unzip that, and put it your myproject src dir

6.    Find jsr173_1.0_src.jar; it is in tools/lib/src.  This contains javax.xml.stream.XMLStreamWriter and XMLStreamException which we need but aren’t whitelisted.

Extract them and copy to myproject.

src tree should now include

/com/sun/xml/bind

/javax/xml/bind

/javax/xml/stream

7.    Add the missing jars

cp tools/lib/redist/jsr173_1.0_api.jar

/home/dev/workspace/myproj/war/WEB-INF/lib/

cp tools/lib/redist/activation.jar /home/dev/workspace/myproj/war/WEB-INF/lib/

cp tools/lib/rebundle/runtime2/*.jar /home/dev/workspace/myproj/war/WEB-INF/lib/

8.    Now fix the major issues :-

  • com.sun.xml.bind.v2.runtime.MarshallerImpl

Comment out the FileOutputStream part as we won’t have file for marshalling in our case

  • javax.xml.bind.helpers.AbstractMarshallerImpl

Comment out

void marshal(Object jaxbElement, File output)

as we won’t be dealing with marshalling of files and also its not supported J

  • com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl.java

As AWT is not supported so we have to comment out

PcdataImpl<Image>(Image.class, createXS(“base64Binary”))

convertToBufferedImage(Image image)

Base64Data print(Image v)

  • ae.javax.xml.bind.ContextFinder.java

As java.util.logging.ConsoleHandler is not supported comment out the logger part

9.    Exclude the classes  from validation (right click > Google > App Engine Settings >App Engine > Validation).  These are

  • com.sun.xml.bind.v2.runtime.property.SingleMapNodeProperty
  • com.sun.xml.bind.v2.util.TypeCast

Interestingly, the validator wonn’t complain about javax.xml.bind, now that it is in our source tree. And it’s enough for the app to start in the Jetty simulation environment.

But it will try to use the JAXB in Java 6, not the ones in my source tree.  So ename:

  • com.sun.xml.bind –> ae.com.sun.xml.bind
  • javax.xml.bind   –> ae.javax.xml.bind
  • javax.xml.stream   –> ae.javax.xml.stream

For JAXBContext: ae.com.sun.xml.bind.v2.runtime.JAXBContextImpl

For marshaller: ae.com.sun.xml.bind.v2.runtime.MarshallerImpl

10. Finally in ae.com.sun.xml.bind.v2.runtime.reflect.opt.Injector.java

Comment out

AccessController.doPrivileged(new PrivilegedAction<Void>() {

public Void run() {

defineClass.setAccessible(true);

resolveClass.setAccessible(true);

return null;

}

});

As it will cause create some security related issues.

This will make JAXB running on GAE.

Reference:

http://code.google.com/p/googleappengine/issues/detail?id=1267

Advertisements