

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Menggunakan AWS SDK for Java 2.x
<a name="using"></a>

Bab ini menunjukkan kepada Anda bagaimana menggunakan secara AWS SDK for Java 2.x efektif. Belajar membuat klien layanan, membuat permintaan, menangani tanggapan, dan mengelola kesalahan. Bab ini mencakup pemrograman sinkron dan asinkron, hasil paginasi, pelayan untuk pemantauan sumber daya, dan pengoptimalan kinerja. 

Anda juga akan menemukan praktik terbaik untuk penggunaan kembali klien, panduan pemecahan masalah, pengoptimalan startup Lambda, dukungan HTTP/2, dan konfigurasi DNS.

**Contents**
+ [Membuat Layanan AWS permintaan menggunakan AWS SDK for Java 2.x](work-witih-clients.md)
  + [Menggunakan klien layanan untuk membuat permintaan](work-witih-clients.md#using-service-client)
    + [Buat klien layanan](work-witih-clients.md#work-with-clients-create)
    + [Konfigurasi klien default](work-witih-clients.md#using-default-client)
    + [Konfigurasikan klien layanan](work-witih-clients.md#using-configure-service-clients)
    + [Tutup klien layanan](work-witih-clients.md#using-closing-client)
  + [Membuat permintaan](work-witih-clients.md#using-making-requests)
    + [Gunakan permintaan untuk mengganti konfigurasi klien](work-witih-clients.md#using-override-client-config-request)
  + [Menangani tanggapan](work-witih-clients.md#using-handling-responses)
+ [Pemrograman secara asinkron menggunakan AWS SDK for Java 2.x](asynchronous.md)
  + [Gunakan klien asinkron APIs](asynchronous.md#basics-async-non-streaming)
  + [Menangani streaming dalam metode asinkron](asynchronous.md#basics-async-streaming)
  + [Konfigurasikan opsi asinkron lanjutan](asynchronous.md#advanced-operations)
+ [Praktik terbaik untuk menggunakan AWS SDK for Java 2.x](best-practices.md)
  + [Mencegah permintaan gantung dengan mengonfigurasi batas waktu API](best-practices.md#bestpractice5)
  + [Meningkatkan kinerja dengan menggunakan kembali klien layanan](best-practices.md#bestpractice1)
  + [Mencegah kebocoran sumber daya dengan menutup klien layanan yang tidak digunakan](best-practices.md#bestpractice-close-client)
  + [Mencegah kelelahan kolam koneksi dengan menutup aliran input](best-practices.md#bestpractice2)
  + [Optimalkan kinerja HTTP untuk beban kerja aplikasi Anda](best-practices.md#bestpractice3)
  + [Tingkatkan kinerja SSL dengan OpenSSL untuk klien async](best-practices.md#bestpractice4)
  + [Pantau kinerja aplikasi dengan metrik SDK](best-practices.md#bestpractice6)
+ [Menangani kesalahan di AWS SDK for Java 2.x](handling-exceptions.md)
  + [Mengapa pengecualian yang tidak dicentang?](handling-exceptions.md#why-unchecked-exceptions)
  + [AwsServiceException (dan subclass)](handling-exceptions.md#sdkserviceexception-and-subclasses)
  + [SdkClientException](handling-exceptions.md#sdkclientexception)
  + [Pengecualian dan perilaku coba lagi](handling-exceptions.md#retried-exceptions)
+ [Menggunakan hasil paginasi di 2.x AWS SDK untuk Java](pagination.md)
  + [pagination sinkron](pagination.md#synchronous-pagination)
    + [Iterasi di atas halaman](pagination.md#iterate-pages)
    + [Iterasi di atas objek](pagination.md#iterate-objects)
      + [Gunakan aliran](pagination.md#use-a-stream)
      + [Gunakan untuk setiap loop](pagination.md#for-loop)
    + [Pagination manual](pagination.md#manual-pagination)
  + [pagination asinkron](pagination.md#asynchronous-pagination)
    + [Ulangi halaman nama tabel](pagination.md#iterate-pages-async)
      + [Gunakan `Subscriber`](pagination.md#use-a-subscriber)
      + [Gunakan `Consumer`](pagination.md#id1pagination)
    + [Ulangi nama tabel](pagination.md#iterate-objects-async)
      + [Gunakan `Subscriber`](pagination.md#id2)
      + [Gunakan `Consumer`](pagination.md#for-loop-async)
    + [Gunakan pustaka pihak ketiga](pagination.md#use-third-party-library)
+ [Menggunakan pelayan di AWS SDK for Java 2.x](waiters.md)
  + [Prasyarat](waiters.md#prerequisiteswaiters)
  + [Menggunakan pelayan](waiters.md#id1waiters)
    + [Pemrograman sinkron](waiters.md#synchronous-programming)
    + [Pemrograman asinkron](waiters.md#asynchronous-programming)
  + [Konfigurasikan pelayan](waiters.md#configuring-waiters)
    + [Konfigurasikan pelayan](waiters.md#configure-a-waiter)
    + [Ganti konfigurasi untuk permintaan tertentu](waiters.md#override-configuration-for-a-specific-request)
  + [Contoh kode](waiters.md#code-examples)
+ [Pemecahan masalah FAQs](troubleshooting.md)
  + [Bagaimana cara memperbaiki kesalahan "`java.net.SocketException`: Pengaturan ulang koneksi” atau “server gagal menyelesaikan respons”?](troubleshooting.md#faq-socketexception)
  + [Bagaimana cara memperbaiki “batas waktu koneksi”?](troubleshooting.md#faq-connection-timeout)
  + [Bagaimana cara memperbaiki "`java.net.SocketTimeoutException`: Baca waktunya habis”?](troubleshooting.md#faq-socket-timeout)
  + [Bagaimana cara memperbaiki kesalahan “Tidak dapat menjalankan permintaan HTTP: Batas waktu menunggu koneksi dari kumpulan”?](troubleshooting.md#faq-pool-timeout)
  + [Bagaimana cara memperbaiki`NoClassDefFoundError`, `NoSuchMethodError` atau`NoSuchFieldError`?](troubleshooting.md#faq-classpath-errors)
  + [Bagaimana cara memperbaiki kesalahan "`SignatureDoesNotMatch`" atau “Tanda tangan permintaan yang kami hitung tidak cocok dengan tanda tangan yang Anda berikan”?](troubleshooting.md#faq-signature-does-not-match-error)
  + [Bagaimana cara memperbaiki kesalahan "`java.lang.IllegalStateException`: Connection pool shut down”?](troubleshooting.md#faq-connection-pool-shutdown-exception)
  + [Bagaimana cara memperbaiki “Tidak dapat memuat kredensyal dari salah satu penyedia dalam rantai “? AwsCredentialsProviderChain](troubleshooting.md#faq-credentials-provider-chain)
    + [Penyebab dan solusi umum](troubleshooting.md#faq-cred-provider-chain-common-causes-and-solutions)
      + [Tinjau konfigurasi kredensyal Anda](troubleshooting.md#faq-cred-provider-chain-check-config)
        + [Untuk instans Amazon EC2](troubleshooting.md#faq-cred-check-ec2)
        + [Untuk lingkungan kontainer](troubleshooting.md#faq-cred-check-container-env)
        + [Untuk pengembangan lokal](troubleshooting.md#faq-cred-check-local-dev)
        + [Untuk federasi identitas web](troubleshooting.md#faq-cred-check-web-id-federation)
      + [Masalah konektivitas jaringan atau proxy](troubleshooting.md#faq-credentials-provider-chain-network-issues)
+ [Kurangi waktu startup SDK untuk AWS Lambda](lambda-optimize-starttime.md)
  + [Gunakan klien HTTP AWS berbasis CRT](lambda-optimize-starttime.md#lambda-quick-url)
  + [Hapus dependensi klien HTTP yang tidak digunakan](lambda-optimize-starttime.md#lambda-quick-remove-deps)
  + [Konfigurasikan klien layanan untuk memintas pencarian](lambda-optimize-starttime.md#lambda-quick-clients)
  + [Inisialisasi klien SDK di luar penangan fungsi Lambda](lambda-optimize-starttime.md#lambda-quick-initialize)
  + [Minimalkan injeksi ketergantungan](lambda-optimize-starttime.md#lambda-quick-di)
  + [Gunakan penargetan Maven Archetype AWS Lambda](lambda-optimize-starttime.md#lambda-quick-maven)
  + [Pertimbangkan Lambda SnapStart untuk Java](lambda-optimize-starttime.md#lambda-quick-snapstart)
  + [Perubahan versi 2.x yang memengaruhi waktu startup](lambda-optimize-starttime.md#example-client-configuration)
  + [Sumber daya tambahan](lambda-optimize-starttime.md#lambda-quick-resources)
+ [Implementasikan `ContentStreamProvider` di AWS SDK for Java 2.x](content-stream-provider.md)
  + [Gunakan `mark()` dan `reset()`](content-stream-provider.md#csp-impl-mark-reset)
  + [Gunakan buffering jika `mark()` dan tidak `reset()` tersedia](content-stream-provider.md#csp-impl-unsupported-streams)
  + [Buat aliran baru](content-stream-provider.md#csp-impl-new-stream)
+ [Mengatur JVM TTL untuk pencarian nama DNS](jvm-ttl-dns.md)
  + [Cara mengatur JVM TTL](jvm-ttl-dns.md#how-to-set-the-jvm-ttl)
    + [Opsi 1: Atur secara terprogram di aplikasi Anda](jvm-ttl-dns.md#set-ttl-programmatically)
    + [Opsi 2: Atur di file java.security](jvm-ttl-dns.md#set-ttl-java-security-file)
    + [Opsi 3: Gunakan fallback properti sistem JDK (baris perintah)](jvm-ttl-dns.md#set-ttl-system-property)
+ [Bekerja dengan HTTP/2 di AWS SDK untuk Java](http2.md)

# Membuat Layanan AWS permintaan menggunakan AWS SDK for Java 2.x
<a name="work-witih-clients"></a>

## Menggunakan klien layanan untuk membuat permintaan
<a name="using-service-client"></a>

Setelah menyelesaikan langkah-langkah dalam [Menyiapkan SDK](setup.md) dan memahami cara [mengonfigurasi klien layanan](configuring-service-clients.md), Anda siap mengajukan permintaan ke AWS layanan seperti Amazon S3, Amazon DynamoDB, Amazon EC2 AWS Identity and Access Management, dan lainnya.

### Buat klien layanan
<a name="work-with-clients-create"></a>

Untuk membuat permintaan ke Layanan AWS, Anda harus terlebih dahulu membuat instance klien layanan untuk layanan tersebut dengan menggunakan metode pabrik statis,. `builder()` `builder()`Metode mengembalikan `builder` objek yang memungkinkan Anda untuk menyesuaikan klien layanan. Metode penyetel yang lancar mengembalikan `builder` objek, sehingga Anda dapat merantai panggilan metode untuk kenyamanan dan kode yang lebih mudah dibaca. Setelah Anda mengkonfigurasi properti yang Anda inginkan, panggil `build()` metode untuk membuat klien.

Sebagai contoh, cuplikan kode berikut membuat instance `Ec2Client` objek sebagai klien layanan untuk Amazon EC2.

```
Region region = Region.US_WEST_2;
Ec2Client ec2Client = Ec2Client.builder()
        .region(region)
        .build();
```

**catatan**  
Klien layanan di SDK aman untuk utas. Untuk kinerja terbaik, perlakukan mereka sebagai benda berumur panjang. Setiap klien memiliki sumber daya kolam koneksi sendiri yang dilepaskan saat klien mengumpulkan sampah.  
Objek klien layanan tidak dapat diubah, jadi Anda harus membuat klien baru untuk setiap layanan yang Anda minta, atau jika Anda ingin menggunakan konfigurasi yang berbeda untuk membuat permintaan ke layanan yang sama.  
Menentukan `Region` dalam pembuat klien layanan tidak diperlukan untuk semua AWS layanan; namun, ini adalah praktik terbaik untuk mengatur Wilayah untuk panggilan API yang Anda buat dalam aplikasi Anda. Lihat [pemilihan AWS wilayah](region-selection.md) untuk informasi lebih lanjut.

### Konfigurasi klien default
<a name="using-default-client"></a>

Pembangun klien memiliki metode pabrik lain bernama`create()`. Metode ini menciptakan klien layanan dengan konfigurasi default. Ini menggunakan [rantai penyedia default](credentials-chain.md) untuk memuat kredensil dan rantai [Wilayah AWS penyedia default](region-selection.md#automatically-determine-the-aws-region-from-the-environment). Jika kredensil atau Wilayah tidak dapat ditentukan dari lingkungan tempat aplikasi berjalan, panggilan ke `create` gagal. Lihat [Menggunakan kredensil](credentials.md) dan [pemilihan Wilayah](region-selection.md) untuk informasi selengkapnya tentang cara SDK menentukan kredensil dan Wilayah yang akan digunakan.

Misalnya, cuplikan kode berikut membuat instance `DynamoDbClient` objek sebagai klien layanan untuk Amazon DynamoDB:

```
DynamoDbClient dynamoDbClient = DynamoDbClient.create();
```

### Konfigurasikan klien layanan
<a name="using-configure-service-clients"></a>

Untuk detail tentang cara mengonfigurasi klien layanan, lihat [Konfigurasi klien secara eksternal](configuring-service-clients-ext.md) dan[Konfigurasi klien dalam kode](configuring-service-clients-code.md).

### Tutup klien layanan
<a name="using-closing-client"></a>

Sebagai praktik terbaik, Anda harus menggunakan klien layanan untuk beberapa panggilan layanan API selama masa pakai aplikasi. Namun, jika Anda membutuhkan klien layanan untuk penggunaan satu kali atau tidak lagi membutuhkan klien layanan, tutuplah.

Panggil `close()` metode ketika klien layanan tidak lagi diperlukan untuk membebaskan sumber daya.

```
ec2Client.close();
```

Jika Anda memerlukan klien layanan untuk penggunaan satu kali, Anda dapat membuat instance klien layanan sebagai sumber daya dalam pernyataan -with-resources. `try` Klien layanan mengimplementasikan `[Autoclosable](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/AutoCloseable.html)` antarmuka, sehingga JDK secara otomatis memanggil `close()` metode di akhir pernyataan.

Contoh berikut menunjukkan cara menggunakan klien layanan untuk panggilan satu kali. `StsClient`Yang memanggil AWS Security Token Service ditutup setelah mengembalikan ID akun.

```
import software.amazon.awssdk.services.sts.StsClient;

String getAccountID() {
    try (StsClient stsClient = StsClient.create()) {
       return stsClient.getCallerIdentity().account();
    }
}
```

## Membuat permintaan
<a name="using-making-requests"></a>

Gunakan klien layanan untuk membuat permintaan ke yang sesuai Layanan AWS.

Misalnya, cuplikan kode ini menunjukkan cara membuat `RunInstancesRequest` objek untuk membuat instance Amazon EC2 baru:

```
// Create the request by using the fluid setter methods of the request builder.
RunInstancesRequest runInstancesRequest = RunInstancesRequest.builder()
        .imageId(amiId)
        .instanceType(InstanceType.T1_MICRO)
        .maxCount(1)
        .minCount(1)
        .build();

// Use the configured request with the service client.
RunInstancesResponse response = ec2Client.runInstances(runInstancesRequest);
```

Alih-alih membuat permintaan dan meneruskan instance, SDK menyediakan API lancar yang dapat Anda gunakan untuk membuat permintaan. Dengan API yang lancar, Anda dapat menggunakan ekspresi lambda Java untuk membuat permintaan 'in-line'.

Contoh berikut menulis ulang contoh sebelumnya dengan menggunakan versi `runInstances` [metode yang menggunakan pembangun](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/Ec2Client.html#runInstances(java.util.function.Consumer)) untuk membuat permintaan.

```
// Create the request by using a lambda expression.
RunInstancesResponse response = ec2.runInstances(r -> r
                .imageId(amiId)
                .instanceType(InstanceType.T1_MICRO)
                .maxCount(1)
                .minCount(1));
```

### Gunakan permintaan untuk mengganti konfigurasi klien
<a name="using-override-client-config-request"></a>

Meskipun klien layanan tidak dapat diubah, Anda dapat mengganti banyak pengaturannya di tingkat permintaan. Saat membuat permintaan, Anda dapat memberikan [AwsRequestOverrideConfiguration](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/awscore/AwsRequestOverrideConfiguration.html)instance untuk menyediakan pengaturan yang diganti. Beberapa metode yang dapat Anda gunakan untuk mengganti pengaturan klien adalah:
+ `apiCallAttemptTimeout`
+ `apiCallTimeout`
+ `credentialProvider`
+ `compressionConfiguration`
+ `putHeader`

Untuk contoh penggantian pengaturan klien dengan permintaan, asumsikan bahwa Anda memiliki klien S3 berikut yang menggunakan pengaturan default.

```
S3Client s3Client = S3Client.create();
```

Anda ingin mengunduh file besar dan ingin memastikan permintaan tidak batas waktu sebelum unduhan selesai. Untuk mencapai hal ini, tingkatkan nilai batas waktu hanya untuk satu `GetObject` permintaan seperti yang ditunjukkan dalam kode berikut.

------
#### [ Standard API ]

```
AwsRequestOverrideConfiguration overrideConfiguration = AwsRequestOverrideConfiguration.builder()
    .apiCallTimeout(Duration.ofSeconds(100L))
    .apiCallAttemptTimeout(Duration.ofSeconds(25L))
    .build();

GetObjectRequest request = GetObjectRequest.builder()
    .bucket("amzn-s3-demo-bucket")
    .key("demo-key")
    .overrideConfiguration(overrideConfiguration)
    .build();

s3Client.getObject(request, myPath);
```

------
#### [ Fluent API ]

```
s3Client.getObject(b -> b
        .bucket("amzn-s3-demo-bucket")
        .key("demo-key")
        .overrideConfiguration(c -> c
            .apiCallTimeout(Duration.ofSeconds(100L))
            .apiCallAttemptTimeout(Duration.ofSeconds(25L))),
    myPath);
```

------

## Menangani tanggapan
<a name="using-handling-responses"></a>

SDK mengembalikan objek respons untuk sebagian besar operasi layanan. Kode Anda dapat memproses informasi dalam objek respons sesuai dengan kebutuhan Anda.

Misalnya, cuplikan kode berikut mencetak id contoh pertama yang dikembalikan dengan [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/model/RunInstancesResponse.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/model/RunInstancesResponse.html)objek dari permintaan sebelumnya.

```
RunInstancesResponse runInstancesResponse = ec2Client.runInstances(runInstancesRequest);
System.out.println(runInstancesResponse.instances().get(0).instanceId());
```

Namun, tidak semua operasi mengembalikan objek respons dengan data khusus layanan. Dalam situasi ini, Anda dapat menanyakan status respons HTTP untuk mengetahui apakah operasi berhasil.

Misalnya, kode dalam cuplikan berikut memeriksa respons HTTP untuk melihat apakah [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sesv2/SesV2Client.html#deleteContactList(software.amazon.awssdk.services.sesv2.model.DeleteContactListRequest)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sesv2/SesV2Client.html#deleteContactList(software.amazon.awssdk.services.sesv2.model.DeleteContactListRequest))pengoperasian Amazon Simple Email Service berhasil. 

```
SesV2Client sesv2Client = SesV2Client.create();

DeleteContactListRequest request = DeleteContactListRequest.builder()
    .contactListName("ExampleContactListName")
    .build();

DeleteContactListResponse response = sesv2Client.deleteContactList(request);
if (response.sdkHttpResponse().isSuccessful()) {
    System.out.println("Contact list deleted successfully");
} else {
    System.out.println("Failed to delete contact list. Status code: " + response.sdkHttpResponse().statusCode());
}
```

# Pemrograman secara asinkron menggunakan AWS SDK for Java 2.x
<a name="asynchronous"></a>

 AWS SDK for Java 2.x Fitur klien asinkron dengan I/O dukungan non-pemblokiran yang menerapkan konkurensi tinggi di beberapa utas. Namun, total non-pemblokiran tidak I/O dijamin. Klien asinkron dapat melakukan pemblokiran panggilan dalam beberapa kasus seperti pengambilan kredensi, penandatanganan permintaan menggunakan [AWS Sigv4 (SigV4)](https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html), atau penemuan titik akhir. 

Metode sinkron memblokir eksekusi thread Anda hingga klien menerima respons dari layanan. Metode asinkron segera kembali, memberikan kontrol kembali ke utas panggilan tanpa menunggu respons.

Karena metode asinkron kembali sebelum respons tersedia, Anda memerlukan cara untuk mendapatkan respons saat sudah siap. Metode untuk klien asinkron di 2.x dari *CompletableFuture objek AWS SDK untuk Java * kembali yang memungkinkan Anda mengakses respons saat sudah siap.

## Gunakan klien asinkron APIs
<a name="basics-async-non-streaming"></a>

*Tanda tangan metode klien asinkron sama dengan rekan sinkron mereka, tetapi metode asinkron mengembalikan [CompletableFuture](https://docs.oracle.com/javase/8/docs/api/index.html?java/util/concurrent/CompletableFuture.html)objek yang berisi hasil operasi asinkron di masa depan.* Jika kesalahan dilemparkan saat metode asinkron SDK dijalankan, kesalahan dilemparkan sebagai. `CompletionException` 

Salah satu pendekatan yang dapat Anda gunakan untuk mendapatkan hasilnya adalah dengan menghubungkan `whenComplete()` metode ke yang `CompletableFuture` dikembalikan oleh pemanggilan metode SDK. `whenComplete()`Metode menerima hasil atau objek Throwable dari tipe `CompletionException` tergantung pada bagaimana panggilan asinkron selesai. Anda memberikan tindakan `whenComplete()` untuk memproses atau memeriksa hasil sebelum dikembalikan ke kode panggilan.

Jika Anda ingin mengembalikan sesuatu selain objek yang dikembalikan oleh metode SDK, gunakan `handle()` metode sebagai gantinya. `handle()`Metode ini mengambil parameter yang sama seperti`whenComplete()`, tetapi Anda dapat memproses hasilnya dan mengembalikan objek.

Untuk menunggu rantai asinkron selesai dan mengambil hasil penyelesaian, Anda dapat memanggil metode. `join()` Jika `Throwable` objek tidak ditangani dalam rantai, `join()` metode melempar tanda centang `CompletionException` yang membungkus pengecualian asli. Anda mengakses pengecualian asli dengan`CompletionException#getCause()`. Anda juga dapat memanggil `CompletableFuture#get()` metode untuk mendapatkan hasil penyelesaian. `get()`Metode ini, bagaimanapun, dapat membuang pengecualian yang diperiksa.

Contoh berikut menunjukkan dua variasi bagaimana Anda dapat bekerja dengan `listTables()` metode klien asinkron DynamoDB. Tindakan diteruskan untuk `whenComplete()` hanya mencatat respons yang berhasil, sedangkan `handle()` versi mengekstrak daftar nama tabel dan mengembalikan daftar. Dalam kedua kasus jika kesalahan dihasilkan dalam rantai asinkron, kesalahan dilemparkan kembali sehingga kode klien memiliki kesempatan untuk menanganinya.

 **Impor** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient;
import software.amazon.awssdk.services.dynamodb.model.ListTablesRequest;
import software.amazon.awssdk.services.dynamodb.model.ListTablesResponse;

import java.util.List;
import java.util.concurrent.CompletableFuture;
```

 **Kode** 

------
#### [ whenComplete() variation ]

```
public class DynamoDbAsyncListTables {

    public static void main(String[] args) {
        Region region = Region.US_EAST_1;
        DynamoDbAsyncClient dynamoDbAsyncClient = DynamoDbAsyncClient.builder().region(region).build();
        try {
            ListTablesResponse listTablesResponse = listTablesWhenComplete(dynamoDbAsyncClient).join();  // The join() method may throw a CompletionException.
            if (listTablesResponse.hasTableNames()){
                System.out.println("Table exist in this region: " + region.id());
            }
        } catch (RuntimeException e) {
            // Handle as needed. Here we simply print out the class names.
            System.out.println(e.getClass()); // Prints 'class java.util.concurrent.CompletionException'.
            System.out.println(e.getCause().getClass()); // Prints 'class software.amazon.awssdk.services.dynamodb.model.DynamoDbException'.
        }
    }

    public static CompletableFuture<ListTablesResponse> listTablesWhenComplete(DynamoDbAsyncClient client) {
        return client.listTables(ListTablesRequest.builder().build())
            .whenComplete((listTablesResponse, throwable) -> {
                if (listTablesResponse != null) {  // Consume the response.
                    System.out.println("The SDK's listTables method completed successfully.");
                } else {
                    RuntimeException cause = (RuntimeException) throwable.getCause(); // If an error was thrown during the SDK's listTables method it is wrapped in a CompletionException.
                                                                                      // The SDK throws only RuntimeExceptions, so this is a safe cast.
                    System.out.println(cause.getMessage());  // Log error here, but rethrow so the calling code can handle as needed.
                    throw cause;
                }
            });
    }
```

------
#### [ handle() variation ]

```
public class DynamoDbAsyncListTables {

    public static void main(String[] args) {
        Region region = Region.US_EAST_1;
        DynamoDbAsyncClient dynamoDbAsyncClient = DynamoDbAsyncClient.builder().region(region).build();
        try {
            List<String> tableNames = listTablesHandle(dynamoDbAsyncClient).join(); // The join() method may throw a CompletionException.
            tableNames.forEach(System.out::println);
        } catch (RuntimeException e) {
            // Handle as needed. Here we simply print out the class names.
            System.out.println(e.getClass()); // Prints 'class java.util.concurrent.CompletionException'.
            System.out.println(e.getCause().getClass()); // Prints 'class software.amazon.awssdk.services.dynamodb.model.DynamoDbException'.
        }
    }

    public static CompletableFuture<List<String>> listTablesHandle(DynamoDbAsyncClient client) {
        return client.listTables(ListTablesRequest.builder().build())
            .handle((listTablesResponse, throwable) -> {
                if (listTablesResponse != null) {
                    return listTablesResponse.tableNames(); // Return the list of table names.
                } else {
                    RuntimeException cause = (RuntimeException) throwable.getCause(); // If an error was thrown during the SDK's listTables method it is wrapped in a CompletionException.
                                                                                      // The SDK throws only RuntimeExceptions, so this is a safe cast.
                    System.out.println(cause.getMessage());  // Log error here, but rethrow so the calling code can handle as needed.
                    throw cause;
                }
            });
    }
}
```

------

## Menangani streaming dalam metode asinkron
<a name="basics-async-streaming"></a>

Untuk metode asinkron dengan konten streaming, Anda harus menyediakan [AsyncRequestBody](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/async/AsyncRequestBody.html)untuk menyediakan konten secara bertahap, atau [AsyncResponseTransformer](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/async/AsyncResponseTransformer.html)untuk menerima dan memproses respons.

Contoh berikut mengunggah file ke Amazon S3 asinkron dengan menggunakan bentuk operasi asinkron. `PutObject`

 **Impor** 

```
import software.amazon.awssdk.core.async.AsyncRequestBody;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3AsyncClient;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.PutObjectResponse;
import java.nio.file.Paths;
import java.util.concurrent.CompletableFuture;
```

 **Kode** 

```
/**
 * To run this AWS code example, ensure that you have setup your development environment, including your AWS credentials.
 *
 * For information, see this documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */

public class S3AsyncOps {

     public static void main(String[] args) {

         final String USAGE = "\n" +
                 "Usage:\n" +
                 "    S3AsyncOps <bucketName> <key> <path>\n\n" +
                 "Where:\n" +
                 "    bucketName - the name of the Amazon S3 bucket (for example, bucket1). \n\n" +
                 "    key - the name of the object (for example, book.pdf). \n" +
                 "    path - the local path to the file (for example, C:/AWS/book.pdf). \n" ;

        if (args.length != 3) {
            System.out.println(USAGE);
             System.exit(1);
        }

        String bucketName = args[0];
        String key = args[1];
        String path = args[2];

        Region region = Region.US_WEST_2;
        S3AsyncClient client = S3AsyncClient.builder()
                .region(region)
                .build();

        PutObjectRequest objectRequest = PutObjectRequest.builder()
                .bucket(bucketName)
                .key(key)
                .build();

        // Put the object into the bucket
        CompletableFuture<PutObjectResponse> future = client.putObject(objectRequest,
                AsyncRequestBody.fromFile(Paths.get(path))
        );
        future.whenComplete((resp, err) -> {
            try {
                if (resp != null) {
                    System.out.println("Object uploaded. Details: " + resp);
                } else {
                    // Handle error
                    err.printStackTrace();
                }
            } finally {
                // Only close the client when you are completely done with it
                client.close();
            }
        });

        future.join();
    }
}
```

Contoh berikut mendapatkan file dari Amazon S3 dengan menggunakan bentuk asinkron operasi. `GetObject`

 **Impor** 

```
import software.amazon.awssdk.core.async.AsyncResponseTransformer;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3AsyncClient;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.GetObjectResponse;
import java.nio.file.Paths;
import java.util.concurrent.CompletableFuture;
```

 **Kode** 

```
/**
 * To run this AWS code example, ensure that you have setup your development environment, including your AWS credentials.
 *
 * For information, see this documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */

public class S3AsyncStreamOps {

    public static void main(String[] args) {

        final String USAGE = "\n" +
                "Usage:\n" +
                "    S3AsyncStreamOps <bucketName> <objectKey> <path>\n\n" +
                "Where:\n" +
                "    bucketName - the name of the Amazon S3 bucket (for example, bucket1). \n\n" +
                "    objectKey - the name of the object (for example, book.pdf). \n" +
                "    path - the local path to the file (for example, C:/AWS/book.pdf). \n" ;

        if (args.length != 3) {
            System.out.println(USAGE);
            System.exit(1);
         }

        String bucketName = args[0];
        String objectKey = args[1];
        String path = args[2];

        Region region = Region.US_WEST_2;
        S3AsyncClient client = S3AsyncClient.builder()
                .region(region)
                .build();

        GetObjectRequest objectRequest = GetObjectRequest.builder()
                .bucket(bucketName)
                .key(objectKey)
                .build();

        CompletableFuture<GetObjectResponse> futureGet = client.getObject(objectRequest,
                AsyncResponseTransformer.toFile(Paths.get(path)));

        futureGet.whenComplete((resp, err) -> {
            try {
                if (resp != null) {
                    System.out.println("Object downloaded. Details: "+resp);
                } else {
                    err.printStackTrace();
                }
            } finally {
               // Only close the client when you are completely done with it
                client.close();
            }
        });
        futureGet.join();
    }
}
```

## Konfigurasikan opsi asinkron lanjutan
<a name="advanced-operations"></a>

 AWS SDK untuk Java 2.x menggunakan [Netty](https://netty.io), kerangka kerja aplikasi jaringan berbasis peristiwa asinkron, untuk menangani thread. I/O AWS SDK untuk Java 2.x membuat Netty `ExecutorService` di belakang, untuk menyelesaikan futures yang dikembalikan dari permintaan klien HTTP hingga ke klien Netty. Abstraksi ini mengurangi risiko aplikasi merusak proses asinkron jika pengembang memilih untuk menghentikan atau menidurkan utas. Secara default, setiap klien asinkron membuat threadpool berdasarkan jumlah prosesor dan mengelola tugas dalam antrian di dalam file. `ExecutorService`

Anda dapat menentukan implementasi JDK tertentu `ExecutorService` ketika Anda membangun klien asinkron Anda. Cuplikan berikut membuat `ExecutorService` dengan jumlah thread tetap.

 **Kode** 

```
S3AsyncClient clientThread = S3AsyncClient.builder()
  .asyncConfiguration(
    b -> b.advancedOption(SdkAdvancedAsyncClientOption
      .FUTURE_COMPLETION_EXECUTOR,
      Executors.newFixedThreadPool(10)
    )
  )
  .build();
```

Untuk mengoptimalkan kinerja, Anda dapat mengelola pelaksana kumpulan utas Anda sendiri, dan menyertakannya saat mengonfigurasi klien Anda.

```
ThreadPoolExecutor executor = new ThreadPoolExecutor(50, 50,
    10, TimeUnit.SECONDS,
    new LinkedBlockingQueue<>(<custom_value>),
    new ThreadFactoryBuilder()
      .threadNamePrefix("sdk-async-response").build());

// Allow idle core threads to time out
executor.allowCoreThreadTimeOut(true);

S3AsyncClient clientThread = S3AsyncClient.builder()
  .asyncConfiguration(
    b -> b.advancedOption(SdkAdvancedAsyncClientOption
      .FUTURE_COMPLETION_EXECUTOR,
      executor
    )
  )
  .build();
```

# Praktik terbaik untuk menggunakan AWS SDK for Java 2.x
<a name="best-practices"></a>

## Mencegah permintaan gantung dengan mengonfigurasi batas waktu API
<a name="bestpractice5"></a>

SDK memberikan [nilai default](https://github.com/aws/aws-sdk-java-v2/blob/a0c8a0af1fa572b16b5bd78f310594d642324156/http-client-spi/src/main/java/software/amazon/awssdk/http/SdkHttpConfigurationOption.java#L134) untuk beberapa opsi batas waktu, seperti batas waktu koneksi dan batas waktu soket, tetapi tidak untuk batas waktu panggilan API atau batas waktu percobaan panggilan API individual. Ini adalah praktik yang baik untuk mengatur batas waktu untuk upaya individu dan seluruh permintaan. Ini akan memastikan aplikasi Anda gagal dengan cepat dengan cara yang optimal ketika ada masalah sementara yang dapat menyebabkan upaya permintaan membutuhkan waktu lebih lama untuk menyelesaikan atau masalah jaringan yang fatal.

Anda dapat mengonfigurasi batas waktu untuk semua permintaan yang dibuat oleh klien layanan menggunakan `[ClientOverrideConfiguration\$1apiCallAttemptTimeout](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/client/config/ClientOverrideConfiguration.html#apiCallAttemptTimeout())` dan`[ClientOverrideConfiguration\$1apiCallTimeout](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/client/config/ClientOverrideConfiguration.html#apiCallTimeout())`.

Contoh berikut menunjukkan konfigurasi klien Amazon S3 dengan nilai batas waktu kustom.

```
S3Client.builder()
        .overrideConfiguration(
             b -> b.apiCallTimeout(Duration.ofSeconds(<custom value>))
                   .apiCallAttemptTimeout(Duration.ofMillis(<custom value>)))
        .build();
```

**`apiCallAttemptTimeout`**  
Pengaturan ini menetapkan jumlah waktu untuk satu percobaan HTTP, setelah itu panggilan API dapat dicoba ulang.

**`apiCallTimeout`**  
Nilai untuk properti ini mengonfigurasi jumlah waktu untuk seluruh eksekusi, termasuk semua upaya coba lagi.

Sebagai alternatif untuk mengatur nilai batas waktu ini pada klien layanan, Anda dapat menggunakan [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/RequestOverrideConfiguration.html#apiCallTimeout()](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/RequestOverrideConfiguration.html#apiCallTimeout())dan `[RequestOverrideConfiguration\$1apiCallAttemptTimeout()](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/RequestOverrideConfiguration.html#apiCallAttemptTimeout())` mengonfigurasi satu permintaan.

Contoh berikut mengkonfigurasi `listBuckets` permintaan tunggal dengan nilai batas waktu kustom.

```
s3Client.listBuckets(lbr -> lbr.overrideConfiguration(
        b -> b.apiCallTimeout(Duration.ofSeconds(<custom value>))
               .apiCallAttemptTimeout(Duration.ofMillis(<custom value>))));
```

Saat Anda menggunakan properti ini bersama-sama, Anda menetapkan batas keras pada total waktu yang dihabiskan untuk semua upaya di seluruh percobaan ulang. Anda juga menetapkan permintaan HTTP individual untuk gagal cepat pada permintaan yang lambat.

## Meningkatkan kinerja dengan menggunakan kembali klien layanan
<a name="bestpractice1"></a>

Setiap [klien layanan](work-witih-clients.md) mempertahankan kumpulan koneksi HTTP sendiri. Koneksi yang sudah ada di kolam dapat digunakan kembali oleh permintaan baru untuk mengurangi waktu untuk membuat koneksi baru. Kami merekomendasikan berbagi satu contoh klien untuk menghindari overhead memiliki terlalu banyak kumpulan koneksi yang tidak digunakan secara efektif. Semua klien layanan aman untuk utas.

Jika Anda tidak ingin berbagi instance klien, panggil `close()` instance untuk melepaskan sumber daya saat klien tidak diperlukan.

## Mencegah kebocoran sumber daya dengan menutup klien layanan yang tidak digunakan
<a name="bestpractice-close-client"></a>

Tutup [klien layanan](work-witih-clients.md) untuk melepaskan sumber daya, seperti utas, jika tidak lagi diperlukan. Jika Anda tidak ingin berbagi instance klien, panggil `close()` instance untuk melepaskan sumber daya saat klien tidak diperlukan.

## Mencegah kelelahan kolam koneksi dengan menutup aliran input
<a name="bestpractice2"></a>

Untuk operasi streaming seperti`[S3Client\$1getObject](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3Client.html#getObject(java.util.function.Consumer,java.nio.file.Path))`, jika Anda bekerja dengan `[ResponseInputStream](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/ResponseInputStream.html)` langsung, kami sarankan Anda melakukan hal berikut:
+ Baca semua data dari aliran input sesegera mungkin.
+ Tutup aliran input sesegera mungkin.

Kami membuat rekomendasi ini karena aliran input adalah aliran langsung data dari koneksi HTTP dan koneksi HTTP yang mendasarinya tidak dapat digunakan kembali sampai semua data dari aliran telah dibaca dan aliran ditutup. Jika aturan ini tidak diikuti, klien dapat kehabisan sumber daya dengan mengalokasikan terlalu banyak koneksi HTTP yang terbuka, tetapi tidak terpakai.

## Optimalkan kinerja HTTP untuk beban kerja aplikasi Anda
<a name="bestpractice3"></a>

SDK menyediakan satu set [konfigurasi http default](https://github.com/aws/aws-sdk-java-v2/blob/master/http-client-spi/src/main/java/software/amazon/awssdk/http/SdkHttpConfigurationOption.java) yang berlaku untuk kasus penggunaan umum. Kami menyarankan agar pelanggan menyetel konfigurasi HTTP untuk aplikasi mereka berdasarkan kasus penggunaan mereka. 

Sebagai titik awal yang baik, SDK menawarkan fitur [default konfigurasi cerdas](http-configuration.md#http-config-smart-defaults). Fitur ini tersedia dimulai dengan versi 2.17.102. Anda memilih mode tergantung pada kasus penggunaan Anda, yang memberikan nilai konfigurasi yang masuk akal. 

## Tingkatkan kinerja SSL dengan OpenSSL untuk klien async
<a name="bestpractice4"></a>

Secara default, SDK [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/nio/netty/NettyNioAsyncHttpClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/nio/netty/NettyNioAsyncHttpClient.html)menggunakan implementasi SSL default JDK sebagai. `SslProvider` Pengujian kami menemukan bahwa OpenSSL berkinerja lebih baik daripada implementasi default JDK. Komunitas Netty juga [merekomendasikan penggunaan OpenSSL](https://netty.io/wiki/requirements-for-4.x.html#tls-with-openssl). 

Untuk menggunakan OpenSSL, `netty-tcnative` tambahkan dependensi Anda. Untuk detail konfigurasi, lihat [dokumentasi proyek Netty](https://netty.io/wiki/forked-tomcat-native.html).

Setelah Anda `netty-tcnative` mengonfigurasi proyek Anda, `NettyNioAsyncHttpClient` instance akan secara otomatis memilih OpenSSL. Atau, Anda dapat mengatur secara `SslProvider` eksplisit menggunakan `NettyNioAsyncHttpClient` builder seperti yang ditunjukkan pada cuplikan berikut.

```
NettyNioAsyncHttpClient.builder()
                        .sslProvider(SslProvider.OPENSSL)
                        .build();
```

## Pantau kinerja aplikasi dengan metrik SDK
<a name="bestpractice6"></a>

SDK for Java [dapat mengumpulkan](metrics.md) metrik untuk klien layanan di aplikasi Anda. Anda dapat menggunakan metrik ini untuk mengidentifikasi masalah kinerja, meninjau tren penggunaan secara keseluruhan, meninjau pengecualian klien layanan yang dikembalikan, atau menggali untuk memahami masalah tertentu.

Kami menyarankan Anda mengumpulkan metrik, lalu menganalisis CloudWatch Log Amazon, untuk mendapatkan pemahaman yang lebih dalam tentang kinerja aplikasi Anda.

# Menangani kesalahan di AWS SDK for Java 2.x
<a name="handling-exceptions"></a>

Memahami bagaimana dan kapan pengecualian AWS SDK for Java 2.x melempar penting untuk membangun aplikasi berkualitas tinggi menggunakan SDK. Bagian berikut menjelaskan berbagai kasus pengecualian yang dilemparkan oleh SDK dan cara menanganinya dengan tepat.

## Mengapa pengecualian yang tidak dicentang?
<a name="why-unchecked-exceptions"></a>

Pengecualian AWS SDK untuk Java menggunakan runtime (atau tidak dicentang) alih-alih pengecualian yang dicentang karena alasan berikut:
+ Untuk memungkinkan pengembang mengontrol kesalahan yang ingin mereka tangani tanpa memaksa mereka untuk menangani kasus luar biasa yang tidak mereka khawatirkan (dan membuat kode mereka terlalu bertele-tele)
+ Untuk mencegah masalah skalabilitas yang melekat pada pengecualian yang diperiksa dalam aplikasi besar

Secara umum, pengecualian yang diperiksa bekerja dengan baik pada skala kecil, tetapi dapat menjadi merepotkan karena aplikasi tumbuh dan menjadi lebih kompleks.

## AwsServiceException (dan subclass)
<a name="sdkserviceexception-and-subclasses"></a>

 [AwsServiceException](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/awscore/exception/AwsServiceException.html)adalah pengecualian paling umum yang akan Anda alami saat menggunakan AWS SDK untuk Java. `AwsServiceException`adalah subkelas yang lebih umum [SdkServiceException](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/exception/SdkServiceException.html). `AwsServiceException`s mewakili respons kesalahan dari Layanan AWS. Misalnya, jika Anda mencoba menghentikan Amazon EC2 instance yang tidak ada, Amazon EC2 akan mengembalikan respons kesalahan dan semua detail respons kesalahan itu akan disertakan dalam `AwsServiceException` yang dilemparkan. 

Ketika Anda menemukan`AwsServiceException`, Anda tahu bahwa permintaan Anda berhasil dikirim ke Layanan AWS tetapi tidak dapat berhasil diproses. Ini bisa karena kesalahan dalam parameter permintaan atau karena masalah di sisi layanan.

 `AwsServiceException`memberi Anda informasi seperti:
+ Kode status HTTP yang dikembalikan
+ Kode AWS kesalahan yang dikembalikan
+ Pesan kesalahan terperinci dari layanan di [AwsErrorDetails](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/awscore/exception/AwsErrorDetails.html)kelas
+  AWS ID permintaan untuk permintaan yang gagal

Dalam kebanyakan kasus, subkelas khusus layanan dilemparkan untuk memungkinkan pengembang mengontrol `AwsServiceException` secara halus atas penanganan kasus kesalahan melalui blok catch. Referensi Java SDK API untuk [AwsServiceException](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/awscore/exception/AwsServiceException.html)menampilkan sejumlah besar `AwsServiceException` subclass. Gunakan tautan subkelas untuk menelusuri untuk melihat pengecualian granular yang dilemparkan oleh layanan.

Misalnya, tautan berikut ke referensi SDK API menunjukkan hierarki pengecualian untuk beberapa hal umum. Layanan AWS Daftar subclass yang ditampilkan pada setiap halaman menunjukkan pengecualian spesifik yang dapat ditangkap oleh kode Anda.
+ [Amazon S3](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/model/S3Exception.html)
+ [DynamoDB](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/DynamoDbException.html)
+ [Amazon SQS](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/model/SqsException.html)

Untuk mempelajari lebih lanjut tentang pengecualian, periksa `errorCode` pada [AwsErrorDetails](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/awscore/exception/AwsErrorDetails.html)objek. Anda dapat menggunakan `errorCode` nilai untuk mencari informasi di API panduan layanan. Misalnya jika tertangkap dan `AwsErrorDetails#errorCode()` nilainya`InvalidRequest`, gunakan [daftar kode kesalahan](https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html#ErrorCodeList) di Referensi API Amazon S3 untuk melihat detail selengkapnya. `S3Exception`

## SdkClientException
<a name="sdkclientexception"></a>

 [SdkClientException](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/exception/SdkClientException.html)menunjukkan bahwa masalah terjadi di dalam kode klien Java, baik saat mencoba mengirim permintaan ke AWS atau saat mencoba mengurai respons dari AWS. An `SdkClientException` umumnya lebih parah daripada`SdkServiceException`, dan menunjukkan masalah besar yang mencegah klien melakukan panggilan layanan ke AWS layanan. Misalnya, AWS SDK untuk Java melempar `SdkClientException` jika tidak ada koneksi jaringan yang tersedia ketika Anda mencoba memanggil operasi pada salah satu klien.

## Pengecualian dan perilaku coba lagi
<a name="retried-exceptions"></a>

SDK for Java mencoba ulang permintaan untuk [beberapa pengecualian sisi klien](https://github.com/aws/aws-sdk-java-v2/blob/13985e0668a9a0b12ad331644e3c4fd1385c2cd7/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/retry/SdkDefaultRetrySetting.java#L79C41-L79C41) dan [untuk kode status HTTP](https://github.com/aws/aws-sdk-java-v2/blob/13985e0668a9a0b12ad331644e3c4fd1385c2cd7/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/retry/SdkDefaultRetrySetting.java#L72C31-L72C31) yang diterimanya dari tanggapan. Layanan AWS Kesalahan ini ditangani sebagai bagian dari warisan `RetryMode` yang digunakan klien layanan secara default. Referensi Java API untuk `[RetryMode](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/RetryMode.html)` menjelaskan berbagai cara yang dapat Anda konfigurasi mode.

Untuk menyesuaikan pengecualian dan kode status HTTP yang memicu percobaan ulang otomatis, konfigurasikan klien layanan Anda dengan `[RetryPolicy](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/RetryPolicy.html)` yang menambahkan `[RetryOnExceptionsCondition](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/conditions/RetryOnExceptionsCondition.html)` dan `[RetryOnStatusCodeCondition](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/awscore/retry/conditions/RetryOnErrorCodeCondition.html)` instance.

# Menggunakan hasil paginasi di 2.x AWS SDK untuk Java
<a name="pagination"></a>

Banyak AWS operasi mengembalikan hasil paginasi ketika objek respons terlalu besar untuk dikembalikan dalam satu respons. Di AWS SDK untuk Java 1.0, respons berisi token yang Anda gunakan untuk mengambil halaman hasil berikutnya. Sebaliknya, AWS SDK untuk Java 2.x memiliki metode autopagination yang membuat beberapa panggilan layanan untuk mendapatkan halaman hasil berikutnya untuk Anda secara otomatis. Anda hanya perlu menulis kode yang memproses hasilnya. Autopagination tersedia untuk klien sinkron dan asinkron.

**catatan**  
Cuplikan kode ini mengasumsikan bahwa Anda memahami [dasar-dasar penggunaan SDK](using.md), dan telah mengonfigurasi lingkungan Anda dengan akses masuk [tunggal](get-started-auth.md#setup-credentials).

## pagination sinkron
<a name="synchronous-pagination"></a>

Contoh berikut menunjukkan metode pagination sinkron untuk mencantumkan objek Amazon S3 dalam bucket.

### Iterasi di atas halaman
<a name="iterate-pages"></a>

Contoh pertama menunjukkan penggunaan objek `listRes` paginator, sebuah [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/paginators/ListObjectsV2Iterable.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/paginators/ListObjectsV2Iterable.html)contoh, untuk iterasi melalui semua halaman respon dengan metode. `stream` Kode mengalir di atas halaman respons, mengubah aliran respons menjadi aliran `[S3Object](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/model/S3Object.html)` konten, dan kemudian memproses konten objek. Amazon S3 

Impor berikut berlaku untuk semua contoh di bagian pagination sinkron ini.

#### Impor
<a name="synchronous-pagination-ex-import"></a>

```
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Random;

import software.amazon.awssdk.core.waiters.WaiterResponse;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.paginators.ListObjectsV2Iterable;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.model.S3Exception;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.ListObjectsV2Request;
import software.amazon.awssdk.services.s3.model.ListObjectsV2Response;
import software.amazon.awssdk.services.s3.model.S3Object;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.DeleteObjectRequest;
import software.amazon.awssdk.services.s3.model.DeleteBucketRequest;
import software.amazon.awssdk.services.s3.model.CreateMultipartUploadRequest;
import software.amazon.awssdk.services.s3.model.CreateMultipartUploadResponse;
import software.amazon.awssdk.services.s3.model.CompletedMultipartUpload;
import software.amazon.awssdk.services.s3.model.CreateBucketRequest;
import software.amazon.awssdk.services.s3.model.CompletedPart;
import software.amazon.awssdk.services.s3.model.CreateBucketConfiguration;
import software.amazon.awssdk.services.s3.model.UploadPartRequest;
import software.amazon.awssdk.services.s3.model.CompleteMultipartUploadRequest;
import software.amazon.awssdk.services.s3.waiters.S3Waiter;
import software.amazon.awssdk.services.s3.model.HeadBucketRequest;
import software.amazon.awssdk.services.s3.model.HeadBucketResponse;
```

```
        ListObjectsV2Request listReq = ListObjectsV2Request.builder()
            .bucket(bucketName)
            .maxKeys(1)
            .build();

        ListObjectsV2Iterable listRes = s3.listObjectsV2Paginator(listReq);
        // Process response pages
        listRes.stream()
            .flatMap(r -> r.contents().stream())
            .forEach(content -> System.out
                .println(" Key: " + content.key() + " size = " + content.size()));
```

Lihat [contoh lengkapnya](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/s3/src/main/java/com/example/s3/S3ObjectOperations.java#L112) di GitHub.

### Iterasi di atas objek
<a name="iterate-objects"></a>

Contoh berikut menunjukkan cara untuk mengulangi objek yang dikembalikan dalam respons, bukan halaman respons. `contents`Metode `ListObjectsV2Iterable` kelas mengembalikan sebuah [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/pagination/sync/SdkIterable.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/pagination/sync/SdkIterable.html)yang menyediakan beberapa metode untuk memproses elemen konten yang mendasarinya.

#### Gunakan aliran
<a name="use-a-stream"></a>

Cuplikan berikut menggunakan `stream` metode pada konten respons untuk mengulangi koleksi item paginasi.

```
        // Helper method to work with paginated collection of items directly.
        listRes.contents().stream()
            .forEach(content -> System.out
                .println(" Key: " + content.key() + " size = " + content.size()));
```

Lihat [contoh lengkapnya](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/s3/src/main/java/com/example/s3/S3ObjectOperations.java#L127) di GitHub.

#### Gunakan untuk setiap loop
<a name="for-loop"></a>

Karena `SdkIterable` memperluas `Iterable` antarmuka, Anda dapat memproses konten seperti apa pun`Iterable`. Cuplikan berikut menggunakan `for-each` loop standar untuk iterasi melalui isi respon.

```
        for (S3Object content : listRes.contents()) {
            System.out.println(" Key: " + content.key() + " size = " + content.size());
        }
```

Lihat [contoh lengkapnya](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/s3/src/main/java/com/example/s3/S3ObjectOperations.java#L133) di GitHub.

### Pagination manual
<a name="manual-pagination"></a>

Jika kasus penggunaan Anda memerlukannya, pagination manual masih tersedia. Gunakan token berikutnya di objek respons untuk permintaan berikutnya. Contoh berikut menggunakan `while` loop.

```
        ListObjectsV2Request listObjectsReqManual = ListObjectsV2Request.builder()
            .bucket(bucketName)
            .maxKeys(1)
            .build();

        boolean done = false;
        while (!done) {
            ListObjectsV2Response listObjResponse = s3.listObjectsV2(listObjectsReqManual);
            for (S3Object content : listObjResponse.contents()) {
                System.out.println(content.key());
            }

            if (listObjResponse.nextContinuationToken() == null) {
                done = true;
            }

            listObjectsReqManual = listObjectsReqManual.toBuilder()
                .continuationToken(listObjResponse.nextContinuationToken())
                .build();
        }
```

Lihat [contoh lengkapnya](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/s3/src/main/java/com/example/s3/S3ObjectOperations.java#L90) di GitHub.

## pagination asinkron
<a name="asynchronous-pagination"></a>

Contoh berikut menunjukkan metode pagination asinkron untuk daftar tabel. DynamoDB 

### Ulangi halaman nama tabel
<a name="iterate-pages-async"></a>

Dua contoh berikut menggunakan klien DynamoDB asinkron yang memanggil metode dengan permintaan `listTablesPaginator` untuk mendapatkan file. [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/paginators/ListTablesPublisher.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/paginators/ListTablesPublisher.html) `ListTablesPublisher`mengimplementasikan dua antarmuka, yang menyediakan banyak opsi untuk memproses respons. Kita akan melihat metode masing-masing antarmuka.

#### Gunakan `Subscriber`
<a name="use-a-subscriber"></a>

Contoh kode berikut menunjukkan bagaimana memproses hasil paginasi dengan menggunakan `org.reactivestreams.Publisher` antarmuka yang diimplementasikan oleh. `ListTablesPublisher` Untuk mempelajari lebih lanjut tentang model aliran reaktif, lihat repo [Reactive](https://github.com/reactive-streams/reactive-streams-jvm/blob/v1.0.2/README.md) Streams. GitHub 

Impor berikut berlaku untuk semua contoh di bagian pagination asinkron ini.

##### Impor
<a name="use-a-subscriber-ex-imports"></a>

```
import io.reactivex.rxjava3.core.Flowable;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;
import reactor.core.publisher.Flux;
import software.amazon.awssdk.core.async.SdkPublisher;
import software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient;
import software.amazon.awssdk.services.dynamodb.model.ListTablesRequest;
import software.amazon.awssdk.services.dynamodb.model.ListTablesResponse;
import software.amazon.awssdk.services.dynamodb.paginators.ListTablesPublisher;

import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
```

Kode berikut memperoleh sebuah `ListTablesPublisher` instance.

```
        // Creates a default client with credentials and region loaded from the
        // environment.
        final DynamoDbAsyncClient asyncClient = DynamoDbAsyncClient.create();

        ListTablesRequest listTablesRequest = ListTablesRequest.builder().limit(3).build();
        ListTablesPublisher publisher = asyncClient.listTablesPaginator(listTablesRequest);
```

Kode berikut menggunakan implementasi anonim `org.reactivestreams.Subscriber` untuk memproses hasil untuk setiap halaman.

`onSubscribe`Metode ini memanggil `Subscription.request` metode untuk memulai permintaan data dari penerbit. Metode ini harus dipanggil untuk mulai mendapatkan data dari penerbit. 

`onNext`Metode pelanggan memproses halaman respons dengan mengakses semua nama tabel dan mencetak masing-masing. Setelah halaman diproses, halaman lain diminta dari penerbit. Metode ini dipanggil berulang kali sampai semua halaman diambil.

`onError`Metode ini dipicu jika terjadi kesalahan saat mengambil data. Akhirnya, `onComplete` metode ini dipanggil ketika semua halaman telah diminta.

```
        // A Subscription represents a one-to-one life-cycle of a Subscriber subscribing
        // to a Publisher.
        publisher.subscribe(new Subscriber<ListTablesResponse>() {
            // Maintain a reference to the subscription object, which is required to request
            // data from the publisher.
            private Subscription subscription;

            @Override
            public void onSubscribe(Subscription s) {
                subscription = s;
                // Request method should be called to demand data. Here we request a single
                // page.
                subscription.request(1);
            }

            @Override
            public void onNext(ListTablesResponse response) {
                response.tableNames().forEach(System.out::println);
                // After you process the current page, call the request method to signal that
                // you are ready for next page.
                subscription.request(1);
            }

            @Override
            public void onError(Throwable t) {
                // Called when an error has occurred while processing the requests.
            }

            @Override
            public void onComplete() {
                // This indicates all the results are delivered and there are no more pages
                // left.
            }
        });
```

Lihat [contoh lengkapnya](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/dynamodbasync/src/main/java/com/example/dynamodbasync/AsyncPagination.java#L83) di GitHub.

#### Gunakan `Consumer`
<a name="id1pagination"></a>

`SdkPublisher`Antarmuka yang `ListTablesPublisher` mengimplementasikan memiliki `subscribe` metode yang mengambil `Consumer` dan mengembalikan a`CompletableFuture<Void>`. 

`subscribe`Metode dari antarmuka ini dapat digunakan untuk kasus penggunaan sederhana ketika overhead `org.reactivestreams.Subscriber` mungkin terlalu banyak. Karena kode di bawah ini menghabiskan setiap halaman, ia memanggil `tableNames` metode pada masing-masing halaman. `tableNames`Metode mengembalikan nama tabel DynamoDB yang diproses dengan metode. `java.util.List` `forEach`

```
        // Use a Consumer for simple use cases.
        CompletableFuture<Void> future = publisher.subscribe(
                response -> response.tableNames()
                        .forEach(System.out::println));
```

Lihat [contoh lengkapnya](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/dynamodbasync/src/main/java/com/example/dynamodbasync/AsyncPagination.java#L96) di GitHub.

### Ulangi nama tabel
<a name="iterate-objects-async"></a>

Contoh berikut menunjukkan cara untuk mengulangi objek yang dikembalikan dalam respons, bukan halaman respons. Mirip dengan contoh Amazon S3 sinkron yang sebelumnya ditampilkan dengan `contents` metodenya, kelas hasil asinkron DynamoDB`ListTablesPublisher`, memiliki `tableNames` metode kenyamanan untuk berinteraksi dengan koleksi item yang mendasarinya. Jenis pengembalian `tableNames` metode adalah [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/async/SdkPublisher.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/async/SdkPublisher.html)yang dapat digunakan untuk meminta item di semua halaman.

#### Gunakan `Subscriber`
<a name="id2"></a>

Kode berikut memperoleh koleksi `SdkPublisher` yang mendasari nama tabel.

```
        // Create a default client with credentials and region loaded from the
        // environment.
        final DynamoDbAsyncClient asyncClient = DynamoDbAsyncClient.create();

        ListTablesRequest listTablesRequest = ListTablesRequest.builder().limit(3).build();
        ListTablesPublisher listTablesPublisher = asyncClient.listTablesPaginator(listTablesRequest);
        SdkPublisher<String> publisher = listTablesPublisher.tableNames();
```

Kode berikut menggunakan implementasi anonim `org.reactivestreams.Subscriber` untuk memproses hasil untuk setiap halaman.

`onNext`Metode pelanggan memproses elemen individual dari koleksi. Dalam hal ini, itu adalah nama tabel. Setelah nama tabel diproses, nama tabel lain diminta dari penerbit. Metode ini dipanggil berulang kali sampai semua nama tabel diambil.

```
        // Use a Subscriber.
        publisher.subscribe(new Subscriber<String>() {
            private Subscription subscription;

            @Override
            public void onSubscribe(Subscription s) {
                subscription = s;
                subscription.request(1);
            }

            @Override
            public void onNext(String tableName) {
                System.out.println(tableName);
                subscription.request(1);
            }

            @Override
            public void onError(Throwable t) {
            }

            @Override
            public void onComplete() {
            }
        });
```

Lihat [contoh lengkapnya](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/dynamodbasync/src/main/java/com/example/dynamodbasync/AsyncPagination.java#L147) di GitHub.

#### Gunakan `Consumer`
<a name="for-loop-async"></a>

Contoh berikut menggunakan `subscribe` metode `SdkPublisher` yang membutuhkan a `Consumer` untuk memproses setiap item.

```
        // Use a Consumer.
        CompletableFuture<Void> future = publisher.subscribe(System.out::println);
        future.get();
```

Lihat [contoh lengkapnya](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/dynamodbasync/src/main/java/com/example/dynamodbasync/AsyncPagination.java#L161) di GitHub.

### Gunakan pustaka pihak ketiga
<a name="use-third-party-library"></a>

Anda dapat menggunakan pustaka pihak ketiga lainnya alih-alih menerapkan pelanggan khusus. Contoh ini menunjukkan penggunaan RxJava, tetapi pustaka apa pun yang mengimplementasikan antarmuka aliran reaktif dapat digunakan. Lihat [halaman RxJava wiki GitHub](https://github.com/ReactiveX/RxJava/wiki) untuk informasi lebih lanjut tentang perpustakaan itu.

Untuk menggunakan perpustakaan, tambahkan sebagai dependensi. Jika menggunakan Maven, contoh menunjukkan cuplikan POM untuk digunakan.

 **Entri POM** 

```
<dependency>
      <groupId>io.reactivex.rxjava3</groupId>
      <artifactId>rxjava</artifactId>
      <version>3.1.6</version>
</dependency>
```

 **Kode** 

```
        DynamoDbAsyncClient asyncClient = DynamoDbAsyncClient.create();
        ListTablesPublisher publisher = asyncClient.listTablesPaginator(ListTablesRequest.builder()
                .build());

        // The Flowable class has many helper methods that work with
        // an implementation of an org.reactivestreams.Publisher.
        List<String> tables = Flowable.fromPublisher(publisher)
                .flatMapIterable(ListTablesResponse::tableNames)
                .toList()
                .blockingGet();
        System.out.println(tables);
```

Lihat [contoh lengkapnya](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/dynamodbasync/src/main/java/com/example/dynamodbasync/AsyncPagination.java#L198) di GitHub.

# Menggunakan pelayan di AWS SDK for Java 2.x
<a name="waiters"></a>

Utilitas pelayan dari AWS SDK untuk Java 2.x memungkinkan Anda untuk memvalidasi bahwa AWS sumber daya berada dalam keadaan tertentu sebelum melakukan operasi pada sumber daya tersebut.

*Pelayan* adalah abstraksi yang digunakan untuk polling AWS sumber daya, seperti DynamoDB tabel atau Amazon S3 ember, sampai keadaan yang diinginkan tercapai (atau sampai penentuan dibuat bahwa sumber daya tidak akan pernah mencapai keadaan yang diinginkan). Alih-alih menulis logika untuk terus polling AWS sumber daya Anda, yang dapat menjadi rumit dan rawan kesalahan, Anda dapat menggunakan pelayan untuk polling sumber daya dan membuat kode Anda terus berjalan setelah sumber daya siap.

## Prasyarat
<a name="prerequisiteswaiters"></a>

Sebelum Anda dapat menggunakan pelayan dalam proyek dengan AWS SDK untuk Java, Anda harus menyelesaikan langkah-langkah dalam [Menyiapkan 2.x](setup.md). AWS SDK untuk Java 

Anda juga harus mengonfigurasi dependensi proyek Anda (misalnya, di `build.gradle` file `pom.xml` atau Anda) untuk menggunakan versi `2.15.0` atau versi yang lebih baru. AWS SDK untuk Java

Contoh:

```
<project>
  <dependencyManagement>
   <dependencies>
      <dependency>
        <groupId>software.amazon.awssdk</groupId>
        <artifactId>bom</artifactId>
        <version>2.27.21</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
   </dependencies>
  </dependencyManagement>
</project>
```

## Menggunakan pelayan
<a name="id1waiters"></a>

Untuk membuat instance objek pelayan, pertama buat klien layanan. Tetapkan `waiter()` metode klien layanan sebagai nilai objek pelayan. Setelah instance pelayan ada, atur opsi responsnya untuk mengeksekusi kode yang sesuai.

### Pemrograman sinkron
<a name="synchronous-programming"></a>

Cuplikan kode berikut menunjukkan cara menunggu DynamoDB tabel ada dan berada dalam status **AKTIF**.

```
DynamoDbClient dynamo = DynamoDbClient.create();
DynamoDbWaiter waiter = dynamo.waiter();

WaiterResponse<DescribeTableResponse> waiterResponse =
  waiter.waitUntilTableExists(r -> r.tableName("myTable"));

// print out the matched response with a tableStatus of ACTIVE
waiterResponse.matched().response().ifPresent(System.out::println);
```

### Pemrograman asinkron
<a name="asynchronous-programming"></a>

Cuplikan kode berikut menunjukkan cara menunggu DynamoDB tabel tidak ada lagi.

```
DynamoDbAsyncClient asyncDynamo = DynamoDbAsyncClient.create();
DynamoDbAsyncWaiter asyncWaiter = asyncDynamo.waiter();

CompletableFuture<WaiterResponse<DescribeTableResponse>> waiterResponse =
          asyncWaiter.waitUntilTableNotExists(r -> r.tableName("myTable"));

waiterResponse.whenComplete((r, t) -> {
  if (t == null) {
   // print out the matched ResourceNotFoundException
   r.matched().exception().ifPresent(System.out::println);
  }
}).join();
```

## Konfigurasikan pelayan
<a name="configuring-waiters"></a>

Anda dapat menyesuaikan konfigurasi untuk pelayan dengan menggunakan `overrideConfiguration()` pada pembangunnya. Untuk beberapa operasi, Anda dapat menerapkan konfigurasi khusus saat Anda membuat permintaan.

### Konfigurasikan pelayan
<a name="configure-a-waiter"></a>

Cuplikan kode berikut menunjukkan cara mengganti konfigurasi pada pelayan.

```
// sync
DynamoDbWaiter waiter =
   DynamoDbWaiter.builder()
          .overrideConfiguration(b -> b.maxAttempts(10))
          .client(dynamoDbClient)
          .build();
// async
DynamoDbAsyncWaiter asyncWaiter =
   DynamoDbAsyncWaiter.builder()
          .client(dynamoDbAsyncClient)
          .overrideConfiguration(o -> o.backoffStrategy(
               FixedDelayBackoffStrategy.create(Duration.ofSeconds(2))))
          .scheduledExecutorService(Executors.newScheduledThreadPool(3))
          .build();
```

### Ganti konfigurasi untuk permintaan tertentu
<a name="override-configuration-for-a-specific-request"></a>

Cuplikan kode berikut menunjukkan cara mengganti konfigurasi untuk pelayan berdasarkan per-permintaan. Perhatikan bahwa hanya beberapa operasi yang memiliki konfigurasi yang dapat disesuaikan.

```
waiter.waitUntilTableNotExists(b -> b.tableName("myTable"),
               o -> o.maxAttempts(10));

asyncWaiter.waitUntilTableExists(b -> b.tableName("myTable"),
                 o -> o.waitTimeout(Duration.ofMinutes(1)));
```

## Contoh kode
<a name="code-examples"></a>

Untuk contoh lengkap menggunakan pelayan dengan DynamoDB, lihat [CreateTable.java](https://github.com/awsdocs/aws-doc-sdk-examples/blob/869b7ddbc7c8f66c7c45acd5b813429aff37003e/javav2/example_code/dynamodb/src/main/java/com/example/dynamodb/CreateTable.java) di Repositori Contoh AWS Kode.

Untuk contoh lengkap menggunakan pelayan dengan Amazon S3, lihat [S3 BucketOps .java](https://github.com/awsdocs/aws-doc-sdk-examples/blob/869b7ddbc7c8f66c7c45acd5b813429aff37003e/javav2/example_code/s3/src/main/java/com/example/s3/S3BucketOps.java) di Repositori Contoh Kode. AWS 

# Pemecahan masalah FAQs
<a name="troubleshooting"></a>

Saat Anda menggunakan AWS SDK for Java 2.x dalam aplikasi Anda, Anda mungkin menemukan kesalahan runtime yang tercantum dalam topik ini. Gunakan saran di sini untuk membantu Anda mengungkap akar penyebab dan menyelesaikan kesalahan.

## Bagaimana cara memperbaiki kesalahan "`java.net.SocketException`: Pengaturan ulang koneksi” atau “server gagal menyelesaikan respons”?
<a name="faq-socketexception"></a>

Kesalahan penyetelan ulang koneksi menunjukkan bahwa host Anda Layanan AWS, pihak, atau pihak perantara (misalnya, gateway NAT, proxy, penyeimbang beban) menutup koneksi sebelum permintaan selesai. Karena ada banyak penyebab, menemukan solusi mengharuskan Anda tahu mengapa koneksi ditutup. Item berikut biasanya menyebabkan koneksi ditutup.
+ **Koneksi tidak aktif.**Ini umum untuk operasi streaming, di mana data tidak ditulis ke atau dari kawat untuk jangka waktu tertentu, sehingga pihak perantara mendeteksi koneksi sebagai mati dan menutupnya. Untuk mencegah hal ini, pastikan aplikasi Anda secara aktif mengunduh atau mengunggah data.
+ **Anda telah menutup klien HTTP atau SDK.** Pastikan untuk tidak menutup sumber daya saat sedang digunakan.
+ **Proxy yang salah dikonfigurasi.** Cobalah untuk melewati proxy apa pun yang telah Anda konfigurasikan untuk melihat apakah itu memperbaiki masalah. Jika ini memperbaiki masalah, proxy menutup koneksi Anda karena alasan tertentu. Teliti proxy spesifik Anda untuk menentukan mengapa itu menutup koneksi.

Jika Anda tidak dapat mengidentifikasi masalah, coba jalankan dump TCP untuk koneksi yang terpengaruh di tepi klien jaringan Anda (misalnya, setelah proxy apa pun yang Anda kontrol). 

Jika Anda melihat bahwa AWS titik akhir mengirim `TCP RST` (reset), [hubungi layanan yang terpengaruh](https://aws.amazon.com/contact-us/) untuk melihat apakah mereka dapat menentukan mengapa reset terjadi. Bersiaplah untuk memberikan permintaan IDs dan stempel waktu kapan masalah terjadi. Tim AWS dukungan mungkin juga mendapat manfaat dari [log kawat](logging-slf4j.md#sdk-java-logging-verbose) yang menunjukkan dengan tepat byte apa yang dikirim dan diterima aplikasi Anda dan kapan.

## Bagaimana cara memperbaiki “batas waktu koneksi”?
<a name="faq-connection-timeout"></a>

Kesalahan batas waktu koneksi menunjukkan bahwa host Anda, pihak Layanan AWS, atau pihak perantara (misalnya, gateway NAT, proxy, penyeimbang beban) gagal membuat koneksi baru dengan server dalam batas waktu koneksi yang dikonfigurasi. Item berikut menjelaskan penyebab umum masalah ini.
+ **Batas waktu koneksi yang dikonfigurasi terlalu rendah.** Secara default, batas waktu koneksi adalah 2 detik di file. AWS SDK for Java 2.x Jika Anda mengatur batas waktu koneksi terlalu rendah, Anda mungkin mendapatkan kesalahan ini. Batas waktu koneksi yang disarankan adalah 1 detik jika Anda hanya melakukan panggilan di wilayah dan 3 detik jika Anda membuat permintaan lintas wilayah.
+ **Proxy yang salah dikonfigurasi.** Cobalah untuk melewati proxy apa pun yang Anda konfigurasikan untuk melihat apakah itu memperbaiki masalah. Jika ini memperbaiki masalah, proxy adalah alasan batas waktu koneksi. Teliti proxy spesifik Anda untuk menentukan mengapa hal itu terjadi

Jika Anda tidak dapat mengidentifikasi masalah, coba jalankan dump TCP untuk koneksi yang terpengaruh di tepi klien jaringan Anda (misalnya, setelah proxy apa pun yang Anda kontrol) untuk menyelidiki masalah jaringan apa pun.

## Bagaimana cara memperbaiki "`java.net.SocketTimeoutException`: Baca waktunya habis”?
<a name="faq-socket-timeout"></a>

Kesalahan waktu baca menunjukkan bahwa JVM berusaha membaca data dari sistem operasi yang mendasarinya, tetapi data tidak dikembalikan dalam waktu yang dikonfigurasi melalui SDK. Kesalahan ini dapat terjadi jika sistem operasi, pihak Layanan AWS, atau pihak perantara (misalnya, gateway NAT, proxy, penyeimbang beban) gagal mengirim data dalam waktu yang diharapkan oleh JVM. Karena ada banyak penyebab, menemukan solusi mengharuskan Anda tahu mengapa data tidak dikembalikan.

Coba jalankan dump TCP untuk koneksi yang terpengaruh di tepi klien jaringan Anda (misalnya, setelah proxy apa pun yang Anda kontrol). 

Jika Anda melihat bahwa AWS titik akhir mengirim `TCP RST` (reset), [hubungi layanan yang terpengaruh](https://aws.amazon.com/contact-us/). Bersiaplah untuk memberikan permintaan IDs dan stempel waktu kapan masalah terjadi. Tim AWS dukungan mungkin juga mendapat manfaat dari [log kawat](logging-slf4j.md#sdk-java-logging-verbose) yang menunjukkan dengan tepat byte apa yang dikirim dan diterima aplikasi Anda dan kapan.

## Bagaimana cara memperbaiki kesalahan “Tidak dapat menjalankan permintaan HTTP: Batas waktu menunggu koneksi dari kumpulan”?
<a name="faq-pool-timeout"></a>

Kesalahan ini menunjukkan bahwa permintaan tidak bisa mendapatkan koneksi dari pool dalam waktu maksimum yang ditentukan. Untuk mengatasi masalah ini, sebaiknya [aktifkan metrik sisi klien SDK untuk memublikasikan metrik ke Amazon](metrics.md). CloudWatch Metrik HTTP dapat membantu mempersempit akar penyebabnya. Item berikut menjelaskan penyebab umum kesalahan ini.
+ **Kebocoran koneksi.** Anda dapat menyelidiki ini dengan memeriksa`LeasedConcurrency`,`AvailableConcurrency`, dan `MaxConcurrency` metrik. Jika `LeasedConcurrency` meningkat hingga mencapai `MaxConcurrency` tetapi tidak pernah berkurang, mungkin ada kebocoran koneksi. Penyebab umum kebocoran adalah karena operasi streaming — seperti metode `getObject` S3 — tidak ditutup. Kami menyarankan agar aplikasi Anda membaca semua data dari aliran input sesegera mungkin dan [menutup aliran input setelahnya](best-practices.md#bestpractice2). Bagan berikut menunjukkan seperti apa metrik SDK untuk kebocoran koneksi.  
![\[Tangkapan layar CloudWatch metrik yang menunjukkan kemungkinan kebocoran koneksi.\]](http://docs.aws.amazon.com/id_id/sdk-for-java/latest/developer-guide/images/JavaDevGuide-connection-leak-metrics-chart.png)
+ **Kelaparan kolam koneksi.**Hal ini dapat terjadi jika tingkat permintaan Anda terlalu tinggi dan ukuran kumpulan koneksi yang telah dikonfigurasi tidak dapat memenuhi permintaan permintaan. Ukuran kumpulan koneksi default adalah 50, dan ketika koneksi di kolam mencapai maksimum, klien HTTP mengantri permintaan masuk hingga koneksi tersedia. Bagan berikut menunjukkan seperti apa metrik SDK untuk kelaparan kumpulan koneksi.  
![\[Tangkapan layar CloudWatch metrik yang menunjukkan bagaimana kelaparan kumpulan koneksi mungkin terlihat.\]](http://docs.aws.amazon.com/id_id/sdk-for-java/latest/developer-guide/images/JavaDevGuide-connection-pool-starvation-chart.png)

  Untuk mengurangi masalah ini, pertimbangkan untuk mengambil salah satu tindakan berikut.
  + Tingkatkan ukuran kolam koneksi,
  + Tingkatkan batas waktu akuisisi.
  + Memperlambat tingkat permintaan.

  Dengan meningkatkan jumlah maksimum koneksi, throughput klien dapat meningkat (kecuali antarmuka jaringan sudah sepenuhnya digunakan). Namun, Anda akhirnya dapat menekan batasan sistem operasi pada jumlah deskriptor file yang digunakan oleh proses. Jika Anda sudah sepenuhnya menggunakan antarmuka jaringan Anda atau tidak dapat meningkatkan jumlah koneksi Anda lebih lanjut, coba tingkatkan batas waktu perolehan. Dengan peningkatan ini, Anda mendapatkan waktu ekstra untuk permintaan untuk mendapatkan koneksi sebelum waktu habis. Jika koneksi tidak bebas, permintaan berikutnya akan tetap batas waktu. 

  Jika Anda tidak dapat memperbaiki masalah dengan menggunakan dua mekanisme pertama, perlambat tingkat permintaan dengan mencoba opsi berikut.
  + Menghaluskan permintaan Anda sehingga semburan lalu lintas yang besar tidak membebani klien.
  + Lebih efisien dengan panggilan ke Layanan AWS.
  + Tingkatkan jumlah host yang mengirim permintaan.
+ **I/O Thread terlalu sibuk.** Ini hanya berlaku jika Anda menggunakan klien SDK asinkron dengan. [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/nio/netty/NettyNioAsyncHttpClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/nio/netty/NettyNioAsyncHttpClient.html) Jika `AvailableConcurrency` metriknya tidak rendah—menunjukkan bahwa koneksi tersedia di kolam—tetapi `ConcurrencyAcquireDuration` tinggi, itu mungkin karena I/O utas tidak dapat menangani permintaan. Pastikan Anda tidak lulus `Runnable:run` sebagai [pelaksana penyelesaian masa depan](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/client/config/SdkAdvancedAsyncClientOption.html#FUTURE_COMPLETION_EXECUTOR) dan melakukan tugas yang memakan waktu dalam rantai penyelesaian masa depan respons karena ini dapat memblokir I/O utas. Jika bukan itu masalahnya, pertimbangkan untuk menambah jumlah I/O utas dengan menggunakan `[eventLoopGroupBuilder](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/nio/netty/NettyNioAsyncHttpClient.Builder.html#eventLoopGroupBuilder(software.amazon.awssdk.http.nio.netty.SdkEventLoopGroup.Builder))` metode ini. Sebagai referensi, jumlah default thread I/O untuk sebuah `NettyNioAsyncHttpClient` instance adalah dua kali jumlah core CPU host.
+ **Latensi jabat tangan TLS tinggi.** Jika `AvailableConcurrency` metrik Anda mendekati 0 dan `LeasedConcurrency` lebih rendah dari`MaxConcurrency`, mungkin karena latensi jabat tangan TLS tinggi. Bagan berikut menunjukkan seperti apa metrik SDK untuk latensi jabat tangan TLS yang tinggi.  
![\[Tangkapan layar CloudWatch metrik yang mungkin menunjukkan latensi jabat tangan TLS yang tinggi.\]](http://docs.aws.amazon.com/id_id/sdk-for-java/latest/developer-guide/images/JavaDevGuide-high-tls-latency-chart.png)

  Untuk klien HTTP yang ditawarkan oleh Java SDK yang tidak didasarkan pada CRT, coba aktifkan [log TLS untuk memecahkan masalah TLS](security-java-tls.md). [Untuk klien HTTP AWS berbasis CRT, coba aktifkan AWS log CRT.](logging-slf4j.md#sdk-java-logging-verbose) Jika Anda melihat bahwa AWS titik akhir tampaknya membutuhkan waktu lama untuk melakukan jabat tangan TLS, Anda harus [menghubungi layanan yang terpengaruh](https://aws.amazon.com/contact-us/).

## Bagaimana cara memperbaiki`NoClassDefFoundError`, `NoSuchMethodError` atau`NoSuchFieldError`?
<a name="faq-classpath-errors"></a>

A `NoClassDefFoundError` menunjukkan bahwa kelas tidak dapat dimuat saat runtime. Dua penyebab paling umum untuk kesalahan ini adalah:
+ kelas tidak ada di classpath karena JAR hilang atau versi JAR yang salah ada di classpath.
+ kelas gagal memuat karena penginisialisasi statisnya memberikan pengecualian.

Demikian pula, `NoSuchMethodError` s dan `NoSuchFieldError` s biasanya dihasilkan dari versi JAR yang tidak cocok. Kami menyarankan Anda melakukan langkah-langkah berikut.

1. **Periksa dependensi Anda** untuk memastikan bahwa Anda menggunakan *versi yang sama dari semua stoples SDK*. Alasan paling umum bahwa kelas, metode, atau bidang tidak dapat ditemukan adalah ketika Anda meningkatkan ke versi klien baru tetapi Anda terus menggunakan versi ketergantungan SDK 'bersama' lama. Versi klien baru mungkin mencoba menggunakan kelas yang hanya ada di dependensi SDK 'bersama' yang lebih baru. Coba jalankan `mvn dependency:tree` atau `gradle dependencies` (untuk Gradle) untuk memverifikasi bahwa semua versi pustaka SDK cocok. Untuk menghindari masalah ini sepenuhnya di masa mendatang, sebaiknya gunakan [BOM (Bill of Materials)](setup-project-maven.md#sdk-as-dependency) untuk mengelola versi modul SDK.

   Contoh berikut menunjukkan contoh versi SDK campuran.

   ```
   [INFO] +- software.amazon.awssdk:dynamodb:jar:2.20.00:compile
   [INFO] |  +- software.amazon.awssdk:aws-core:jar:2.13.19:compile
   [INFO] +- software.amazon.awssdk:netty-nio-client:jar:2.20.00:compile
   ```

   Versi `dynamodb` adalah 2.20.00 dan versi 2.13.19`aws-core`. Versi `aws-core` artefak juga harus 2.20.00.

1. **Periksa pernyataan di awal log Anda** untuk melihat apakah kelas gagal dimuat karena kegagalan inisialisasi statis. Pertama kali kelas gagal memuat, mungkin ada pengecualian yang berbeda dan lebih berguna yang menentukan *mengapa* kelas tidak dapat dimuat. Pengecualian yang berpotensi berguna ini hanya terjadi sekali, jadi pernyataan log selanjutnya hanya akan melaporkan bahwa kelas tidak ditemukan.

1. **Periksa proses penyebaran Anda** untuk memastikan bahwa itu benar-benar menyebarkan file JAR yang diperlukan bersama dengan aplikasi Anda. Ada kemungkinan bahwa Anda sedang membangun dengan versi yang benar, tetapi proses yang membuat classpath untuk aplikasi Anda tidak termasuk dependensi yang diperlukan.

## Bagaimana cara memperbaiki kesalahan "`SignatureDoesNotMatch`" atau “Tanda tangan permintaan yang kami hitung tidak cocok dengan tanda tangan yang Anda berikan”?
<a name="faq-signature-does-not-match-error"></a>

`SignatureDoesNotMatch`Kesalahan menunjukkan bahwa tanda tangan yang dihasilkan oleh AWS SDK untuk Java dan tanda tangan yang dihasilkan oleh Layanan AWS tidak cocok. Item berikut menjelaskan penyebab potensial.
+ Pihak proxy atau perantara memodifikasi permintaan. Misalnya, proxy atau penyeimbang beban dapat mengubah header, path, atau string kueri yang ditandatangani oleh SDK.
+ Layanan dan SDK berbeda dalam cara mereka menyandikan permintaan ketika masing-masing menghasilkan string untuk ditandatangani.

Untuk men-debug masalah ini, sebaiknya [aktifkan logging debug untuk SDK](logging-slf4j.md#sdk-debug-level-logging). Cobalah untuk mereproduksi kesalahan dan temukan permintaan kanonik yang dihasilkan SDK. Di log, permintaan kanonik diberi label `AWS4 Canonical Request: ...` dan string yang akan ditandatangani diberi label. `AWS4 String to sign: ...` 

Jika Anda tidak dapat mengaktifkan debugging—misalnya, karena hanya dapat direproduksi dalam produksi—tambahkan logika ke aplikasi Anda yang mencatat informasi tentang permintaan saat terjadi kesalahan. Anda kemudian dapat menggunakan informasi tersebut untuk mencoba mereplikasi kesalahan di luar produksi dalam pengujian integrasi dengan logging debug diaktifkan.

Setelah Anda mengumpulkan permintaan kanonik dan string untuk ditandatangani, bandingkan dengan [spesifikasi AWS Signature Version 4](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-signing.html) untuk menentukan apakah ada masalah dalam cara SDK menghasilkan string untuk ditandatangani. Jika ada yang salah, Anda dapat membuat [laporan GitHub bug](https://github.com/aws/aws-sdk-java-v2/issues/new/choose) ke file AWS SDK untuk Java. 

Jika tidak ada yang salah, Anda dapat membandingkan string SDK untuk ditandatangani dengan string untuk menandatangani bahwa beberapa Layanan AWS kembali sebagai bagian dari respons kegagalan (Amazon S3, misalnya). Jika ini tidak tersedia, Anda harus [menghubungi layanan yang terpengaruh](https://aws.amazon.com/contact-us/) untuk melihat permintaan dan string kanonik apa yang akan ditandatangani yang dihasilkan untuk perbandingan. Perbandingan ini dapat membantu mengidentifikasi pihak perantara yang mungkin telah memodifikasi permintaan atau menyandikan perbedaan antara layanan dan klien.

Untuk informasi latar belakang selengkapnya tentang permintaan [penandatanganan, lihat Menandatangani permintaan AWS API](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-signing.html) di Panduan AWS Identity and Access Management Pengguna.

**Example dari permintaan kanonik**  

```
PUT
/Example-Bucket/Example-Object
partNumber=19&uploadId=string
amz-sdk-invocation-id:f8c2799d-367c-f024-e8fa-6ad6d0a1afb9
amz-sdk-request:attempt=1; max=4
content-encoding:aws-chunked
content-length:51
content-type:application/octet-stream
host:xxxxx
x-amz-content-sha256:STREAMING-UNSIGNED-PAYLOAD-TRAILER
x-amz-date:20240308T034733Z
x-amz-decoded-content-length:10
x-amz-sdk-checksum-algorithm:CRC32
x-amz-trailer:x-amz-checksum-crc32
```

**Example dari string untuk ditandatangani**  

```
AWS4-HMAC-SHA256
20240308T034435Z
20240308/us-east-1/s3/aws4_request
5f20a7604b1ef65dd89c333fd66736fdef9578d11a4f5d22d289597c387dc713
```

## Bagaimana cara memperbaiki kesalahan "`java.lang.IllegalStateException`: Connection pool shut down”?
<a name="faq-connection-pool-shutdown-exception"></a>

Kesalahan ini menunjukkan kumpulan koneksi HTTP Apache yang mendasarinya ditutup. Item berikut menjelaskan penyebab potensial.
+ **Klien SDK ditutup sebelum waktunya.**SDK hanya menutup kumpulan koneksi saat klien terkait ditutup. Pastikan untuk tidak menutup sumber daya saat sedang digunakan.
+ **A `java.lang.Error` dilemparkan.** Kesalahan seperti `OutOfMemoryError` menyebabkan kolam koneksi HTTP Apache [dimatikan.](https://github.com/apache/httpcomponents-client/blob/6a741b4f8f23e6c5c7cc42c36c2acabfac19c3d6/httpclient/src/main/java/org/apache/http/impl/execchain/MainClientExec.java#L368) Periksa log Anda untuk jejak tumpukan kesalahan. Juga tinjau kode Anda untuk tempat-tempat di mana ia menangkap `Throwable` s atau `Error` s tetapi menelan output yang mencegah kesalahan muncul ke permukaan. Jika kode Anda tidak melaporkan kesalahan, tulis ulang kode sehingga informasi dicatat. Informasi yang dicatat membantu menentukan akar penyebab kesalahan.
+ **Anda mencoba menggunakan penyedia kredensyal yang dikembalikan `DefaultCredentialsProvider#create()` setelah ditutup**. [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/auth/credentials/DefaultCredentialsProvider.html#create()](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/auth/credentials/DefaultCredentialsProvider.html#create())mengembalikan instance tunggal, jadi jika ditutup dan kode Anda memanggil `resolveCredentials` metode, pengecualian dilemparkan setelah kredensi cache (atau token) kedaluwarsa. 

  Periksa kode Anda untuk tempat-tempat di mana `DefaultCredentialsProvider` ditutup, seperti yang ditunjukkan pada contoh berikut.
  + Instance singleton ditutup dengan memanggil `DefaultCredentialsProvider#close().`

    ```
    DefaultCredentialsProvider defaultCredentialsProvider = DefaultCredentialsProvider.create(); // Singleton instance returned.
    AwsCredentials credentials = defaultCredentialsProvider.resolveCredentials();
    
    // Make calls to Layanan AWS.
    
    defaultCredentialsProvider.close();  // Explicit close.
    
    // Make calls to Layanan AWS.
    
    // After the credentials expire, either of the following calls eventually results in a "Connection pool shut down" exception.
    credentials = defaultCredentialsProvider.resolveCredentials();
    // Or
    credentials = DefaultCredentialsProvider.create().resolveCredentials();
    ```
  + Memanggil `DefaultCredentialsProvider#create()` dalam satu try-with-resources blok.

    ```
    try (DefaultCredentialsProvider defaultCredentialsProvider = DefaultCredentialsProvider.create()) {
        AwsCredentials credentials = defaultCredentialsProvider.resolveCredentials();
        
        // Make calls to Layanan AWS.
    
    } // After the try-with-resources block exits, the singleton DefaultCredentialsProvider is closed.
    
    // Make calls to Layanan AWS.
    
    DefaultCredentialsProvider defaultCredentialsProvider = DefaultCredentialsProvider.create(); // The closed singleton instance is returned.
    // If the credentials (or token) has expired, the following call results in the error.
    AwsCredentials credentials = defaultCredentialsProvider.resolveCredentials();
    ```

  Buat instance baru, non-singleton dengan memanggil `DefaultCredentialsProvider.builder().build()` jika kode Anda telah menutup instance tunggal dan Anda perlu menyelesaikan kredensialnya dengan menggunakan file. `DefaultCredentialsProvider`

## Bagaimana cara memperbaiki “Tidak dapat memuat kredensyal dari salah satu penyedia dalam rantai “? AwsCredentialsProviderChain
<a name="faq-credentials-provider-chain"></a>

Kesalahan ini menunjukkan bahwa tidak AWS SDK for Java 2.x dapat menemukan AWS kredensyal yang valid melalui salah satu penyedia kredensi dalam rantai penyedia kredensyal default. SDK secara otomatis mencari kredensyal dalam urutan tertentu, dan kesalahan ini terjadi ketika semua penyedia dalam rantai gagal memberikan kredensyal yang valid.

Pesan kesalahan lengkap biasanya terlihat seperti ini (akhiran baris dan indentasi ditambahkan untuk meningkatkan keterbacaan):

```
Unable to load credentials from any of the providers in the chain AwsCredentialsProviderChain(
    credentialsProviders=[
        SystemPropertyCredentialsProvider(),
        EnvironmentVariableCredentialsProvider(), 
        WebIdentityTokenCredentialsProvider(), 
        ProfileCredentialsProvider(profileName=default, profileFile=ProfileFile(sections=[])), 
        ContainerCredentialsProvider(), 
        InstanceProfileCredentialsProvider()
    ]) : [
        SystemPropertyCredentialsProvider(): Unable to load credentials from system settings.
        Access key must be specified either via environment variable (AWS_ACCESS_KEY_ID) 
        or system property (aws.accessKeyId)., 

        EnvironmentVariableCredentialsProvider(): Unable to load credentials from system settings. 
        Access key must be specified either via environment variable (AWS_ACCESS_KEY_ID) 
        or system property (aws.accessKeyId)., 

        WebIdentityTokenCredentialsProvider(): To use web identity tokens, the 'sts' service module 
        must be on the class path., 

        ProfileCredentialsProvider(profileName=default, profileFile=ProfileFile(sections=[])): 
        Profile file contained no credentials for profile 'default': ProfileFile(sections=[]), 

        ContainerCredentialsProvider(): Cannot fetch credentials from container - neither 
        AWS_CONTAINER_CREDENTIALS_FULL_URI or AWS_CONTAINER_CREDENTIALS_RELATIVE_URI environment 
        variables are set., 

        InstanceProfileCredentialsProvider(): Failed to load credentials from IMDS.]
```

### Penyebab dan solusi umum
<a name="faq-cred-provider-chain-common-causes-and-solutions"></a>

#### Tinjau konfigurasi kredensyal Anda
<a name="faq-cred-provider-chain-check-config"></a>

Saat Anda menggunakan penyedia kredensyal default (dengan menelepon `ServiceClient.create()` tanpa mengonfigurasi kredensyal secara eksplisit), SDK akan mencari kredensyal dalam urutan tertentu. Tinjau [cara kerja rantai penyedia kredensyal default](credentials-chain.md) untuk memahami sumber kredensyal mana yang diperiksa SDK dan dalam urutan apa.

Pastikan bahwa metode konfigurasi kredensyal yang ingin Anda gunakan diatur dengan benar di lingkungan Anda:

##### Untuk instans Amazon EC2
<a name="faq-cred-check-ec2"></a>
+ **Periksa peran IAM:** Verifikasi bahwa peran IAM dilampirkan ke instance Anda.
+ Kegagalan **IMDS intermiten: Jika Anda mengalami kegagalan** intermiten (biasanya berlangsung beberapa ratus milidetik), ini biasanya menunjukkan masalah jaringan sementara yang mencapai Layanan Metadata Instans (IMDS).

  Solusi:
  + Aktifkan [pencatatan debug](logging-slf4j.md#sdk-debug-level-logging) untuk menganalisis waktu dan frekuensi kegagalan
  + Pertimbangkan untuk menerapkan logika coba lagi dalam aplikasi Anda untuk kegagalan terkait kredensyal
  + Periksa masalah konektivitas jaringan antara instans Anda dan titik akhir IMDS

##### Untuk lingkungan kontainer
<a name="faq-cred-check-container-env"></a>

Konfirmasikan bahwa peran tugas (Amazon ECS) atau akun layanan (Amazon EKS) dikonfigurasi dan variabel lingkungan yang diperlukan disetel.

##### Untuk pengembangan lokal
<a name="faq-cred-check-local-dev"></a>

Periksa apakah variabel lingkungan, file kredensyal, atau konfigurasi Pusat Identitas IAM sudah ada.

##### Untuk federasi identitas web
<a name="faq-cred-check-web-id-federation"></a>
+ **Verifikasi konfigurasi:** Verifikasi bahwa file token identitas web ada dan variabel lingkungan yang diperlukan dikonfigurasi.
+ **Ketergantungan modul STS yang hilang:** Jika Anda melihat kesalahan`To use web identity tokens, the 'sts' service module must be on the class path`, Anda perlu menambahkan modul STS sebagai ketergantungan. Ini biasa terjadi saat menggunakan Amazon EKS Pod Identity atau otentikasi token identitas web lainnya.

  Solusi: Tambahkan modul STS ke dependensi proyek Anda:
  + 

    ```
    <dependency>
        <groupId>software.amazon.awssdk</groupId>
        <artifactId>sts</artifactId>
    </dependency>
    ```

    Untuk beberapa layanan, Anda mungkin juga memerlukan `aws-query-protocol` ketergantungan:

    ```
    <dependency>
        <groupId>software.amazon.awssdk</groupId>
        <artifactId>aws-query-protocol</artifactId>
    </dependency>
    ```

#### Masalah konektivitas jaringan atau proxy
<a name="faq-credentials-provider-chain-network-issues"></a>

Jika Anda melihat `Connection refused` kesalahan dalam rantai penyedia kredensyal, ini biasanya menunjukkan masalah konektivitas jaringan saat SDK mencoba mencapai AWS titik akhir.

**Solusi:**
+ Verifikasi konfigurasi proxy jika Anda menggunakan server proxy
+ Periksa apakah jaringan Anda mengizinkan koneksi HTTPS keluar ke titik akhir AWS 
+ Aktifkan [pencatatan debug](logging-slf4j.md#sdk-debug-level-logging) untuk melihat upaya koneksi terperinci
+ Uji konektivitas menggunakan alat seperti `curl` memverifikasi akses jaringan ke titik AWS akhir

# Kurangi waktu startup SDK untuk AWS Lambda
<a name="lambda-optimize-starttime"></a>

Salah satu tujuannya AWS SDK for Java 2.x adalah untuk mengurangi latensi startup untuk AWS Lambda fungsi. SDK berisi perubahan yang mengurangi waktu startup, yang dibahas di akhir topik ini.

Pertama, topik ini berfokus pada perubahan yang dapat Anda lakukan untuk mengurangi waktu mulai dingin. Ini termasuk membuat perubahan dalam struktur kode Anda dan dalam konfigurasi klien layanan.

## Gunakan klien HTTP AWS berbasis CRT
<a name="lambda-quick-url"></a>

Untuk bekerja dengan AWS Lambda, kami merekomendasikan skenario [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/crt/AwsCrtHttpClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/crt/AwsCrtHttpClient.html)untuk sinkron dan [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/crt/AwsCrtAsyncHttpClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/crt/AwsCrtAsyncHttpClient.html)untuk skenario asinkron.

[Konfigurasikan AWS klien HTTP berbasis CRT](http-configuration-crt.md)Topik dalam panduan ini menjelaskan manfaat menggunakan klien HTTP, cara menambahkan ketergantungan, dan cara mengonfigurasi penggunaannya oleh klien layanan. 

## Hapus dependensi klien HTTP yang tidak digunakan
<a name="lambda-quick-remove-deps"></a>

Seiring dengan penggunaan eksplisit klien AWS berbasis CRT, Anda dapat menghapus klien HTTP lain yang dibawa SDK secara default. Waktu startup Lambda berkurang ketika lebih sedikit pustaka yang perlu dimuat, jadi Anda harus menghapus artefak yang tidak terpakai yang perlu dimuat JVM.

Cuplikan berikut dari `pom.xml` file Maven menunjukkan pengecualian klien HTTP berbasis Apache dan klien HTTP berbasis Netty. (Klien ini tidak diperlukan saat Anda menggunakan klien AWS berbasis CRT.) Contoh ini mengecualikan artefak klien HTTP dari ketergantungan klien S3 dan menambahkan `aws-crt-client` artefak untuk memungkinkan akses ke klien HTTP berbasis CRT. AWS 

```
<project>
    <properties>
        <aws.java.sdk.version>2.27.21</aws.java.sdk.version>
    <properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>software.amazon.awssdk</groupId>
                <artifactId>bom</artifactId>
                <version>${aws.java.sdk.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>aws-crt-client</artifactId>
        </dependency>
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>s3</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>software.amazon.awssdk</groupId>
                    <artifactId>netty-nio-client</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>software.amazon.awssdk</groupId>
                    <artifactId>apache-client</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
</project>
```

**catatan**  
Tambahkan `<exclusions>` elemen ke semua dependensi klien layanan di file Anda`pom.xml`.

## Konfigurasikan klien layanan untuk memintas pencarian
<a name="lambda-quick-clients"></a>

**Tentukan wilayah**  
Saat Anda membuat klien layanan, panggil `region` metode pada pembuat klien layanan. Ini memintas [proses pencarian Wilayah](region-selection.md#default-region-provider-chain) default SDK yang memeriksa beberapa tempat untuk informasi. Wilayah AWS   
Untuk menjaga kode Lambda independen dari wilayah, gunakan kode berikut di dalam metode. `region` Kode ini mengakses variabel `AWS_REGION` lingkungan yang ditetapkan oleh wadah Lambda.  

```
Region.of(System.getenv(SdkSystemSetting.AWS_REGION.environmentVariable()))
```

**Gunakan `EnvironmentVariableCredentialProvider`**  
Sama seperti perilaku pencarian default untuk informasi Wilayah, SDK mencari kredensional di beberapa tempat. Dengan menentukan [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/auth/credentials/EnvironmentVariableCredentialsProvider.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/auth/credentials/EnvironmentVariableCredentialsProvider.html)kapan Anda membangun klien layanan, Anda menghemat waktu dalam proses pencarian SDK untuk kredensi.  
Menggunakan penyedia kredensi ini memungkinkan kode untuk digunakan dalam Lambda fungsi, tetapi mungkin tidak berfungsi pada Amazon EC2 atau sistem lain.  
Jika Anda berniat menggunakan [Lambda SnapStart untuk Java](#lambda-quick-snapstart) di beberapa titik, Anda harus mengandalkan rantai penyedia kredensi default untuk mencari kredensil. Jika Anda menentukan`EnvironmentVariableCredentialsProvider`, pencarian kredensial awal berfungsi, tetapi ketika SnapStart diaktifkan, [runtime Java menetapkan variabel lingkungan kredensi kontainer](https://docs.aws.amazon.com/lambda/latest/dg/snapstart-activate.html#snapstart-credentials). Pada aktivasi, variabel lingkungan yang digunakan oleh variabel lingkungan kunci `EnvironmentVariableCredentialsProvider` akses — tidak tersedia untuk Java SDK.

Cuplikan kode berikut menunjukkan klien layanan S3 yang dikonfigurasi dengan tepat untuk digunakan di lingkungan Lambda.

```
S3Client s3Client = S3Client.builder()
    .region(Region.of(System.getenv(SdkSystemSetting.AWS_REGION.environmentVariable())))
    .credentialsProvider(EnvironmentVariableCredentialsProvider.create())
    .httpClient(AwsCrtHttpClient.builder().build())
    .build();
```

## Inisialisasi klien SDK di luar penangan fungsi Lambda
<a name="lambda-quick-initialize"></a>

Sebaiknya inisialisasi klien SDK di luar metode penangan Lambda. Dengan cara ini, jika konteks eksekusi digunakan kembali, inisialisasi klien layanan dapat dilewati. Dengan menggunakan kembali instance klien dan koneksinya, pemanggilan berikutnya dari metode handler terjadi lebih cepat.

Dalam contoh berikut, `S3Client` instance diinisialisasi dalam konstruktor menggunakan metode pabrik statis. Jika wadah yang dikelola oleh lingkungan Lambda digunakan kembali, instance yang diinisialisasi `S3Client` akan digunakan kembali.

```
public class App implements RequestHandler<Object, Object> {
    private final S3Client s3Client;

    public App() {
        s3Client = DependencyFactory.s3Client();
    }

    @Override
    public Object handle Request(final Object input, final Context context) {
         ListBucketResponse response = s3Client.listBuckets();
         // Process the response.
    }
}
```

## Minimalkan injeksi ketergantungan
<a name="lambda-quick-di"></a>

Kerangka kerja injeksi ketergantungan (DI) mungkin membutuhkan waktu tambahan untuk menyelesaikan proses penyiapan. Mereka mungkin juga memerlukan dependensi tambahan, yang membutuhkan waktu untuk memuat.

Jika kerangka kerja DI diperlukan, kami sarankan menggunakan kerangka kerja DI ringan seperti [Dagger](https://dagger.dev/dev-guide/).

## Gunakan penargetan Maven Archetype AWS Lambda
<a name="lambda-quick-maven"></a>

Tim AWS Java SDK telah mengembangkan [template Maven Archetype](https://github.com/aws/aws-sdk-java-v2/tree/master/archetypes/archetype-lambda) untuk mem-bootstrap proyek Lambda dengan waktu startup minimal. Anda dapat membangun proyek Maven dari pola dasar dan mengetahui bahwa dependensi dikonfigurasi sesuai untuk lingkungan Lambda. 

[Untuk mempelajari lebih lanjut tentang arketipe dan bekerja melalui contoh penyebaran, lihat posting blog ini.](https://aws.amazon.com/blogs/developer/bootstrapping-a-java-lambda-application-with-minimal-aws-java-sdk-startup-time-using-maven/)

## Pertimbangkan Lambda SnapStart untuk Java
<a name="lambda-quick-snapstart"></a>

Jika persyaratan runtime Anda kompatibel, AWS tawarkan [ SnapStart Lambda](https://docs.aws.amazon.com/lambda/latest/dg/snapstart.html) untuk Java. Lambda SnapStart adalah solusi berbasis infrastruktur yang meningkatkan kinerja startup untuk fungsi Java. Saat Anda mempublikasikan versi baru suatu fungsi, Lambda SnapStart menginisialisasinya dan mengambil snapshot memori dan status disk yang tidak dapat diubah dan terenkripsi. SnapStart kemudian menyimpan snapshot untuk digunakan kembali.

## Perubahan versi 2.x yang memengaruhi waktu startup
<a name="example-client-configuration"></a>

Selain perubahan yang Anda buat pada kode Anda, SDK for Java versi 2.x mencakup tiga perubahan utama yang mengurangi waktu startup:
+ Penggunaan [jackson-jr](https://github.com/FasterXML/jackson-jr), yang merupakan pustaka serialisasi yang meningkatkan waktu inisialisasi
+ Penggunaan pustaka [java.time](https://docs.oracle.com/javase/8/docs/api/index.html?java/time.html) untuk objek tanggal dan waktu, yang merupakan bagian dari JDK
+ Penggunaan [SLF4j untuk fasad penebangan](https://www.slf4j.org/)

## Sumber daya tambahan
<a name="lambda-quick-resources"></a>

Panduan AWS Lambda Pengembang berisi [bagian tentang praktik terbaik](https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html) untuk mengembangkan fungsi Lambda yang tidak spesifik untuk Java.

Untuk contoh membangun aplikasi cloud-native di Java yang menggunakan AWS Lambda, lihat konten [lokakarya](https://github.com/aws-samples/aws-lambda-java-workshop) ini. Optimalisasi kinerja diskusi lokakarya dan praktik terbaik lainnya.

Anda dapat mempertimbangkan untuk menggunakan gambar statis yang dikompilasi sebelumnya untuk mengurangi latensi startup. Misalnya, Anda dapat menggunakan SDK for Java 2.x dan Maven untuk [membuat](setup-project-graalvm.md) gambar asli GraalVM.

# Implementasikan `ContentStreamProvider` di AWS SDK for Java 2.x
<a name="content-stream-provider"></a>

`ContentStreamProvider`adalah abstraksi yang digunakan AWS SDK for Java 2.x untuk memungkinkan beberapa pembacaan data input. Topik ini menjelaskan cara menerapkan dengan `ContentStreamProvider` benar untuk aplikasi Anda.

SDK for Java 2.x menggunakan `ContentStreamProvider#newStream()` metode ini setiap kali perlu membaca seluruh aliran. Agar ini berfungsi untuk seluruh aliran, aliran yang dikembalikan harus selalu berada di awal konten dan harus berisi data yang sama. 

Pada bagian berikut, kami menyediakan tiga pendekatan untuk bagaimana menerapkan perilaku ini dengan benar.

## Gunakan `mark()` dan `reset()`
<a name="csp-impl-mark-reset"></a>

Pada contoh di bawah ini, kita gunakan `mark(int)` dalam konstruktor sebelum membaca mulai untuk memastikan bahwa kita dapat mengatur ulang aliran kembali ke awal. Untuk setiap pemanggilan `newStream()` kami mengatur ulang aliran:

```
public class MyContentStreamProvider implements ContentStreamProvider {  
    private InputStream contentStream;  
  
    public MyContentStreamProvider(InputStream contentStream) {  
        this.contentStream = contentStream;  
        this.contentStream.mark(MAX_LEN);  
    }  
  
    @Override  
    public InputStream newStream() {  
        contentStream.reset();  
        return contentStream;  
    }  
}
```

## Gunakan buffering jika `mark()` dan tidak `reset()` tersedia
<a name="csp-impl-unsupported-streams"></a>

 Jika streaming Anda tidak mendukung `mark()` dan `reset()` secara langsung, Anda masih dapat menggunakan solusi yang ditunjukkan sebelumnya dengan terlebih dahulu membungkus aliran dalam`BufferedInputStream`:

```
public class MyContentStreamProvider implements ContentStreamProvider {  
    private BufferedReader contentStream;  
  
    public MyContentStreamProvider(InputStream contentStream) {  
        this.contentStream = new BufferedInputStream(contentStream);  
        this.contentStream.mark(MAX_LEN);
    }  
  
    @Override  
    public InputStream newStream() {  
        contentStream.reset();  
        return contentStream;  
    }  
}
```

## Buat aliran baru
<a name="csp-impl-new-stream"></a>

Pendekatan yang lebih sederhana adalah dengan hanya mendapatkan aliran baru ke data Anda pada setiap pemanggilan dan menutup yang sebelumnya:

```
public class MyContentStreamProvider implements ContentStreamProvider {  
    private InputStream contentStream;  
  
    @Override  
    public InputStream newStream() {  
        if (contentStream != null) {  
            contentStream.close();  
        }  
        contentStream = openStream();  
        return contentStream;  
    }  
}
```

# Mengatur JVM TTL untuk pencarian nama DNS
<a name="jvm-ttl-dns"></a>

Mesin virtual Java (JVM) menyimpan cache pencarian nama DNS. Ketika JVM menyelesaikan nama host ke alamat IP, itu menyimpan alamat IP untuk jangka waktu tertentu, yang dikenal sebagai (TTL). *time-to-live*

Karena AWS sumber daya menggunakan entri nama DNS yang terkadang berubah, kami sarankan Anda mengonfigurasi JVM Anda dengan nilai TTL 5 detik. Ini memastikan bahwa ketika alamat IP sumber daya berubah, aplikasi Anda akan dapat menerima dan menggunakan alamat IP baru sumber daya dengan meminta DNS.

Pada beberapa konfigurasi Java, TTL default JVM diatur sehingga *tidak akan pernah* menyegarkan entri DNS sampai JVM dimulai ulang. Jadi, jika alamat IP untuk AWS sumber daya berubah saat aplikasi Anda masih berjalan, itu tidak akan dapat menggunakan sumber daya itu sampai Anda *secara manual me-restart* JVM dan informasi IP cache di-refresh. Dalam hal ini, sangat penting untuk mengatur TTL JVM sehingga secara berkala akan menyegarkan informasi IP cache.

## Cara mengatur JVM TTL
<a name="how-to-set-the-jvm-ttl"></a>

Untuk memodifikasi TTL JVM, atur nilai properti keamanan [networkaddress.cache.ttl](https://docs.oracle.com/en/java/javase/17/core/java-networking.html#GUID-A680DADB-C4C1-40F1-B568-D9A97C917F5D). Perhatikan bahwa `networkaddress.cache.ttl` adalah *properti keamanan*, bukan properti sistem, yaitu, tidak dapat diatur dengan flag `-D` baris perintah.

### Opsi 1: Atur secara terprogram di aplikasi Anda
<a name="set-ttl-programmatically"></a>

Panggilan di [https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/security/Security.html](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/security/Security.html)awal startup aplikasi Anda, sebelum klien AWS SDK dibuat dan sebelum permintaan jaringan dibuat:

```
import java.security.Security;

public class MyApplication {
    public static void main(String[] args) {
        Security.setProperty("networkaddress.cache.ttl", "5");

        // ... create SDK clients and run application
    }
}
```

### Opsi 2: Atur di file java.security
<a name="set-ttl-java-security-file"></a>

Mengatur `networkaddress.cache.ttl` properti dalam `$JAVA_HOME/jre/lib/security/java.security` file untuk Java 8 atau `$JAVA_HOME/conf/security/java.security` file untuk Java 11 atau lebih tinggi.

Berikut ini adalah cuplikan dari `java.security` file yang menunjukkan cache TTL diatur ke 5 detik.

```
#
# The Java-level namelookup cache policy for successful lookups:
#
# any negative value: caching forever
# any positive value: the number of seconds to cache an address for
# zero: do not cache
#
...
networkaddress.cache.ttl=5
...
```

Semua aplikasi yang berjalan pada JVM diwakili oleh variabel `$JAVA_HOME` lingkungan menggunakan pengaturan ini.

### Opsi 3: Gunakan fallback properti sistem JDK (baris perintah)
<a name="set-ttl-system-property"></a>

Jika Anda tidak dapat mengubah konfigurasi atau kode keamanan, Anda dapat menggunakan properti sistem JDK. Ini bertindak sebagai fallback jika tidak ada properti keamanan yang didefinisikan.
+ `sun.net.inetaddr.ttl`— Mengontrol pencarian yang berhasil (TTL positif)
+ `sun.net.inetaddr.negative.ttl`— Kontrol pencarian gagal (TTL negatif)

```
java -Dsun.net.inetaddr.ttl=5 -Dsun.net.inetaddr.negative.ttl=1 -jar myapp.jar
```

**catatan**  
Ini adalah properti JDK-internal yang didokumentasikan dalam referensi [Oracle Java 8 Networking Properties](https://docs.oracle.com/javase/8/docs/technotes/guides/net/properties.html) sebagai properti pribadi yang “mungkin tidak didukung dalam rilis masa depan”. Gunakan Opsi 1-2 jika memungkinkan.

# Bekerja dengan HTTP/2 di AWS SDK untuk Java
<a name="http2"></a>

HTTP/2 adalah revisi besar dari protokol HTTP. Versi baru ini memiliki beberapa peningkatan untuk meningkatkan kinerja:
+ Pengkodean data biner memberikan transfer data yang lebih efisien.
+ Kompresi header mengurangi byte overhead yang diunduh oleh klien, membantu mendapatkan konten ke klien lebih cepat. Ini sangat berguna untuk klien seluler yang sudah dibatasi bandwidth.
+ Komunikasi asinkron dua arah (multiplexing) memungkinkan beberapa permintaan dan pesan respons antara klien dan AWS berada dalam penerbangan pada saat yang sama melalui satu koneksi, bukan melalui beberapa koneksi, yang meningkatkan kinerja.

Pengembang yang memutakhirkan ke yang terbaru SDKs akan secara otomatis menggunakan HTTP/2 ketika didukung oleh layanan yang mereka kerjakan. Antarmuka pemrograman baru dengan mulus memanfaatkan fitur HTTP/2 dan menyediakan cara baru untuk membangun aplikasi.

Fitur AWS SDK untuk Java 2.x baru APIs untuk streaming acara yang mengimplementasikan protokol HTTP/2. Untuk contoh cara menggunakan yang baru ini APIs, lihat [Bekerja dengan Kinesis](examples-kinesis.md).