Announcement Announcement Module
Collapse
No announcement yet.
Can't move files. IOException : Failed to delete original file Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Can't move files. IOException : Failed to delete original file

    I'm trying to implement a simple file integration pattern:
    1) I have XML files in my incoming folder.
    2) <inbound-channel-adapter> with single-threaded poller
    3) <xpath-router> to route messages to different channels (to start afterwards SpringBatch jobs)

    Code:
     <i:channel id="inChannel">
     
     <i-file:inbound-channel-adapter    id="inAdapter"  channel="inChannel" directory="${incomingDirectory}"
                       					auto-startup="true" prevent-duplicates="true" filename-pattern="*.xml">
        <i:poller max-messages-per-poll="1" fixed-rate="10" time-unit="SECONDS"/>
      </i-file:inbound-channel-adapter>
      
      <i-xml:xpath-router   id="inRouter" input-channel="inChannel" evaluate-as-string="true"
                            resolution-required="true"  default-output-channel="corruptedInputChannel">
            <i-xml:xpath-expression expression="local-name(./node())"/>
            <i-xml:mapping value="a" channel="outA"/>
            <i-xml:mapping value="b" channel="outB"/>
        </i-xml:xpath-router>
    It works fine for most scenarios. The problem arrives when I try to treat the scenario where my input file is corrupted and <xpath-router> throws a parsing exception.
    What I would like to achieve is to move this corrupted file from incoming folder to another one.

    I've tried several approaches to conenct to default errorChannel and move my file:
    1) Adding OutboundFileAdapater
    Code:
     <i-file:outbound-channel-adapter
                channel="errorChannel"
                directory="${rejectDirectory}"
                auto-startup="true"
                auto-create-directory="true"
                delete-source-files="true"
       />
    2) Adding my service via service-activator to move file manually :
    Code:
      <i:service-activator id="fileMover" method="move" input-channel="errorChannel"
                             ref="fileMover"/>
    
       //FileMover
       	public void move(ErrorMessage message) {
       		MessagingException me = (MessagingException) message.getPayload();
            Message<?> failedMessage = me.getFailedMessage();
            if(failedMessage.getPayload() instanceof File) {
            	try {
                	FileUtils.moveFileToDirectory(payload,targetDir,true);
            	} catch (IOException e) {
                	throw new MessagingException("Unable to move file " + payload.getAbsolutePath() + " to " + targetDir.getAbsolutePath()) ;
            	}
            }
       	}
       ....
    In all cases Im' getting IOException : Failed to delete original file 'C:\Temp\file.xml'

  • #2
    Do you have the right permissions to move/delete the file?

    Comment


    • #3
      Yes,I do. Actually further on in my flow (if XML file is successfully routed to another channel) I start a corresponding batch job which moves this file to processing directory.

      Code:
       <! aTypeCHannel gets messages from xpath-router-->
       <i:transformer input-channel="aTypeChannel" output-channel="aJobRequests">
              <bean class="be.fgov.just.cjr.business.extract.integration.FileToJobRequestTransformer">
                  <property name="job" ref="ExtractRequestSolarisJob"/>
                  <property name="reader" value="BeExtractItemReader"/>
                  <property name="writer" value="BeExtractItemWriter"/>
              </bean>
        </i:transformer>
        <i:service-activator input-channel="aJobRequests" ref="aJobLauncher" method="launch"/>
      'aJobLauncher' starts my job

      Code:
        @ServiceActivator
          public String launch(JobLaunchRequest request) {
              Assert.notNull(request);
              Job job = request.getJob();
              JobParameters params = request.getJobParameters();
              String inputFile = params.getString("inputFile");  
                 try {
      
                  JobExecution je = launcher.run(job, params);      
              	.............
              }
      In this job the first step consists of moving XML file to processing dir (from the same incoming dir)
      Code:
      // extrtact of one of the tasklets just to show the move code which works
       public void moveFileToFolder(String source, String target, boolean suffixDate) throws IOException {
              File sourceFile = new File(source);
              File targetFile = new File(target + "/" + FilenameUtils.getName(source) + (suffixDate ? "_" + DateFormatUtils.format(new Date(), "yyyyMMddHHmmss") : ""));
              LOGGER.debug("Will move file from " + sourceFile + " to " + targetFile);
              FileUtils.moveFile(sourceFile, targetFile);
              LOGGER.debug("Move file from " + sourceFile + " to " + targetFile);
          }
      So this part works fine and I don't get what could be the problem with xpath-router.

      Maybe going through XPath parsing exception an InputStream is not correctly closed at some point and the file is still blocked.
      Last edited by O.Korolenko; Aug 22nd, 2013, 04:37 AM.

      Comment


      • #4
        That's a possibility, I do't know the internals of DocumentBuilder but if it leaves the input stream open it could cause this issue.

        Try adding a file-to-string transformer between the adapter and the router.

        Comment


        • #5
          It works with additional file-to-string transformer. In my FileMover which deals with errors I'm getting now the original file form the message headers. Though I do need to adapt my job starting part of the flow to deal with String message.

          Thanks a lot for your help!

          Comment

          Working...
          X