2012-04-23 78 views
4

我正在使用標準javax.xml包來解析Linux機器上的某些XML文件。我的代碼如下:使用javax.xml的Java中的錯誤文件描述符IOException

try 
{ 
    // Prepare parser 
    DocumentBuilder documentBuilder = documentBuilderFactory 
     .newDocumentBuilder(); 
    Document document = documentBuilder.parse(file.getAbsolutePath()); // This is line 397 
    XPath xPath = xPathFactory.newXPath(); 
    ... 
} 
catch(IOException e) { ... } 

單個的DocumentBuilderFactory由多個線程訪問,如同一個單一的XPathFactory,相信這是可以接受的用法。使用上述代碼解析XML文件時,偶爾會看到以下錯誤。

java.io.IOException: Bad file descriptor 
     at java.io.FileInputStream.readBytes(Native Method) 
     at java.io.FileInputStream.read(FileInputStream.java:229) 
     at java.io.BufferedInputStream.fill(BufferedInputStream.java:229) 
     at java.io.BufferedInputStream.read(BufferedInputStream.java:246) 
     at org.apache.xerces.impl.XMLEntityManager$RewindableInputStream.read(Unknown Source) 
     at org.apache.xerces.impl.XMLEntityManager.setupCurrentEntity(Unknown Source) 
     at org.apache.xerces.impl.XMLVersionDetector.determineDocVersion(Unknown Source) 
     at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source) 
     at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source) 
     at org.apache.xerces.parsers.XMLParser.parse(Unknown Source) 
     at org.apache.xerces.parsers.DOMParser.parse(Unknown Source) 
     at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source) 
     at javax.xml.parsers.DocumentBuilder.parse(Unknown Source) 
     at mypackage.MyXmlParser.parseFile(MyXmlParser.java:397) 
     at mypackage.MyXmlParser.access$500(MyXmlParser.java:51) 
     at mypackage.MyXmlParser$1.call(MyXmlParser.java:337) 
     at mypackage.MyXmlParser$1.call(MyXmlParser.java:328) 
     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:284) 
     at java.util.concurrent.FutureTask.run(FutureTask.java:138) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:665) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:690) 
     at java.lang.Thread.run(Thread.java:799) 

我偶爾(〜的時間的10%)見下面的附加文本:

Caused by: 
java.io.IOException: Bad file descriptor 
     at org.apache.xml.serializer.ToStream.flushWriter(ToStream.java:260) 
     at org.apache.xml.serializer.ToXMLStream.endDocument(ToXMLStream.java:191) 
     at org.apache.xalan.transformer.TransformerIdentityImpl.endDocument(TransformerIdentityImpl.java:983) 
     at org.apache.xml.serializer.TreeWalker.traverse(TreeWalker.java:174) 
     at org.apache.xalan.transformer.TransformerIdentityImpl.transform(TransformerIdentityImpl.java:410) 
     ... 9 more 

當我手動檢查文件,我可以看到,失敗的文件和所述文件之間沒有差別通過。我可以確認通過的文件是有效的XML,沒有特殊字符或提前結束。

有誰知道爲什麼會發生這種情況,以及我如何避免它?

> java -version 
java version "1.5.0" 
Java(TM) 2 Runtime Environment, Standard Edition (build pxa64dev-20061002a (SR3)) 
IBM J9 VM (build 2.3, J2RE 1.5.0 IBM J9 2.3 Linux amd64-64 j9vmxa6423-20061001 (JIT enabled) 
J9VM - 20060915_08260_LHdSMr 
JIT - 20060908_1811_r8 
GC - 20060906_AA) 
JCL - 20061002 
+2

看來你的FileStream在數據讀取開始之前被關閉。您可能需要調查爲什麼它被關閉。 – kosa 2012-04-23 18:44:34

+0

謝謝,如果是這種情況,雖然我找不到任何理由。我沒有觸及上面發佈的javax.xml代碼之外的文件。 – Ina 2012-04-24 14:08:57

回答

2

它看起來像一個併發線程的問題。

錯誤可能在您向我們展示的codelet之外的某個地方。但是對於DocumentBuilderFactory和XPathFactory,我不確定它們是否是線程安全的;它在文檔中沒有提及。

對於第一次測試,我建議您將解析XML文件的整個代碼放到synchronized {}子句中。如果這解決了你的問題,那麼它肯定是一個多線程問題。在這種情況下,您必須找出必須同步的代碼的最小部分。

+0

似乎修復了它,謝謝。 DocumentBuilderFactory和XPathFactory顯然不是線程安全的。 – Ina 2012-04-24 20:00:19

相關問題