javax.xml.bind.JAXBException: class <ClassName> 或其任何超类在此上下文中都是已知的
Posted
技术标签:
【中文标题】javax.xml.bind.JAXBException: class <ClassName> 或其任何超类在此上下文中都是已知的【英文标题】:javax.xml.bind.JAXBException: class <ClassName> nor any of its super class is known to this context 【发布时间】:2013-09-13 01:23:27 【问题描述】:我有一个 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.
(为简洁起见,我省略了完全限定的类名)此外,对 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 上下文。
更新、取消部署/重新部署并不总能解决这个问题,但是用它打包所有库。是否有我需要注意的静态对象?
【问题讨论】:
【参考方案1】:在您的代码中的某处,您正在创建一个JAXBContext
对象,该对象列出了所有可以编组和/或取消编组的Java 类。将包名称或 ObjectFactory 传递给它是很常见的,以便它知道很多类。该错误消息听起来好像在构造 JAXBContext
时上下文中的那些类不在类路径中。
跟踪代码并找到构造此JAXBContext
实例的位置并检查正在设置的Java 类。它在重新部署后起作用的事实让我认为这是一个类路径问题;可能在其余代码加载之前,某些类没有被加载到类路径中。
web.xml
中的 load-on-startup
值也可能提供一些提示。
【讨论】:
不幸的是,这两个建议都没有对这个问题产生太大影响。 谢谢。我需要将正确的 getter 和 setter 添加到我的 ObjectFactory【参考方案2】:我的团队遇到了同样的错误消息。在我们的例子中,有问题的类在两个 jar 文件中,看起来旧版本正在加载到 JAXBContext 中。清理完重复的类文件后,问题就解决了。
【讨论】:
以上是关于javax.xml.bind.JAXBException: class <ClassName> 或其任何超类在此上下文中都是已知的的主要内容,如果未能解决你的问题,请参考以下文章