JAXBContext initialization speedup?

Hans-Peter Störr picture Hans-Peter Störr · Apr 27, 2009 · Viewed 21.8k times · Source

Is there any way to speed up the initialization of javax.xml.bind.JAXBContexts with a large (>1000) number of classes? In our XML heavy application the startup time is some 10 minutes and consists mainly of the initialization time of the JAXBContexts. :-(

We are using Sun's JAXB implementation in the JDK 1.5 and the org.jvnet.jaxb2.maven2.maven-jaxb2-plugin for the code generation from XSDs.

Clarification: The problem is not that we have many instances of a JAXBContext with the same contextpaths, but the problem is that the initialization of one single JAXBContext takes tens of seconds since it has to load and process thousands of classes. (Our XSDs are fairly large and complicated.) All JAXBContext instances have different contextpaths - we cannot reduce the number further.

Answer

skaffman picture skaffman · Nov 23, 2009

The JAXB reference implementation has a sort-of-undocumented system property for exactly this reason:

-Dcom.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.fastBoot=true

or for old versions prior to the package refactoring:

-Dcom.sun.xml.bind.v2.runtime.JAXBContextImpl.fastBoot=true

This instructs JAXB to skip the expensive process of pre-caching the various reflection muscles it needs to do the job. Instead, it will do all the reflection when the context gets used. This makes for a slower runtime, but considerably faster initialization, especially for large numbers of classes.

However, one part of the speed problem is unavoidable, and that's the fact that JAXB has to load every single one of your classes, and classloading is slow. This is apparent if you create a 2nd context immediately after the first, with the same configuration - you'll see it's much, much faster, having already loaded the classes.

Also, you say that you have multiple JAXBContext instances because you have multiple contextpaths. Did you realise that you can put multiple context paths into a single context? You just need to pass them all as a semicolon-delimited string when you initialize the context, e.g.

JaxbContext.newInstance("a.b.c:x.y.z");

will load the contexts a.b.c and x.y.z. It likely won't make any difference to performance, though.