### Question:
ServiceUtils { public static S3Object retryableDownloadS3ObjectToFile(File file, RetryableS3DownloadTask retryableS3DownloadTask, boolean appendData) { boolean hasRetried = false; boolean needRetry; S3Object s3Object; do { needRetry = false; s3Object = retryableS3DownloadTask.getS3ObjectStream(); if (s3Object == null) { return null; } try { ServiceUtils.downloadObjectToFile(s3Object, file, retryableS3DownloadTask.needIntegrityCheck(), appendData); } catch (final AmazonClientException ace) { if (!ace.isRetryable()) { throw ace; } if (ace.getCause() instanceof SocketException || ace.getCause() instanceof SSLProtocolException) { throw ace; } else { needRetry = true; if (hasRetried) { throw ace; } else { log.info("Retry the download of object " + s3Object.getKey() + " (bucket " + s3Object.getBucketName() + ")", ace); hasRetried = true; } } } finally { s3Object.getObjectContent().abort(); } } while (needRetry); return s3Object; }  static Date parseIso8601Date(String dateString); static String formatIso8601Date(Date date); static Date parseRfc822Date(String dateString); static String formatRfc822Date(Date date); static boolean isMultipartUploadETag(String eTag); static byte[] toByteArray(String s); static String removeQuotes(String s); static URL convertRequestToUrl(Request<?> request); static URL convertRequestToUrl(Request<?> request,
            boolean removeLeadingSlashInResourcePath); static String join(List<String> strings); static void downloadObjectToFile(S3Object s3Object,
            File destinationFile, boolean performIntegrityCheck,
            boolean appendData); static S3Object retryableDownloadS3ObjectToFile(File file,
            RetryableS3DownloadTask retryableS3DownloadTask, boolean appendData); static boolean skipMd5CheckPerResponse(ObjectMetadata metadata); static boolean skipMd5CheckPerResponse(ObjectMetadata metadata, S3ClientOptions clientOptions); static boolean skipMd5CheckPerRequest(AmazonWebServiceRequest request); static boolean skipMd5CheckPerRequest(AmazonWebServiceRequest request, S3ClientOptions clientOptions); static final boolean APPEND_MODE; static final boolean OVERWRITE_MODE; }### Answer:
@Test(expected = AmazonClientException.class) public void retryableDownloadS3ObjectToFileTest() throws IOException { final RetryableS3DownloadTask task = new RetryableS3DownloadTask() { private int count = 0; @Override public boolean needIntegrityCheck() { return false; } @Override public S3Object getS3ObjectStream() { try { if (count == 0) { return null; } else if (count == 1) { final S3Object s3Object = new S3Object(); final String input = "test input"; s3Object.setObjectContent(new StringInputStream(input)); final ObjectMetadata metadata = new ObjectMetadata(); metadata.setHeader(Headers.ETAG, "5eed650258ee02f6a77c87b748b764ec"); s3Object.setObjectMetadata(metadata); return s3Object; } else if (count == 2) { throw new AmazonClientException("test exception") { @Override public Throwable getCause() { return new SocketException(); }; @Override public boolean isRetryable() { return false; }; }; } } catch (final UnsupportedEncodingException e) { } finally { count++; } return null; } }; ServiceUtils.retryableDownloadS3ObjectToFile(File.createTempFile("temp1", "temp2"), task, false); ServiceUtils.retryableDownloadS3ObjectToFile(File.createTempFile("temp1", "temp2"), task, false); ServiceUtils.retryableDownloadS3ObjectToFile(File.createTempFile("temp1", "temp2"), task, false); }