我有一个RESTful Web服务,我正在使用Java 1.6在Tomcat 6上部署,我看到了一些奇怪的行为。我正在使用大约5个其他war文件部署这个特定的war文件。有问题的Web应用程序还定期以xml格式向远程服务器发送状态消息,所有XML绑定都是使用JAXB 2.1.13完成的。初始部署后,JAXB绑定似乎无法正常工作。也就是说,如果我启动tomcat并等待状态消息发送,我会收到以下错误:
javax.xml.bind.JAXBException: class StatusMessage nor any of its super class is known to this context.
(为了简洁起见,我省略了完全限定的类名)。对RESTful服务的任何传入请求也会抛出相同的异常。
如果我在每次战争中打包所有库,我都没有看到这个问题,但是我试图不这样做,因为我的WAR文件变得非常臃肿。这个战争包装了JAX库,但是像Spring,commons- *,hibernate,都在tomcat / lib中。有没有人有任何想法可能导致这种奇怪的部署顺序敏感性?
这里有一些代码细节,每次触发状态消息时都会发生以下情况:
JAXBElement<StatusMessage> el = ( new ObjectFactory() ).createHeartbeat( statusMessage );
ApiUtils apiUtil = new ApiUtils();
NamespaceFilter outFilter = new NamespaceFilter("http://middleware/status", true);
String xml = apiUtil.makeXml( el, "com.package.path.status", ApiUtils.getFormatXMLSetting(), ApiUtils.getValidateXMLSetting(), outFilter);
makeXML调用如下所示:
public String makeXml(JAXBElement el, String packageName, Boolean formatXml, Boolean validateXml, NamespaceFilter outFilter) throws JAXBException,
SAXException, UnsupportedEncodingException, IOException{
// Marshal XML
JAXBContext jaxbContext = JAXBContext.newInstance( packageName );
Marshaller marshaller = jaxbContext.createMarshaller();
OutputFormat format = new OutputFormat();;
if (formatXml){
format.setIndent(true);
format.setNewlines(true);
}
//Create a filter that will remove the xmlns attribute
if(outFilter == null)
outFilter = new NamespaceFilter(null, false);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if ( validateXml ) {
SchemaFactory schemaFactory = SchemaFactory.newInstance( "http://www.w3.org/2001/XMLSchema" );
InputStream is = this.getClass().getClassLoader().getResourceAsStream( packageName.replaceAll( "\\.", "/" ) + "/schema.xsd" );
Source source = new StreamSource( is );
Schema schema = schemaFactory.newSchema( source );
// This line enforces schema validation
marshaller.setSchema( schema );
}
XMLWriter writer = new XMLWriter(baos, format);
outFilter.setContentHandler(writer);
marshaller.marshal( el, outFilter );
return baos.toString( "UTF-8" );
}
马歇尔线是抛出异常的地方。看起来每次执行时都应该创建JAXB上下文。
更新,取消部署/重新部署并不总能解决这个问题,但是用它打包所有的lib。在某个地方我需要注意一个静态物体吗?
答案 0 :(得分:7)
在代码中的某处,您正在创建一个JAXBContext
对象,该对象列出了可以编组和/或无法编组的所有Java类。将包名或ObjectFactory传递给它以使它知道很多类是很常见的。错误消息使得听起来好像上下文中的那些类在构造JAXBContext
时不在类路径中。
跟踪代码并找到构造此JAXBContext
实例的位置,并查看正在设置的Java类。它在redploying之后工作的事实使我认为它是一个类路径问题;也许有些类在代码的其余部分之前没有被加载到类路径中。
load-on-startup
中的web.xml
值也可能会提供一些提示。
答案 1 :(得分:0)
我的团队遇到了同样的错误消息。在我们的例子中,有问题的类是在两个jar文件中,看起来旧版本正在JAXBContext中加载。清除重复的类文件后,问题就解决了。