56

我越来越奇怪“文件过早结束”。最近几天在我们的一台服务器上例外。相同的配置 XML 在另一台服务器上工作正常。我们在这两台服务器上都使用 Tomcat 5.0.28。这段代码已经工作了很长时间(7 年以上),只是在最近的服务器崩溃之后,我们在其中一台服务器上遇到了这个问题。XML 和 Java 解析代码没有变化。:(

我能看到的唯一区别是 Java 版本 -

问题服务器 java 版本 "1.6.0_16" Java(TM) SE Runtime Environment (build 1.6.0_16-b01) Java HotSpot(TM) 64-Bit Server VM (build 14.2-b01, mixed mode)

工作服务器 java 版本“1.6.0_07” Java(TM) SE 运行时环境(构建 1.6.0_07-b06) Java HotSpot(TM) 64 位服务器 VM(构建 10.0-b23,混合模式)

这是已经工作了几年的Java代码 -

private void readSource(final InputSource in ) {
    try {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document doc = db.parse(in);
        Element elt = doc.getDocumentElement();

        this.readElement( elt );
    } catch ( Exception ex ) {
        ex.printStackTrace();
        throw new ConfigurationException( "Unable to parse configuration information", ex );
    }
}

这是一个例外。

[Fatal Error] :-1:-1: Premature end of file.
org.xml.sax.SAXParseException: Premature end of file.
        at org.apache.xerces.parsers.DOMParser.parse(Unknown Source)
        at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source)
        at com.circus.core.Configuration.readSource(Configuration.java:706)

我已经尝试过验证 XML 并没有发现任何错误。知道我还能在哪里寻找可能的问题吗?

任何指针将不胜感激!

TIA, - 马尼什

4

8 回答 8

70

这是 Java InputStream 的问题。当文件偏移位置计数器移动到文件末尾时读取流时。在随后使用相同的流读取时,您将收到此错误。因此,您必须再次关闭并重新打开流或调用inputStream.reset()将偏移计数器重置为其初始位置。

于 2012-12-06T21:29:18.633 回答
28

这解决了。问题出在其他地方。cron 作业中的另一个代码是将 XML 截断为长度为 0 的文件。我已经处理好了。

于 2013-02-11T10:17:31.800 回答
22

只有在解析空字符串/空字节数组时才会发生此异常。

以下是有关如何重现它的片段:

String xml = ""; // <-- deliberately an empty string.
ByteArrayInputStream xmlStream = new java.io.ByteArrayInputStream(xml.getBytes());
Unmarshaller u = JAXBContext.newInstance(...)
u.setSchema(...);
u.unmarshal( xmlStream ); // <-- here it will fail
于 2016-10-14T09:35:49.583 回答
5

请确保inputstream在解析之前您没有在任何地方使用您的任何内容。示例代码如下:下面的响应是httpresponse(即响应),主要内容是包含在里面StringEntity (i.e. getEntity())in form of inputStream(i.e. getContent())

InputStream rescontent = response.getEntity().getContent();
tsResponse=(TsResponse) transformer.convertFromXMLToObject(rescontent );
于 2016-06-11T10:49:55.597 回答
3

如果输入流未正确关闭,则可能会发生此异常。确保:如果使用的输入流未以某种方式使用“之前”,那么您打算阅读的位置。即,如果在单个操作中从同一输入流中第二次读取,则第二次调用将获得此异常。还要确保在 finally 块或类似的东西中关闭输入流。

于 2015-08-11T22:30:13.763 回答
2

您确定 XML 文件的字符编码正确吗?FileReader始终使用平台默认编码,因此如果“工作”服务器的默认编码为(例如)ISO-8859-1,而“问题”服务器使用 UTF-8,如果 XML 包含任何非 ASCII,您将看到此错误人物。

如果您从 FileInputStream 而不是 FileReader 创建 InputSource,它会起作用吗?

于 2012-11-20T20:54:43.020 回答
2

2021 年 12 月 6 日再次出现同样的错误!!!

样本痕迹:

XmlBeanDefinitionStoreException: Line -1 in XML document from ServletContext resource [<here a reference to spring context .xml file>] is invalid; nested exception is org.xml.sax.SAXParseException; Premature end of file.
Caused by: org.xml.sax.SAXParseException; Premature end of file.
at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:201)
at org.apache.xerces.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:175)
at org.apache.xerces.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:398)
at org.apache.xerces.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:325)
at org.apache.xerces.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:282)
at org.apache.xerces.impl.XMLVersionDetector.determineDocVersion(XMLVersionDetector.java:204)
at org.apache.xerces.impl.xs.opti.SchemaParsingConfig.parse(SchemaParsingConfig.java:576)
at org.apache.xerces.impl.xs.opti.SchemaParsingConfig.parse(SchemaParsingConfig.java:679)
at org.apache.xerces.impl.xs.opti.SchemaDOMParser.parse(SchemaDOMParser.java:527)
at org.apache.xerces.impl.xs.traversers.XSDHandler.getSchemaDocument(XSDHandler.java:2148)
at org.apache.xerces.impl.xs.traversers.XSDHandler.parseSchema(XSDHandler.java:557)

提示:

  1. Apache CAMEL 团队决定按照 XML Spring 上下文中通常引用的方式重新组织 CAMEL 模式文件。他们不只是删除(这将需要一个简单的例外,很容易发现)http://camel.apache.org/schema/spring/camel-spring-2.16.4.xsd通常的模式位置,他们实现了一个 HTTP 301将响应重定向到 HTTPS。

  2. Apache XERCES 库在 HTTP 301 的情况下不会引发错误,但假定它已收到一个空文件!这需要奇怪和错误的异常/将您置于错误的轨道上,因为它们报告链接到顶级 XML 文件的故障,而不是实际有问题的架构描述符

  3. 在我们的应用服务器平台中,在 WAR 重新加载/部署时(来自数据/内容 repo 缓存)对所有模式描述符及其 XSD 依赖项的完全重新验证是完全出乎意料的……而且完全没用!更糟糕的是:创建运行时公共网络依赖项,仅用于重新加载已验证的组件和描述符(在构建时)

1+2+3 以上,砰!主要服务中断:生产服务器无法重新加载依赖于 CAMEL 的任何组件

固定装置:

两名候选人:

a) 在 XML 中的 xsi:schemaLocation 属性中,只需将“s”添加到http://camel.apache.org/schema/etc变为 https://.... 但接受对每个组件的公共网络依赖重新加载

b) 用 classpath: 替换所有 http://... shema 位置。您将下载所有 XSD 和子依赖模式,并将它们与 WAR 一起部署,以确保对类加载器的可见性。例如,将文件放入 java/main/resources/somename.xsd 并提供 classpath:somename.xsd 作为模式位置路径

于 2021-12-06T17:28:58.673 回答
1

在我们的例子中,它是一个空的AndroidManifest.xml

在升级 Eclispe 时,我们遇到了常见的问题,并且 AndroidManifest.xml 必须在被破坏后被构建脚本签入到 SVN。

通过从 Eclipse 内部而不是从命令行编译找到它。

于 2014-10-26T12:51:32.353 回答