[MNG-5629] ClosedChannelException from DefaultUpdateCheckManager.read

o Updated to stop producing 'ClosedChannelException's when reading tracking files.
o Updated to use 'Long.MAX_VALUE' as the size of any locked regions to prevent writing beyond locked regions.
o Updated to support shrinking of tracking files.
This commit is contained in:
Christian Schulte 2015-12-11 21:42:09 +01:00
parent e51fc87277
commit ca1179ce6a
1 changed files with 24 additions and 37 deletions

View File

@ -28,15 +28,12 @@ import org.apache.maven.repository.Proxy;
import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.logging.AbstractLogEnabled; import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.logging.Logger; import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.util.IOUtil;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.RandomAccessFile; import java.io.RandomAccessFile;
import java.nio.ByteBuffer; import java.nio.channels.Channels;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import java.nio.channels.FileLock; import java.nio.channels.FileLock;
import java.util.Date; import java.util.Date;
@ -242,18 +239,12 @@ public class DefaultUpdateCheckManager
Properties props = new Properties(); Properties props = new Properties();
channel = new RandomAccessFile( touchfile, "rw" ).getChannel(); channel = new RandomAccessFile( touchfile, "rw" ).getChannel();
lock = channel.lock( 0, channel.size(), false ); lock = channel.lock();
if ( touchfile.canRead() ) if ( touchfile.canRead() )
{ {
getLogger().debug( "Reading resolution-state from: " + touchfile ); getLogger().debug( "Reading resolution-state from: " + touchfile );
ByteBuffer buffer = ByteBuffer.allocate( (int) channel.size() ); props.load( Channels.newInputStream( channel ) );
channel.read( buffer );
buffer.flip();
ByteArrayInputStream stream = new ByteArrayInputStream( buffer.array() );
props.load( stream );
} }
props.setProperty( key, Long.toString( System.currentTimeMillis() ) ); props.setProperty( key, Long.toString( System.currentTimeMillis() ) );
@ -267,18 +258,15 @@ public class DefaultUpdateCheckManager
props.remove( key + ERROR_KEY_SUFFIX ); props.remove( key + ERROR_KEY_SUFFIX );
} }
ByteArrayOutputStream stream = new ByteArrayOutputStream();
getLogger().debug( "Writing resolution-state to: " + touchfile ); getLogger().debug( "Writing resolution-state to: " + touchfile );
props.store( stream, "Last modified on: " + new Date() ); channel.truncate( 0 );
props.store( Channels.newOutputStream( channel ), "Last modified on: " + new Date() );
byte[] data = stream.toByteArray(); lock.release();
ByteBuffer buffer = ByteBuffer.allocate( data.length ); lock = null;
buffer.put( data );
buffer.flip();
channel.position( 0 ); channel.close();
channel.write( buffer ); channel = null;
} }
catch ( IOException e ) catch ( IOException e )
{ {
@ -359,27 +347,26 @@ public class DefaultUpdateCheckManager
synchronized ( touchfile.getAbsolutePath().intern() ) synchronized ( touchfile.getAbsolutePath().intern() )
{ {
FileInputStream in = null;
FileLock lock = null; FileLock lock = null;
FileChannel channel = null;
try try
{ {
Properties props = new Properties(); Properties props = new Properties();
FileInputStream stream = new FileInputStream( touchfile ); in = new FileInputStream( touchfile );
try lock = in.getChannel().lock( 0, Long.MAX_VALUE, true );
{
channel = stream.getChannel();
lock = channel.lock( 0, channel.size(), true );
getLogger().debug( "Reading resolution-state from: " + touchfile ); getLogger().debug( "Reading resolution-state from: " + touchfile );
props.load( stream ); props.load( in );
return props; lock.release();
} lock = null;
finally
{ in.close();
IOUtil.close( stream ); in = null;
}
return props;
} }
catch ( IOException e ) catch ( IOException e )
{ {
@ -402,11 +389,11 @@ public class DefaultUpdateCheckManager
} }
} }
if ( channel != null ) if ( in != null )
{ {
try try
{ {
channel.close(); in.close();
} }
catch ( IOException e ) catch ( IOException e )
{ {