javax.xml.bind.JAXBException:类<classname>也不知道它的任何超类</classname>

时间:2013-09-09 14:09:05

标签: java spring tomcat jaxb

我有一个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。在某个地方我需要注意一个静态物体吗?

2 个答案:

答案 0 :(得分:7)

在代码中的某处,您正在创建一个JAXBContext对象,该对象列出了可以编组和/或无法编组的所有Java类。将包名或ObjectFactory传递给它以使它知道很多类是很常见的。错误消息使得听起来好像上下文中的那些类在构造JAXBContext时不在类路径中。

跟踪代码并找到构造此JAXBContext实例的位置,并查看正在设置的Java类。它在redploying之后工作的事实使我认为它是一个类路径问题;也许有些类在代码的其余部分之前没有被加载到类路径中。

load-on-startup中的web.xml值也可能会提供一些提示。

答案 1 :(得分:0)

我的团队遇到了同样的错误消息。在我们的例子中,有问题的类是在两个jar文件中,看起来旧版本正在JAXBContext中加载。清除重复的类文件后,问题就解决了。