减少创建 JAXBContext 所需的时间
每当启动 Web Service 应用程序时,将搜索类装入器以查看是否存在潜在的 JAXB 类。当应用程序的搜索过程比较漫长时,有一些方法可减少系统为应用程序创建 JAXBContex 时花费的时间量。
- 创建软件包列表,这些软件包可能包含 JAXB 类。将根据 WSDL
和注释的内容创建该列表。没有任何选项可以减少创建软件包列表所需的时间。但是,某些隐蔽的情况和独特的使用方案可能会导致软件包列表中包括不包含 JAXB 类的软件包,了解这一点很重要。以下是跟踪消息的示例,该消息表示提供的软件包中不包含任何 JAXB 类:
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.
每次出现此消息时,您都应该在软件包中包括一个空的 jaxb.index 文件,以指示没有 JAXB 类。如果未执行此操作,那么将耗费时间来搜索 JAXB 类。
- 确定要启动的 JAXBContext.newInstance() 的特征符。由于可以通过软件包列表或 JAXB 类列表来启动 JAXBContext.newInstance(),所以您必须根据您的目标来决定要使用哪种方法。
- 启动 JAXBContext.newInstance(),它将实际创建 JAXBContext 对象。
完成以下操作可能会减少创建 JAXBContext 所需的时间量
- 启用 JAXB 搜索结果持久高速缓存。要对每个软件包都启用搜索结果持久高速缓存,请将
com.ibm.ws.websvcs.getJAXBContext.cacheClassList.persist
Java™ 虚拟机 (JVM) 定制属性设置为 true。
如果 JAXBContext 的任何软件包不包含 ObjectFactory 或 jaxb.index 文件,那么将搜索类装入器以获取每个软件包的潜在 JAXB 类。当涉及大型类装入器时,此搜索会非常费时。可以使用 com.ibm.ws.websvcs.getJAXBContext.cacheClassList.persist JVM 定制属性,以始终将搜索的每个软件包的搜索结果进行高速缓存。以后,JAXBContext 请求将使用已高速缓存的类列表,而不是对那些软件包执行新的搜索。
更新或卸载应用程序时,将除去该高速缓存。虽然此方法在提高性能方面可能不如提供软件包列表的方法,但是它不要求对应用程序进行任何更改。
建议将此操作作为第一个步骤,即使您打算使用 jaxb.index 文件也是如此。
- 为每个不包含 ObjectFactory 类的软件包提供 jaxb.index 文件。此操作使系统能够完全避免搜索 JAXB 类。此方法要求修改应用程序,以对添加的
jaxb.index 文件进行说明。
当每个软件包都包含 ObjectFactory 类或 jaxb.index 文件(用于指定软件包的 JAXB 类)时,可以使用包含 JAXB 类的软件包的列表。当您在 ObjectFactory 类或 jaxb.index 文件中提供了 JAXB 类列表时,将不需要搜索 JAXB 类。
使用软件包列表会使性能得到更大的提高,这可能要求您手动创建 jaxb.index 文件并对应用程序进行更改。如果您决定使用此方法,那么可以查看调试跟踪日志中的不包含 ObjectFactory 消息,以确定必须更新的软件包的数目。
如果要获取最佳性能并且愿意对应用程序进行更改,那么可以使用 jaxb.index 文件。通常仅通过自顶向下工具 (wsimport) 来创建 ObjectFactory 类。因此,通过自底向上工具 wsgen 开发的任何软件包可能不包含 ObjectFactory 类。jaxb.index 文件用来标识软件包中的 JAXB 类并减少创建上下文所需的时间量。JAXBContext.newInstance() 方法以接受 ObjectFactory 类的相同方式接受 jaxb.index 文件。
使用 jaxb.index 文件时,要求您评估跟踪文件中指示软件包不包含 ObjectFactory 类的所有实例,并创建相应的 jaxb.index 文件。在搜索跟踪以获取不包含 ObjectFactory 消息(指示需要 jaxb.index 文件的软件包)之后,您必须执行以下操作:- 创建具有 JAXB 类列表的 jaxb.index 文件。如果软件包不包含任何 JAXB 类,那么必须将空的 jaxb.index 文件放置在软件包中。
- 重新运行跟踪操作并确保跟踪中再也不会出现不包含 ObjectFactory 消息。
如果缺少必需的 JAXB 类,并且未将其包括在 jaxb.index 文件中,那么将发生错误,指示 JAXBContext 无法找到该类,应该将该类添加到 jaxb.index 文件。
JAXBContext 中使用的每个软件包都必须具有 ObjectFactory 类或 jaxb.index 文件,以防止搜索 JAXB 类。这意味着必须检查跟踪文件,并且必须处理缺少的 ObjectFactory 类或 jaxb.index 文件的每个实例。如果 JAXBContext 的任何软件包已标识为不包含 ObjectFactory 类或 jaxb.index 文件,那么将耗费时间来搜索 JAXB 类。在 JAXBContext.newInstance() 的 Oracle Javadoc(网址为 http://docs.oracle.com/javaee/5/api/javax/xml/bind/JAXBContext.html)中记录了 jaxb.index 文件的格式。
对于转换用户: 在 V7.0 中,甚至在使用 wsgen 来创建生成的类时,也不会保存这些类。但是,JAX-WS 规范 2.2,要求必须保存生成的类。因此,wsgen 将生成的类放置在 packagename/jaxws 目录中。所以现在要搜索的软件包列表包括 packagename/jaxws,它不存在于 EAR 文件中。出现这种情况时,您会接收到类似于以下消息的错误消息:
为了解决此错误,您可以执行以下操作: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
- 创建两个不同的 EAR 文件,一个文件不包含 somepackage.jaxws jaxb.index 文件以与 V7.0 配合使用,另一个文件包含 somepackage.jaxws jaxb.index 文件以与产品的当前版本配合使用。
- 如果要将单个 EAR 文件用于产品的这两个版本,请将生成的类和 jaxb.index 文件添加到 EAR 文件。如果使用此选项,那么还应该包括具有生成的类的 WSDL。
- 使用持久高速缓存而不是 jaxb.index 文件。选择此选项时,JAX-RS 仍然会对每个软件包搜索一次 JAXB 类,但是它会保留结果,因此,除非更新了应用程序,否则它不必再次搜索。
- 如果 JAXBContext.newInstance() 本身需要较长时间才能完成,那么您可以使用
jaxws.JAXBContext.permStoreCostThresholdMsec JVM 定制属性来创建
JAXBContext 对象的硬引用高速缓存,垃圾回收期间不会丢失该高速缓存。
没有任何选项来更改或改进实际的 JAXBContext 实例创建过程。将上下文进行实例化所花的时间受许多因素(例如,JAXB 类数、软件包数和类路径的大小)的影响。创建的 JAXBContext 保存在内存的软引用高速缓存中。因此,如果可用内存变少,那么垃圾回收可能会废弃 JAXBContext。然后,需要已废弃的 JAXBContext 的下一个请求必须重新创建该 JAXBContext。虽然此重新创建过程对于大多数 JAXBContext 没有意义,但是当 newInstance() 步骤本身要花很长时间时,存在例外情况。
如果应用程序的 JAXBContext 需要很长的时间来创建 newInstance(),请考虑使用以下 JVM 定制属性来将 JAXBContext 放置在高速缓存中,该高速缓存会保留至重新启动 JVM 或应用程序为止。
- jaxws.JAXBContext.permStoreCostThresholdMsec
- 将此属性设置为非零值(以毫秒计)。如果构造上下文所需时间超过指定的时间量,那么会高速缓存这些上下文。建议值为 5000 或更大。缺省值为 0。如果此属性设置为 0,那么不会使用高速缓存。
- jaxws.JAXBContext.permStoreMaxSize
- 将此属性设置为您希望在高速缓存中维护的最大条目数。缺省值为 32。如果高速缓存变满,那么将从高速缓存中除去需要最小的时间量来创建的 JAXBContext,以便为具有更长创建时间的 JAXBContext 腾出空间。
- jaxws.JAXBContext.permStoreStaleThresholdHours
- 将此属性设置为您希望条目保留在高速缓存中的时间长度(以小时计)。在高速缓存中添加较新条目之前,将移除高速缓存中在指定的小时数之后尚未访问的条目。缺省值为 24 小时。