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 the application is lengthy, there are ways to reduce the amount of time the system spends creating the JAXBContext for the application.
Creation of the JAXBContext object can be divided into three steps.
- Create 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 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, we 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.
- 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, we must decide which approach to use based on your goals.
- Starting the JAXBContext.newInstance() which actually creates the JAXBContext object.
Completing the following actions might reduce the amount of time 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 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. 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 we 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 we provide the list of JAXB classes in the ObjectFactory class or a jaxb.index file, no search for JAXB classes is required.
Use a list of packages provides the greater performance improvement might require you to manually create jaxb.index files and changes to the application. If we decide to use this approach, we 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 we 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.
Use a jaxb.index file requires us 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, we must:
- 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.
- 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 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 v7.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, we 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 classesTo overcome this error, we can:
- Create two different EAR files, one without the somepackage.jaxws jaxb.index file for use with v7.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 to use a single EAR file for both versions of the product. If we use this option, we 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.
trns
- If the JAXBContext.newInstance() itself takes a long time to complete, we 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 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 is 0. If set to 0, the cache is not used.
- jaxws.JAXBContext.permStoreMaxSize
- Set to the maximum number of entries we want maintained in the cache. The default 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 to the length of time, in hours, that we 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 is 24 hours.
Web services specifications and APIs Java virtual machine custom properties