Repository: maven-resolver Updated Branches: refs/heads/master 9bf6abff7 -> ad50215d2
[MRESOLVER-13] Exceptions are suppressed incorrectly when closing resources fails. This closes #7 Project: http://git-wip-us.apache.org/repos/asf/maven-resolver/repo Commit: http://git-wip-us.apache.org/repos/asf/maven-resolver/commit/ad50215d Tree: http://git-wip-us.apache.org/repos/asf/maven-resolver/tree/ad50215d Diff: http://git-wip-us.apache.org/repos/asf/maven-resolver/diff/ad50215d Branch: refs/heads/master Commit: ad50215d27feede0ad0e5eb83ae96c6d6fdcc639 Parents: 9bf6abf Author: Christian Schulte <c...@schulte.it> Authored: Sun Mar 12 00:26:47 2017 +0100 Committer: Christian Schulte <schu...@apache.org> Committed: Fri Mar 17 00:13:59 2017 +0100 ---------------------------------------------------------------------- .../connector/basic/ChecksumCalculator.java | 66 ++++---- .../aether/connector/basic/PartialFile.java | 101 +++++++++--- .../aether/connector/basic/PartialFileTest.java | 98 ++++++++---- .../internal/impl/DefaultFileProcessor.java | 104 ++++++++----- .../transport/AbstractTransporter.java | 101 +++++++----- .../test/util/DependencyGraphParser.java | 21 ++- .../test/util/IniArtifactDataReader.java | 18 ++- .../internal/test/util/TestFileProcessor.java | 76 ++++++--- .../internal/test/util/TestFileUtils.java | 106 ++++++++++--- .../aether/transport/http/HttpServer.java | 34 +++- .../transport/wagon/WagonTransporter.java | 155 +++++++++++++------ .../org/eclipse/aether/util/ChecksumUtils.java | 62 ++++---- 12 files changed, 647 insertions(+), 295 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/ad50215d/maven-resolver-connector-basic/src/main/java/org/eclipse/aether/connector/basic/ChecksumCalculator.java ---------------------------------------------------------------------- diff --git a/maven-resolver-connector-basic/src/main/java/org/eclipse/aether/connector/basic/ChecksumCalculator.java b/maven-resolver-connector-basic/src/main/java/org/eclipse/aether/connector/basic/ChecksumCalculator.java index e76f8a9..3d05ff0 100644 --- a/maven-resolver-connector-basic/src/main/java/org/eclipse/aether/connector/basic/ChecksumCalculator.java +++ b/maven-resolver-connector-basic/src/main/java/org/eclipse/aether/connector/basic/ChecksumCalculator.java @@ -22,6 +22,7 @@ package org.eclipse.aether.connector.basic; import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; import java.nio.ByteBuffer; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -139,46 +140,37 @@ final class ChecksumCalculator { return; } + + InputStream in = null; try { - FileInputStream fis = new FileInputStream( targetFile ); - try + in = new FileInputStream( targetFile ); + long total = 0; + ByteBuffer buffer = ByteBuffer.allocate( 1024 * 32 ); + for ( byte[] array = buffer.array(); total < dataOffset; ) { - long total = 0; - ByteBuffer buffer = ByteBuffer.allocate( 1024 * 32 ); - for ( byte[] array = buffer.array(); total < dataOffset; ) + int read = in.read( array ); + if ( read < 0 ) { - int read = fis.read( array ); - if ( read < 0 ) + if ( total < dataOffset ) { - if ( total < dataOffset ) - { - throw new IOException( targetFile + " contains only " + total - + " bytes, cannot resume download from offset " + dataOffset ); - } - break; + throw new IOException( targetFile + " contains only " + total + + " bytes, cannot resume download from offset " + dataOffset ); } - total += read; - if ( total > dataOffset ) - { - read -= total - dataOffset; - } - buffer.rewind(); - buffer.limit( read ); - update( buffer ); + break; } - } - finally - { - try - { - fis.close(); - } - catch ( IOException e ) + total += read; + if ( total > dataOffset ) { - // irrelevant + read -= total - dataOffset; } + buffer.rewind(); + buffer.limit( read ); + update( buffer ); } + + in.close(); + in = null; } catch ( IOException e ) { @@ -187,6 +179,20 @@ final class ChecksumCalculator checksum.error( e ); } } + finally + { + try + { + if ( in != null ) + { + in.close(); + } + } + catch ( IOException e ) + { + // Suppressed due to an exception already thrown in the try block. + } + } } public void update( ByteBuffer data ) http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/ad50215d/maven-resolver-connector-basic/src/main/java/org/eclipse/aether/connector/basic/PartialFile.java ---------------------------------------------------------------------- diff --git a/maven-resolver-connector-basic/src/main/java/org/eclipse/aether/connector/basic/PartialFile.java b/maven-resolver-connector-basic/src/main/java/org/eclipse/aether/connector/basic/PartialFile.java index ad428d4..d360658 100644 --- a/maven-resolver-connector-basic/src/main/java/org/eclipse/aether/connector/basic/PartialFile.java +++ b/maven-resolver-connector-basic/src/main/java/org/eclipse/aether/connector/basic/PartialFile.java @@ -23,9 +23,11 @@ import java.io.Closeable; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; +import java.nio.channels.Channel; import java.nio.channels.FileLock; import java.nio.channels.OverlappingFileLockException; import java.util.UUID; +import java.util.concurrent.atomic.AtomicBoolean; import org.eclipse.aether.spi.log.Logger; @@ -57,19 +59,18 @@ final class PartialFile private final FileLock lock; - private final boolean concurrent; + private final AtomicBoolean concurrent; public LockFile( File partFile, int requestTimeout, RemoteAccessChecker checker, Logger logger ) throws Exception { lockFile = new File( partFile.getPath() + EXT_LOCK ); - boolean[] concurrent = { false }; + concurrent = new AtomicBoolean( false ); lock = lock( lockFile, partFile, requestTimeout, checker, logger, concurrent ); - this.concurrent = concurrent[0]; } private static FileLock lock( File lockFile, File partFile, int requestTimeout, RemoteAccessChecker checker, - Logger logger, boolean[] concurrent ) + Logger logger, AtomicBoolean concurrent ) throws Exception { boolean interrupted = false; @@ -89,7 +90,7 @@ final class PartialFile { if ( lastLength < 0 ) { - concurrent[0] = true; + concurrent.set( true ); /* * NOTE: We're going with the optimistic assumption that the other thread is downloading the * file from an equivalent repository. As a bare minimum, ensure the repository we are given @@ -104,12 +105,12 @@ final class PartialFile else if ( requestTimeout > 0 && currentTime - lastTime > Math.max( requestTimeout, 3 * 1000 ) ) { throw new IOException( "Timeout while waiting for concurrent download of " + partFile - + " to progress" ); + + " to progress" ); } try { - Thread.sleep( 100 ); + Thread.sleep( Math.max( requestTimeout / 2, 100 ) ); } catch ( InterruptedException e ) { @@ -129,56 +130,114 @@ final class PartialFile private static FileLock tryLock( File lockFile ) throws IOException { - RandomAccessFile raf = new RandomAccessFile( lockFile, "rw" ); + RandomAccessFile raf = null; + FileLock lock = null; try { - FileLock lock = raf.getChannel().tryLock( 0, 1, false ); + raf = new RandomAccessFile( lockFile, "rw" ); + lock = raf.getChannel().tryLock( 0, 1, false ); + if ( lock == null ) { - close( raf ); + raf.close(); + raf = null; } - return lock; } catch ( OverlappingFileLockException e ) { close( raf ); - return null; + raf = null; + lock = null; } catch ( RuntimeException e ) { close( raf ); - lockFile.delete(); + raf = null; + if ( !lockFile.delete() ) + { + lockFile.deleteOnExit(); + } throw e; } catch ( IOException e ) { close( raf ); - lockFile.delete(); + raf = null; + if ( !lockFile.delete() ) + { + lockFile.deleteOnExit(); + } throw e; } + finally + { + try + { + if ( lock == null && raf != null ) + { + raf.close(); + } + } + catch ( final IOException e ) + { + // Suppressed due to an exception already thrown in the try block. + } + } + + return lock; } private static void close( Closeable file ) { try { - file.close(); + if ( file != null ) + { + file.close(); + } } catch ( IOException e ) { - // irrelevant + // Suppressed. } } public boolean isConcurrent() { - return concurrent; + return concurrent.get(); } - public void close() + public void close() throws IOException { - close( lock.channel() ); - lockFile.delete(); + Channel channel = null; + try + { + channel = lock.channel(); + lock.release(); + channel.close(); + channel = null; + } + finally + { + try + { + if ( channel != null ) + { + channel.close(); + } + } + catch ( final IOException e ) + { + // Suppressed due to an exception already thrown in the try block. + } + finally + { + if ( !lockFile.delete() ) + { + lockFile.deleteOnExit(); + } + } + } } @Override @@ -277,7 +336,7 @@ final class PartialFile return lockFile != null && partFile.length() >= threshold; } - public void close() + public void close() throws IOException { if ( partFile.exists() && !isResume() ) { http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/ad50215d/maven-resolver-connector-basic/src/test/java/org/eclipse/aether/connector/basic/PartialFileTest.java ---------------------------------------------------------------------- diff --git a/maven-resolver-connector-basic/src/test/java/org/eclipse/aether/connector/basic/PartialFileTest.java b/maven-resolver-connector-basic/src/test/java/org/eclipse/aether/connector/basic/PartialFileTest.java index edfeee9..b6fd701 100644 --- a/maven-resolver-connector-basic/src/test/java/org/eclipse/aether/connector/basic/PartialFileTest.java +++ b/maven-resolver-connector-basic/src/test/java/org/eclipse/aether/connector/basic/PartialFileTest.java @@ -26,6 +26,7 @@ import java.io.Closeable; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import java.io.OutputStream; import java.io.RandomAccessFile; import java.nio.channels.FileLock; import java.util.ArrayList; @@ -97,48 +98,91 @@ public class PartialFileTest @Override public void run() { + RandomAccessFile raf = null; + FileLock lock = null; + OutputStream out = null; try { - RandomAccessFile raf = new RandomAccessFile( lockFile, "rw" ); + raf = new RandomAccessFile( lockFile, "rw" ); + lock = raf.getChannel().lock( 0, 1, false ); + locked.countDown(); + out = new FileOutputStream( partFile ); + for ( int i = 0, n = Math.abs( length ); i < n; i++ ) + { + for ( long start = System.currentTimeMillis(); System.currentTimeMillis() - start < sleep; ) + { + Thread.sleep( 10 ); + } + out.write( 65 ); + out.flush(); + System.out.println( " " + System.currentTimeMillis() + " Wrote byte " + ( i + 1 ) + "/" + + n ); + } + if ( length >= 0 && !dstFile.setLastModified( System.currentTimeMillis() ) ) + { + throw new IOException( "Could not update destination file" ); + } + + out.close(); + out = null; + lock.release(); + lock = null; + raf.close(); + raf = null; + } + catch ( Exception e ) + { + error = e; + } + finally + { try { - FileLock lock = raf.getChannel().lock( 0, 1, false ); - locked.countDown(); - FileOutputStream fos = new FileOutputStream( partFile ); + if ( out != null ) + { + out.close(); + } + } + catch ( final IOException e ) + { + // Suppressed due to an exception already thrown in the try block. + } + finally + { try { - for ( int i = 0, n = Math.abs( length ); i < n; i++ ) + if ( lock != null ) { - for ( long start = System.currentTimeMillis(); System.currentTimeMillis() - start < sleep; ) + lock.release(); + } + } + catch ( final IOException e ) + { + // Suppressed due to an exception already thrown in the try block. + } + finally + { + try + { + if ( raf != null ) { - Thread.sleep( 10 ); + raf.close(); } - fos.write( 65 ); - fos.flush(); - System.out.println( " " + System.currentTimeMillis() + " Wrote byte " + ( i + 1 ) + "/" - + n ); } - if ( length >= 0 && !dstFile.setLastModified( System.currentTimeMillis() ) ) + catch ( final IOException e ) { - throw new IOException( "Could not update destination file" ); + // Suppressed due to an exception already thrown in the try block. + } + finally + { + if ( !lockFile.delete() ) + { + lockFile.deleteOnExit(); + } } } - finally - { - fos.close(); - } - lock.release(); - } - finally - { - raf.close(); - lockFile.delete(); } } - catch ( Exception e ) - { - error = e; - } } } http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/ad50215d/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultFileProcessor.java ---------------------------------------------------------------------- diff --git a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultFileProcessor.java b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultFileProcessor.java index cfeac98..a77e353 100644 --- a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultFileProcessor.java +++ b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultFileProcessor.java @@ -19,7 +19,6 @@ package org.eclipse.aether.internal.impl; * under the License. */ -import java.io.Closeable; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -40,21 +39,6 @@ public class DefaultFileProcessor implements FileProcessor { - private static void close( Closeable closeable ) - { - if ( closeable != null ) - { - try - { - closeable.close(); - } - catch ( IOException e ) - { - // too bad but who cares - } - } - } - /** * Thread-safe variant of {@link File#mkdirs()}. Creates the directory named by the given abstract pathname, * including any necessary but nonexistent parent directories. Note that if this operation fails it may have @@ -99,22 +83,32 @@ public class DefaultFileProcessor { mkdirs( target.getAbsoluteFile().getParentFile() ); - OutputStream fos = null; + OutputStream out = null; try { - fos = new FileOutputStream( target ); + out = new FileOutputStream( target ); if ( data != null ) { - fos.write( data.getBytes( "UTF-8" ) ); + out.write( data.getBytes( "UTF-8" ) ); } - // allow output to report any flush/close errors - fos.close(); + out.close(); + out = null; } finally { - close( fos ); + try + { + if ( out != null ) + { + out.close(); + } + } + catch ( final IOException e ) + { + // Suppressed due to an exception already thrown in the try block. + } } } @@ -123,19 +117,29 @@ public class DefaultFileProcessor { mkdirs( target.getAbsoluteFile().getParentFile() ); - OutputStream fos = null; + OutputStream out = null; try { - fos = new FileOutputStream( target ); + out = new FileOutputStream( target ); - copy( fos, source, null ); + copy( out, source, null ); - // allow output to report any flush/close errors - fos.close(); + out.close(); + out = null; } finally { - close( fos ); + try + { + if ( out != null ) + { + out.close(); + } + } + catch ( final IOException e ) + { + // Suppressed due to an exception already thrown in the try block. + } } } @@ -150,25 +154,51 @@ public class DefaultFileProcessor { long total = 0; - InputStream fis = null; - OutputStream fos = null; + InputStream in = null; + OutputStream out = null; try { - fis = new FileInputStream( source ); + in = new FileInputStream( source ); mkdirs( target.getAbsoluteFile().getParentFile() ); - fos = new FileOutputStream( target ); + out = new FileOutputStream( target ); + + total = copy( out, in, listener ); - total = copy( fos, fis, listener ); + out.close(); + out = null; - // allow output to report any flush/close errors - fos.close(); + in.close(); + in = null; } finally { - close( fis ); - close( fos ); + try + { + if ( out != null ) + { + out.close(); + } + } + catch ( final IOException e ) + { + // Suppressed due to an exception already thrown in the try block. + } + finally + { + try + { + if ( in != null ) + { + in.close(); + } + } + catch ( final IOException e ) + { + // Suppressed due to an exception already thrown in the try block. + } + } } return total; http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/ad50215d/maven-resolver-spi/src/main/java/org/eclipse/aether/spi/connector/transport/AbstractTransporter.java ---------------------------------------------------------------------- diff --git a/maven-resolver-spi/src/main/java/org/eclipse/aether/spi/connector/transport/AbstractTransporter.java b/maven-resolver-spi/src/main/java/org/eclipse/aether/spi/connector/transport/AbstractTransporter.java index 21e54c9..03864d3 100644 --- a/maven-resolver-spi/src/main/java/org/eclipse/aether/spi/connector/transport/AbstractTransporter.java +++ b/maven-resolver-spi/src/main/java/org/eclipse/aether/spi/connector/transport/AbstractTransporter.java @@ -19,7 +19,6 @@ package org.eclipse.aether.spi.connector.transport; * under the License. */ -import java.io.Closeable; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -96,25 +95,47 @@ public abstract class AbstractTransporter protected void utilGet( GetTask task, InputStream is, boolean close, long length, boolean resume ) throws IOException, TransferCancelledException { + OutputStream os = null; try { task.getListener().transportStarted( resume ? task.getResumeOffset() : 0, length ); - OutputStream os = task.newOutputStream( resume ); - try - { - copy( os, is, task.getListener() ); - os.close(); - } - finally + os = task.newOutputStream( resume ); + copy( os, is, task.getListener() ); + os.close(); + os = null; + + if ( close ) { - close( os ); + is.close(); + is = null; } } finally { - if ( close ) + try + { + if ( os != null ) + { + os.close(); + } + } + catch ( final IOException e ) { - close( is ); + // Suppressed due to an exception already thrown in the try block. + } + finally + { + try + { + if ( close && is != null ) + { + is.close(); + } + } + catch ( final IOException e ) + { + // Suppressed due to an exception already thrown in the try block. + } } } } @@ -150,18 +171,13 @@ public abstract class AbstractTransporter protected void utilPut( PutTask task, OutputStream os, boolean close ) throws IOException, TransferCancelledException { + InputStream is = null; try { task.getListener().transportStarted( 0, task.getDataLength() ); - InputStream is = task.newInputStream(); - try - { - copy( os, is, task.getListener() ); - } - finally - { - close( is ); - } + is = task.newInputStream(); + copy( os, is, task.getListener() ); + if ( close ) { os.close(); @@ -170,12 +186,38 @@ public abstract class AbstractTransporter { os.flush(); } + + os = null; + + is.close(); + is = null; } finally { - if ( close ) + try + { + if ( close && os != null ) + { + os.close(); + } + } + catch ( final IOException e ) + { + // Suppressed due to an exception already thrown in the try block. + } + finally { - close( os ); + try + { + if ( is != null ) + { + is.close(); + } + } + catch ( final IOException e ) + { + // Suppressed due to an exception already thrown in the try block. + } } } } @@ -215,19 +257,4 @@ public abstract class AbstractTransporter } } - private static void close( Closeable file ) - { - if ( file != null ) - { - try - { - file.close(); - } - catch ( IOException e ) - { - // irrelevant - } - } - } - } http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/ad50215d/maven-resolver-test-util/src/main/java/org/eclipse/aether/internal/test/util/DependencyGraphParser.java ---------------------------------------------------------------------- diff --git a/maven-resolver-test-util/src/main/java/org/eclipse/aether/internal/test/util/DependencyGraphParser.java b/maven-resolver-test-util/src/main/java/org/eclipse/aether/internal/test/util/DependencyGraphParser.java index a745ccf..d6f7a17 100644 --- a/maven-resolver-test-util/src/main/java/org/eclipse/aether/internal/test/util/DependencyGraphParser.java +++ b/maven-resolver-test-util/src/main/java/org/eclipse/aether/internal/test/util/DependencyGraphParser.java @@ -21,7 +21,6 @@ package org.eclipse.aether.internal.test.util; import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStream; import java.io.InputStreamReader; import java.io.StringReader; import java.net.URL; @@ -187,17 +186,27 @@ public class DependencyGraphParser public DependencyNode parse( URL resource ) throws IOException { - InputStream stream = null; + BufferedReader reader = null; try { - stream = resource.openStream(); - return parse( new BufferedReader( new InputStreamReader( stream, "UTF-8" ) ) ); + reader = new BufferedReader( new InputStreamReader( resource.openStream(), "UTF-8" ) ); + final DependencyNode node = parse( reader ); + reader.close(); + reader = null; + return node; } finally { - if ( stream != null ) + try + { + if ( reader != null ) + { + reader.close(); + } + } + catch ( final IOException e ) { - stream.close(); + // Suppressed due to an exception already thrown in the try block. } } } http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/ad50215d/maven-resolver-test-util/src/main/java/org/eclipse/aether/internal/test/util/IniArtifactDataReader.java ---------------------------------------------------------------------- diff --git a/maven-resolver-test-util/src/main/java/org/eclipse/aether/internal/test/util/IniArtifactDataReader.java b/maven-resolver-test-util/src/main/java/org/eclipse/aether/internal/test/util/IniArtifactDataReader.java index 4253544..0b5d08b 100644 --- a/maven-resolver-test-util/src/main/java/org/eclipse/aether/internal/test/util/IniArtifactDataReader.java +++ b/maven-resolver-test-util/src/main/java/org/eclipse/aether/internal/test/util/IniArtifactDataReader.java @@ -113,9 +113,10 @@ class IniArtifactDataReader Map<State, List<String>> sections = new HashMap<State, List<String>>(); - BufferedReader in = new BufferedReader( reader ); + BufferedReader in = null; try { + in = new BufferedReader( reader ); while ( ( line = in.readLine() ) != null ) { @@ -149,10 +150,23 @@ class IniArtifactDataReader lines.add( line.trim() ); } } + + in.close(); + in = null; } finally { - in.close(); + try + { + if ( in != null ) + { + in.close(); + } + } + catch ( final IOException e ) + { + // Suppressed due to an exception already thrown in the try block. + } } Artifact relocation = relocation( sections.get( State.RELOCATION ) ); http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/ad50215d/maven-resolver-test-util/src/main/java/org/eclipse/aether/internal/test/util/TestFileProcessor.java ---------------------------------------------------------------------- diff --git a/maven-resolver-test-util/src/main/java/org/eclipse/aether/internal/test/util/TestFileProcessor.java b/maven-resolver-test-util/src/main/java/org/eclipse/aether/internal/test/util/TestFileProcessor.java index fe130a3..5ec38e0 100644 --- a/maven-resolver-test-util/src/main/java/org/eclipse/aether/internal/test/util/TestFileProcessor.java +++ b/maven-resolver-test-util/src/main/java/org/eclipse/aether/internal/test/util/TestFileProcessor.java @@ -20,7 +20,6 @@ package org.eclipse.aether.internal.test.util; */ import java.io.BufferedOutputStream; -import java.io.Closeable; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -38,21 +37,6 @@ public class TestFileProcessor implements FileProcessor { - private static void close( Closeable closeable ) - { - if ( closeable != null ) - { - try - { - closeable.close(); - } - catch ( IOException e ) - { - // too bad but who cares - } - } - } - public boolean mkdirs( File directory ) { if ( directory == null ) @@ -98,12 +82,22 @@ public class TestFileProcessor fos.write( data.getBytes( "UTF-8" ) ); } - // allow output to report any flush/close errors fos.close(); + fos = null; } finally { - close( fos ); + try + { + if ( fos != null ) + { + fos.close(); + } + } + catch ( final IOException e ) + { + // Suppressed due to an exception already thrown in the try block. + } } } @@ -119,12 +113,22 @@ public class TestFileProcessor copy( fos, source, null ); - // allow output to report any flush/close errors fos.close(); + fos = null; } finally { - close( fos ); + try + { + if ( fos != null ) + { + fos.close(); + } + } + catch ( final IOException e ) + { + // Suppressed due to an exception already thrown in the try block. + } } } @@ -151,13 +155,39 @@ public class TestFileProcessor total = copy( fos, fis, listener ); - // allow output to report any flush/close errors fos.close(); + fos = null; + + fis.close(); + fis = null; } finally { - close( fis ); - close( fos ); + try + { + if ( fos != null ) + { + fos.close(); + } + } + catch ( final IOException e ) + { + // Suppressed due to an exception already thrown in the try block. + } + finally + { + try + { + if ( fis != null ) + { + fis.close(); + } + } + catch ( final IOException e ) + { + // Suppressed due to an exception already thrown in the try block. + } + } } return total; http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/ad50215d/maven-resolver-test-util/src/main/java/org/eclipse/aether/internal/test/util/TestFileUtils.java ---------------------------------------------------------------------- diff --git a/maven-resolver-test-util/src/main/java/org/eclipse/aether/internal/test/util/TestFileUtils.java b/maven-resolver-test-util/src/main/java/org/eclipse/aether/internal/test/util/TestFileUtils.java index 9757daa..a948c01 100644 --- a/maven-resolver-test-util/src/main/java/org/eclipse/aether/internal/test/util/TestFileUtils.java +++ b/maven-resolver-test-util/src/main/java/org/eclipse/aether/internal/test/util/TestFileUtils.java @@ -20,7 +20,6 @@ package org.eclipse.aether.internal.test.util; */ import java.io.BufferedOutputStream; -import java.io.Closeable; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -179,22 +178,6 @@ public class TestFileUtils return tmpFile; } - private static void close( Closeable c ) - throws IOException - { - if ( c != null ) - { - try - { - c.close(); - } - catch ( IOException e ) - { - // ignore - } - } - } - public static long copyFile( File source, File target ) throws IOException { @@ -210,7 +193,7 @@ public class TestFileUtils fos = new BufferedOutputStream( new FileOutputStream( target ) ); - for ( byte[] buffer = new byte[1024 * 32];; ) + for ( byte[] buffer = new byte[ 1024 * 32 ];; ) { int bytes = fis.read( buffer ); if ( bytes < 0 ) @@ -224,11 +207,38 @@ public class TestFileUtils } fos.close(); + fos = null; + + fis.close(); + fis = null; } finally { - close( fis ); - close( fos ); + try + { + if ( fos != null ) + { + fos.close(); + } + } + catch ( final IOException e ) + { + // Suppressed due to an exception already thrown in the try block. + } + finally + { + try + { + if ( fis != null ) + { + fis.close(); + } + } + catch ( final IOException e ) + { + // Suppressed due to an exception already thrown in the try block. + } + } } return total; @@ -241,13 +251,25 @@ public class TestFileUtils try { in = new RandomAccessFile( file, "r" ); - byte[] actual = new byte[(int) in.length()]; + byte[] actual = new byte[ (int) in.length() ]; in.readFully( actual ); + in.close(); + in = null; return actual; } finally { - close( in ); + try + { + if ( in != null ) + { + in.close(); + } + } + catch ( final IOException e ) + { + // Suppressed due to an exception already thrown in the try block. + } } } @@ -265,10 +287,21 @@ public class TestFileUtils out.write( pattern ); } out.close(); + out = null; } finally { - close( out ); + try + { + if ( out != null ) + { + out.close(); + } + } + catch ( final IOException e ) + { + // Suppressed due to an exception already thrown in the try block. + } } } @@ -293,10 +326,22 @@ public class TestFileUtils { fis = new FileInputStream( file ); props.load( fis ); + fis.close(); + fis = null; } finally { - close( fis ); + try + { + if ( fis != null ) + { + fis.close(); + } + } + catch ( final IOException e ) + { + // Suppressed due to an exception already thrown in the try block. + } } } @@ -311,10 +356,21 @@ public class TestFileUtils fos = new FileOutputStream( file ); props.store( fos, "aether-test" ); fos.close(); + fos = null; } finally { - close( fos ); + try + { + if ( fos != null ) + { + fos.close(); + } + } + catch ( final IOException e ) + { + // Suppressed due to an exception already thrown in the try block. + } } } http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/ad50215d/maven-resolver-transport-http/src/test/java/org/eclipse/aether/transport/http/HttpServer.java ---------------------------------------------------------------------- diff --git a/maven-resolver-transport-http/src/test/java/org/eclipse/aether/transport/http/HttpServer.java b/maven-resolver-transport-http/src/test/java/org/eclipse/aether/transport/http/HttpServer.java index 8c80bbd..44e32ed 100644 --- a/maven-resolver-transport-http/src/test/java/org/eclipse/aether/transport/http/HttpServer.java +++ b/maven-resolver-transport-http/src/test/java/org/eclipse/aether/transport/http/HttpServer.java @@ -365,9 +365,10 @@ public class HttpServer { return; } - FileInputStream is = new FileInputStream( file ); + FileInputStream is = null; try { + is = new FileInputStream( file ); if ( offset > 0 ) { long skipped = is.skip( offset ); @@ -377,10 +378,22 @@ public class HttpServer } } IO.copy( is, response.getOutputStream() ); + is.close(); + is = null; } finally { - IO.close( is ); + try + { + if ( is != null ) + { + is.close(); + } + } + catch ( final IOException e ) + { + // Suppressed due to an exception already thrown in the try block. + } } } else if ( HttpMethods.PUT.equals( req.getMethod() ) ) @@ -393,14 +406,27 @@ public class HttpServer { try { - FileOutputStream os = new FileOutputStream( file ); + FileOutputStream os = null; try { + os = new FileOutputStream( file ); IO.copy( request.getInputStream(), os ); + os.close(); + os = null; } finally { - os.close(); + try + { + if ( os != null ) + { + os.close(); + } + } + catch ( final IOException e ) + { + // Suppressed due to an exception already thrown in the try block. + } } } catch ( IOException e ) http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/ad50215d/maven-resolver-transport-wagon/src/main/java/org/eclipse/aether/transport/wagon/WagonTransporter.java ---------------------------------------------------------------------- diff --git a/maven-resolver-transport-wagon/src/main/java/org/eclipse/aether/transport/wagon/WagonTransporter.java b/maven-resolver-transport-wagon/src/main/java/org/eclipse/aether/transport/wagon/WagonTransporter.java index e9f89c2..e8a4049 100644 --- a/maven-resolver-transport-wagon/src/main/java/org/eclipse/aether/transport/wagon/WagonTransporter.java +++ b/maven-resolver-transport-wagon/src/main/java/org/eclipse/aether/transport/wagon/WagonTransporter.java @@ -19,7 +19,6 @@ package org.eclipse.aether.transport.wagon; * under the License. */ -import java.io.Closeable; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -458,6 +457,7 @@ final class WagonTransporter if ( path != null && !path.delete() && path.exists() ) { logger.debug( "Could not delete temorary file " + path ); + path.deleteOnExit(); } } @@ -471,21 +471,6 @@ final class WagonTransporter } } - private static void close( Closeable file ) - { - if ( file != null ) - { - try - { - file.close(); - } - catch ( IOException e ) - { - // too bad - } - } - } - public void close() { if ( closed.compareAndSet( false, true ) ) @@ -551,14 +536,27 @@ final class WagonTransporter File file = task.getDataFile(); if ( file == null && wagon instanceof StreamingWagon ) { - OutputStream dst = task.newOutputStream(); + OutputStream dst = null; try { + dst = task.newOutputStream(); ( (StreamingWagon) wagon ).getToStream( src, dst ); + dst.close(); + dst = null; } finally { - dst.close(); + try + { + if ( dst != null ) + { + dst.close(); + } + } + catch ( final IOException e ) + { + // Suppressed due to an exception already thrown in the try block. + } } } else @@ -567,14 +565,14 @@ final class WagonTransporter try { wagon.get( src, dst ); - if ( !dst.exists() ) + /* + * NOTE: Wagon (1.0-beta-6) doesn't create the destination file when transferring a 0-byte + * resource. So if the resource we asked for didn't cause any exception but doesn't show up in + * the dst file either, Wagon tells us in its weird way the file is empty. + */ + if ( !dst.exists() && !dst.createNewFile() ) { - /* - * NOTE: Wagon (1.0-beta-6) doesn't create the destination file when transferring a 0-byte - * resource. So if the resource we asked for didn't cause any exception but doesn't show up in - * the dst file either, Wagon tells us in its weird way the file is empty. - */ - new FileOutputStream( dst ).close(); + throw new IOException( String.format( "Failure creating file '%s'.", dst.getAbsolutePath() ) ); } if ( file == null ) { @@ -594,24 +592,46 @@ final class WagonTransporter private void readTempFile( File dst ) throws IOException { - FileInputStream fis = new FileInputStream( dst ); + FileInputStream in = null; + OutputStream out = null; try { - OutputStream os = task.newOutputStream(); + in = new FileInputStream( dst ); + out = task.newOutputStream(); + copy( out, in ); + out.close(); + out = null; + in.close(); + in = null; + } + finally + { try { - copy( os, fis ); - os.close(); + if ( out != null ) + { + out.close(); + } + } + catch ( final IOException e ) + { + // Suppressed due to an exception already thrown in the try block. } finally { - close( os ); + try + { + if ( in != null ) + { + in.close(); + } + } + catch ( final IOException e ) + { + // Suppressed due to an exception already thrown in the try block. + } } } - finally - { - close( fis ); - } } } @@ -634,15 +654,28 @@ final class WagonTransporter File file = task.getDataFile(); if ( file == null && wagon instanceof StreamingWagon ) { - InputStream src = task.newInputStream(); + InputStream src = null; try { + src = task.newInputStream(); // StreamingWagon uses an internal buffer on src input stream. ( (StreamingWagon) wagon ).putFromStream( src, dst, task.getDataLength(), -1 ); + src.close(); + src = null; } finally { - close( src ); + try + { + if ( src != null ) + { + src.close(); + } + } + catch ( final IOException e ) + { + // Suppressed due to an exception already thrown in the try block. + } } } else @@ -666,32 +699,52 @@ final class WagonTransporter throws IOException { File tmp = newTempFile(); + OutputStream out = null; + InputStream in = null; try { - FileOutputStream fos = new FileOutputStream( tmp ); + in = task.newInputStream(); + out = new FileOutputStream( tmp ); + copy( out, in ); + out.close(); + out = null; + in.close(); + in = null; + } + catch ( IOException e ) + { + delTempFile( tmp ); + throw e; + } + finally + { try { - InputStream is = task.newInputStream(); - try + if ( out != null ) { - copy( fos, is ); - fos.close(); - } - finally - { - close( is ); + out.close(); } } + catch ( final IOException e ) + { + // Suppressed due to an exception already thrown in the try block. + } finally { - close( fos ); + try + { + if ( in != null ) + { + in.close(); + } + } + catch ( final IOException e ) + { + // Suppressed due to an exception already thrown in the try block. + } } } - catch ( IOException e ) - { - delTempFile( tmp ); - throw e; - } + return tmp; } http://git-wip-us.apache.org/repos/asf/maven-resolver/blob/ad50215d/maven-resolver-util/src/main/java/org/eclipse/aether/util/ChecksumUtils.java ---------------------------------------------------------------------- diff --git a/maven-resolver-util/src/main/java/org/eclipse/aether/util/ChecksumUtils.java b/maven-resolver-util/src/main/java/org/eclipse/aether/util/ChecksumUtils.java index b629c8d..3134c80 100644 --- a/maven-resolver-util/src/main/java/org/eclipse/aether/util/ChecksumUtils.java +++ b/maven-resolver-util/src/main/java/org/eclipse/aether/util/ChecksumUtils.java @@ -23,6 +23,7 @@ import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; import java.io.InputStreamReader; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -52,49 +53,40 @@ public final class ChecksumUtils throws IOException { String checksum = ""; - - FileInputStream fis = new FileInputStream( checksumFile ); + BufferedReader br = null; try { - BufferedReader br = new BufferedReader( new InputStreamReader( fis, "UTF-8" ), 512 ); - try - { - while ( true ) - { - String line = br.readLine(); - if ( line == null ) - { - break; - } - line = line.trim(); - if ( line.length() > 0 ) - { - checksum = line; - break; - } - } - } - finally + br = new BufferedReader( new InputStreamReader( new FileInputStream( checksumFile ), "UTF-8" ), 512 ); + while ( true ) { - try + String line = br.readLine(); + if ( line == null ) { - br.close(); + break; } - catch ( IOException e ) + line = line.trim(); + if ( line.length() > 0 ) { - // ignored + checksum = line; + break; } } + + br.close(); + br = null; } finally { try { - fis.close(); + if ( br != null ) + { + br.close(); + } } catch ( IOException e ) { - // ignored + // Suppressed due to an exception already thrown in the try block. } } @@ -144,12 +136,13 @@ public final class ChecksumUtils } } - FileInputStream fis = new FileInputStream( dataFile ); + InputStream in = null; try { - for ( byte[] buffer = new byte[32 * 1024];; ) + in = new FileInputStream( dataFile ); + for ( byte[] buffer = new byte[ 32 * 1024 ];; ) { - int read = fis.read( buffer ); + int read = in.read( buffer ); if ( read < 0 ) { break; @@ -159,16 +152,21 @@ public final class ChecksumUtils digest.update( buffer, 0, read ); } } + in.close(); + in = null; } finally { try { - fis.close(); + if ( in != null ) + { + in.close(); + } } catch ( IOException e ) { - // ignored + // Suppressed due to an exception already thrown in the try block. } }