我正在尝试创建一个JAX-WS服务,该服务使用从非常大(900+类)的Opentravel Alliance schemas集合生成的对象的JAXB数据绑定。
我能够在各种servlet容器(Jetty,Tomcat6 / 7等)上成功部署包含我的JAX-WS服务的war(包含正确的web.xml和sun-jaxws.xml),只要我的web方法不引用我的任何JAXB对象。例如,这有效:
@WebService(serviceName = "OTAService",
targetNamespace = "http://www.opentravel.org/OTA/2003/05")
@Addressing
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public class OTAService {
public String sayHello(final String name) {
return "Hello " + name + "!";
}
}
但是,如果我通过添加@XmlSeeAlso
注释或直接引用对象来更改Web方法以使用JAXB数据绑定,那么我尝试过的所有servlet容器都会无限期地挂起(1小时以上),没有错误,永远不要开始:
@WebService(serviceName = "OTAService",
targetNamespace = "http://www.opentravel.org/OTA/2003/05")
@Addressing
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
@XmlSeeAlso({OTAHotelResNotifRQ.class, OTAHotelResNotifRS.class})
public class OTAService {
@Action(input = "OTA_HotelResNotif")
@WebMethod(operationName = "OTA_HotelResNotif", action = "OTA_HotelResNotif")
public @WebResult OTAHotelResNotifRQ tokenizeOtaHotelResNotifRq(
@WebParam(partName = "OTA_HotelResNotifRQ", name = "OTA_HotelResNotifRQ",
targetNamespace = "http://www.opentravel.org/OTA/2003/05")
final OTAHotelResNotifRQ request) {
return request;
}
}
我已经验证了所有必需的jar,包括JAXB和JAX-WS API以及运行时jar,都存在于war的/ lib目录中。
通过在this project上运行mvn clean install
,可以创建包含我的JAXB对象的jar,这是我的JAX-WS项目的必需依赖项,并且可以创建并安装到本地存储库。
我的JAX-WS项目(可用here)可以通过调用mvn clean package jetty:run-war
在Jetty中运行。
如果仅存在简单的sayHello
方法,您会注意到Jetty正好启动。但是,如果取消注释JAXB方法,Jetty和我尝试过的所有其他servlet容器将在尝试实例化JAX-WS servlet时永远挂起。 有人可以解释为什么使用JAXB数据绑定的Web方法会阻止我的战争部署吗?由于各种servlet容器的冻结行为相同,我觉得必须有一些我缺少的关键步骤;但是,由于没有报告错误且容器启动只是挂起,我不知道如何继续。
答案 0 :(得分:3)
这似乎是由于我的opentravel项目中有大量的JAXB对象。当我将VisualVM连接到启动程序进程并对内存进行采样时,看起来JAXB似乎是出于某种原因而行走和预加载/缓存整个对象树(可能是为了重构模式以包含在WSDL中?)。
按照this question的答案中所述设置-Dcom.sun.xml.bind.v2.runtime.JAXBContextImpl.fastBoot=true
并使用-Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=512m
增加内存让Jetty快速启动。
我还不确定运行时性能是否会成为可接受的权衡。