Reducing the time required to create the JAXBContext

A search of the classloader for potential JAXB classes is performed every time a web services application is started. If the search process for your application is lengthy, there are ways to reduce the amount of time the system spends creating the JAXBContext for your application.

Creation of the JAXBContext object can be divided into three steps.
  1. Creating the list of packages that might contain JAXB classes. The list is created based on the contents of the WSDL and annotations.
    There are no options to reduce the time that is required to create the list of packages. However, it is important to know that some corner cases and unique usage scenarios, might cause a package that does not contain JAXB classes to be included in the package list. Following is an example of a trace message that indicates a package is included that does not contain any JAXB classes:
    Here is an example trace that indicates this situation12/2/11 6:24:40:548 PST] 0000003e JAXBUtils 1 org.apache.axis2.jaxws.message.databinding.JAXBUtils createJAXBContextValue Package com.company.queryall.v1 does not have any JAXB classes. It is removed from the JAXB context path.

    For each occurrence of this message, you should include an empty jaxb.index file in the package to indicate that there are no JAXB classes. If this action is not taken, the time consuming JAXB class search occurs.

  2. Determining the signature of JAXBContext.newInstance() to be started. Because JAXBContext.newInstance() can be started with either a list of packages, or a list of JAXB classes, you must decide which approach to use based on your goals.
  3. Starting the JAXBContext.newInstance() which actually creates the JAXBContext object.

Completing the following actions might reduce the amount of time that is required to create the JAXBContext

  • Enable the persistent cache of the JAXB search results. To enable the persistent cache of search results for each package, set the com.ibm.ws.websvcs.getJAXBContext.cacheClassList.persist Java™ virtual machine (JVM) custom property to true.

    If any of the packages for a JAXBContext do not contain an ObjectFactory or jaxb.index file, a search of the classloader for potential JAXB classes for each package is performed. This search can be very time consuming when a large classloader is involved. You can use the com.ibm.ws.websvcs.getJAXBContext.cacheClassList.persist JVM custom property to permanently cache the search results for each package searched. Later JAXBContext requests use the cached list of classes instead of performing a new search of those packages.

    The cache is removed when an application is updated or uninstalled. While this approach might not improve performance as much as providing a list of packages, it does not require any changes to the application.

    This action is recommended as a first step even if you intend to use jaxb.index files.

  • Provide a jaxb.index file for every package that does not contain an ObjectFactory class. This action enables the system to completely avoid the search for JAXB classes. This approach does require application modification to account for the addition of the jaxb.index files.

    The list of packages that contain JAXB classes can be used when every package contains either an ObjectFactory class, or a jaxb.index file that specifies the JAXB classes for the package. When you provide the list of JAXB classes in the ObjectFactory class or a jaxb.index file, no search for JAXB classes is required.

    Using a list of packages provides the greater performance improvement might require you to manually create jaxb.index files and changes to the application. If you decide to use this approach, you can review the debug trace logs for does not contain an ObjectFactory messages to determine how many packages must be updated.

    A jaxb.index file can be used if you want the optimum performance and are willing to make changes to the application. The ObjectFactory class is normally created only with the top-down tool (wsimport). Therefore, any packages that are developed with bottom-up toolwsgen probably do not contain an ObjectFactory class. The jaxb.index file is used to identify the JAXB classes within the package and lessen the amount of time it takes for context creation. The JAXBContext.newInstance() method accepts jaxb.index files in the same way that it accepts the ObjectFactory class.

    Using a jaxb.index file requires you to evaluate all the instances in the trace file that indicate a package does not contain an ObjectFactory class, and create the appropriate jaxb.index file. After you search the trace for does not contain an ObjectFactory messages that indicate the packages that need the jaxb.index file, you must:
    1. Create a jaxb.index file with the list of JAXB classes. If the package does not contain any JAXB classes, an empty jaxb.index file must be placed in the package.
    2. Rerun the trace operation and ensure no does not contain an ObjectFactory messages still appear in the trace.

    If a required JAXB class is missed and not included in the jaxb.index file, an error occurs indicating the class is not known to the JAXBContext and the class should be added to the jaxb.index file.

    Every package that is used in a JAXBContext must have either an ObjectFactory class or a jaxb.index file to prevent the JAXB class search. This means that the trace files must be examined, and each instance of the missing ObjectFactory class or a jaxb.index file must be addressed. If any package for the JAXBContext is identified as not containing an ObjectFactory class or a jaxb.index file, the time consuming JAXB class search is performed. The format of the jaxb.index file is documented in the Oracle Javadoc for JAXBContext.newInstance() at http://docs.oracle.com/javaee/5/api/javax/xml/bind/JAXBContext.html.

    For transitioning users: In Version 7.0, even when wsgen is used to create the generated classes, they are not kept. However, the JAX-WS Specification 2.2, requires that generated classes must be kept. Therefore, wsgen places the generated classes in the packagename/jaxws directory. Therefore, the list of packages to search now includes packagename/jaxws, which does not exist in the EAR file. When this situation occurs, you receive an error message similar to the following message:
    6/21/12 17:07:36:477 CDT] 0000001a JAXBContextTr 1 org.apache.axis2.jaxws.message.databinding.JAXBUtils 
    createJAXBContextValue JAXBContextCreate: Package somepackage.jaxws does not contain an ObjectFactory 
    or package-info class. Searching for JAXB classes
    To overcome this error, you can:
    • Create two different EAR files, one without the somepackage.jaxws jaxb.index file for use with Version 7.0, and one with the somepackage.jaxws jaxb.index file for use with the current version of the product.
    • Add the generated classes and jaxb.index file to the EAR file if you want to use a single EAR file for both versions of the product. If you use this option, you should also include the WSDL with the generated classes.
    • Use the persistent cache instead of jaxb.index files. With this option JAX-RS still searches for JAXB classes one time per package, but it persists the results so it does not have to search again unless the application is updated.
  • If the JAXBContext.newInstance() itself takes a long time to complete, you can use the jaxws.JAXBContext.permStoreCostThresholdMsec JVM custom property to create a hard reference cache of JAXBContext objects that is not lost during garbage collection.

    There are not any options to change or improve the actual JAXBContext instance creation. The time spent to instantiate the context is affected by many factors, such as the number of JAXB classes, the number of packages, and the size of the class path. The JAXBContext created is held in a soft reference cache in memory. As a result, garbage collection might discard a JAXBContext if available memory becomes low. The next request that requires the discarded JAXBContext must then re-create the JAXBContext. While this recreation process is not significant for most JAXBContext, there are exceptions where the newInstance() step itself takes a significant amount of time.

    If the JAXBContext for an application has a large newInstance() creation times, consider using the following JVM custom properties to place the JAXBContext in a cache that persists until the JVM or application is restarted.

    jaxws.JAXBContext.permStoreCostThresholdMsec
    Set this property to a non-zero value in milliseconds. Contexts requiring more time than the specified amount of time to construct are cached. The recommended value is 5000 or greater. The default value is 0. If this property is set to 0, the cache is not used.
    jaxws.JAXBContext.permStoreMaxSize
    Set this property to the maximum number of entries you want maintained in the cache. The default value is 32. If the cache becomes full, the JAXBContext that requires the least amount of time to create is removed from the cache to make room for a JAXBContext with a longer creation time.
    jaxws.JAXBContext.permStoreStaleThresholdHours
    Set this property to the length of time, in hours, that you want entries to remain in the cache. Entries in the cache that have not been accessed after the specified number of hours are removed before newer entries being added in the cache. The default value is 24 hours.