javax.xml.bind.JAXBException: class <ClassName> 或其任何超类在此上下文中都是已知的

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18700196/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 10:17:55  来源:igfitidea点击:

javax.xml.bind.JAXBException: class <ClassName> nor any of its super class is known to this context

javaspringtomcatjaxb

提问by KillerTofu

I have a RESTful web service that I am deploying on Tomcat 6 with Java 1.6 that I'm seeing some strange behavior with. I'm deploying this particular war file with about 5 other war files. The web app in question also periodically sends a status message to remote server in xml format, all the XML binding is done with JAXB 2.1.13. The JAXB binding does not appear to be working properly after initial deployment. That is to say, if I start tomcat and wait for the status message to be sent I get the following error:

我有一个 RESTful Web 服务,我正在使用 Java 1.6 在 Tomcat 6 上部署它,我看到了一些奇怪的行为。我正在使用大约 5 个其他战争文件部署这个特定的战争文件。有问题的 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. 

(I left out the fully qualified classname for brevity) Also any incoming requests to the RESTful service throw the same exception.

(为简洁起见,我省略了完全限定的类名)此外,对 RESTful 服务的任何传入请求都会引发相同的异常。

I don't see this problem if I package ALL the libraries in each war, but I'm trying not to do that because my WAR files were getting extremely bloated.The JAX libraries are packaged in this war, but things like the Spring, commons-*, hibernate, are in tomcat/lib. Does anyone have any ideas what could be causing this strange deployment order sensitivity?

如果我在每次战争中打包所有库,我就不会看到这个问题,但我试图不这样做,因为我的 WAR 文件变得非常臃肿。 JAX 库被打包在这场战争中,但是像 Spring, commons-*,hibernate,在 tomcat/lib 中。有没有人有任何想法可能导致这种奇怪的部署顺序敏感性?

Here's a little more code detail, every time the status message is triggered the following happens:

这里有更多的代码细节,每次触发状态消息时都会发生以下情况:

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);

The makeXML call looks like this:

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" );
}

The marshall line is where the exception is thrown. It seems like the JAXB context should be created every time this gets executed.

marshall 行是抛出异常的地方。似乎每次执行时都应该创建 JAXB 上下文。

Update, undeploying/redeploying doesn't always fix this issue, however packaging all the libs with it does. Is there a static object somewhere I need to be aware of?

更新、取消部署/重新部署并不总是能解决这个问题,但是用它打包所有的库可以解决这个问题。我需要注意某个地方是否有静态对象?

采纳答案by austin

Somewhere in your code, you are creating a JAXBContextobject which lists all of the Java classes that can be marshalled and/or unmarhsalled. It's pretty common to pass a package name or an ObjectFactory to it so that it knows about a lot of classes. The error message makes it sound like those classes in the context aren't in the classpath at the time the JAXBContextis being constructed.

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

Trace through the code and find where this JAXBContextinstance is constructed and check out what Java classes are being set. The fact that it works after redploying make me think that it's a classpath issue; maybe some of the classes aren't being loaded into the classpath before the rest of the code is.

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

Your load-on-startupvalues in your web.xmlmight also provide some hints.

您的load-on-startup价值观web.xml也可能提供一些提示。

回答by kman

My team ran into the same error message. In our case, the class in question was in two jar files and it appears that the older version was being loaded in the JAXBContext. Once the duplicate class files were cleaned up, the problem was fixed.

我的团队遇到了同样的错误消息。在我们的例子中,有问题的类位于两个 jar 文件中,并且似乎在 JAXBContext 中加载了旧版本。一旦清除了重复的类文件,问题就解决了。