如何解锁由JAXB';锁定的文件;s unmarhsaller

如何解锁由JAXB';锁定的文件;s unmarhsaller,jaxb,Jaxb,我使用以下代码在Windows 7 x64上使用JAXB w/Java 1.7.003解组XML文件: try (InputStream xsdStream = ConfigurationService.class.getClassLoader().getResourceAsStream(CONFIG_XSD_FILE_NAME)) { configFile = new File(configFilePath); if (configFile.e

我使用以下代码在Windows 7 x64上使用JAXB w/Java 1.7.003解组XML文件:

 try (InputStream xsdStream = ConfigurationService.class.getClassLoader().getResourceAsStream(CONFIG_XSD_FILE_NAME)) {
            configFile = new File(configFilePath);
            if (configFile.exists()) {
                context = JAXBContext.newInstance(Config.class);
                Unmarshaller unMarshaller = context.createUnmarshaller();

                SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
                StreamSource xsdStreamSource = new StreamSource(xsdStream);
                Schema schema = sf.newSchema(xsdStreamSource);

                unMarshaller.setSchema(schema);
                Object xmlObject = Config.class.cast(unMarshaller.unmarshal(configFile));
                myConfig = (Config) xmlObject;
            } else {
                log.severe(configFile.getAbsolutePath() + " does not exist, can not parse configuration info from it.");
            }
  }
调用此方法的代码随后删除XML文件

如果取消建模成功,XML文件将被正确删除。但是,如果上面的代码抛出和异常,例如SAXException,XML文件将无限期地保持锁定,调用代码无法使用file.delete()删除它

在这种情况下,感觉JAXB没有关闭资源/文件。这是我的责任还是一个bug


回顾《破译者》一书并没有揭示这一点,谷歌搜索这一问题揭示了这一从2008年开始就没有答案的老问题

简短回答

您描述的行为听起来像是JAXB参考实现中的一个bug。您可以使用以下链接打开票据:

解决问题

您可以从
文件输入流
中解组,而不是从
文件
中解组,并在解组后控制它是否正确关闭


长答案

我无法重现您看到的问题。我已经在下面列出了我尝试过的内容。我正在为Mac使用JDK1.7.0_07 x64

配置服务

下面的大部分代码都是从您的问题中复制的。我添加了删除输入文件的调用,如果该文件仍然存在,则执行输出

用于UM14765898的包;
导入java.io.*;
导入javax.xml.xmlstants;
导入javax.xml.bind.*;
导入javax.xml.transform.stream.StreamSource;
导入javax.xml.validation.*;
公共类配置服务{
私有静态最终字符串配置_XSD_FILE_NAME=“forum14765898/schema.XSD”;
公共静态void main(字符串[]args)引发异常{
File configFile=null;
字符串configFilePath=“src/forum14765898/input.xml”;
JAXBContext上下文;
配置myConfig;
try(InputStream xsdStream=ConfigurationService.class.getClassLoader().getResourceAsStream(配置文件名)){
configFile=新文件(configFilePath);
if(configFile.exists()){
context=JAXBContext.newInstance(Config.class);
Unmarshaller Unmarshaller=context.createUnmarshaller();
SchemaFactory sf=SchemaFactory.newInstance(xmlstants.W3C\u XML\u SCHEMA\u NS\u URI);
StreamSource xsdStreamSource=新的StreamSource(xsdStream);
Schema Schema=sf.newSchema(xsdStreamSource);
解组器。设置模式(模式);
对象xmlObject=Config.class.cast(unMarshaller.unmarshal(configFile));
myConfig=(Config)xmlObject;
}否则{
//log.severe(configFile.getAbsolutePath()+“不存在,无法从中解析配置信息。”);
}
}捕获(例外e){
e、 printStackTrace(系统输出);
}
configFile.delete();
System.out.println(configFile.exists());
}
}
schema.xsd

下面是我正在使用的简单XML模式


input.xml

下面是XML输入。根据XML架构,
bar
元素无效。当在
解组器
上设置
架构
时,此文档将足以在执行解组操作时引发
异常


无效的
配置

用于UM14765898的包;
导入javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
公共类配置{
公共酒吧;
}
输出

下面是运行演示代码的输出。它显示了验证异常,在最后一行,我们看到XML文件已成功删除,因为它不再存在

javax.xml.bind.UnmarshalException
-除此之外:
[org.xml.sax.SAXParseException;systemId:file:/Users/bdoughan/Scratch/src/forum14765898/input.xml;行号:3;列号:23;cvc数据类型有效。1.2.1:“INVALID”不是“integer”的有效值。]
位于javax.xml.bind.helpers.AbstractUnmarshallerImpl.CreateUnmarshaleException(AbstractUnmarshallerImpl.java:335)
位于com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.createUnmarshaleException(UnmarshallerImpl.java:512)
位于com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:209)
位于com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:175)
位于javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157)
位于javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:162)
位于javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:171)
位于javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:189)
位于forum14765898.ConfigurationService.main(ConfigurationService.java:31)
原因:org.xml.sax.saxpasseeption;systemId:file:/Users/bdoughan/Scratch/src/forum14765898/input.xml;行号:3;栏目号:23;cvc数据类型有效。1.2.1:“无效”不是“整数”的有效值。
位于com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:198)
位于com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:134)
位于com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:437)
请访问com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:368)
在com.sun.org.apache.xerc上
    public CashCountCompleted CashDeposit(String path) throws Exception {
      // TODO Auto-generated method stub
      CashCountCompleted cashCountCompleted = null;
      File file = null;
      FileInputStream inputStram = null;
      try {
            file = new File(path);
      inputStram = new FileInputStream(file);
      JAXBContext jaxbContext = JAXBContext.newInstance(CashCountCompleted.class);
      Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
      cashCountCompleted = (CashCountCompleted) jaxbUnmarshaller.unmarshal(inputStram);         
      }catch (JAXBException e) {
          //throw new...        
      } catch (FileNotFoundException e) {
           //throw new...
      }finally{         
            try{
                if(inputStram !=null){
                    inputStram.close();
                }
            }catch(Exception exception){
               //throw new...
            }                 
      }
      return cashCountCompleted;    
}