Skip to content

Java code example standards

Scott Macdonald edited this page Jul 23, 2024 · 28 revisions

Java Code Examples Standards

This document summarizes important points for writing and reviewing code examples written for the AWS SDK for Java V2. For more information on tools and standards, see the complete list in TCX Code Examples Standards.

General Structure

Service folders with examples should follow the common structure that uses folders for Actions, Scenarios, and Tests, with a top level POM file.

For most scenarios, code examples should use the Java Async client. This demonstrates how to perform asynchronous service calls. Error handing is done within the CompletableFuture block.

public String createECRRepository(String repoName) {
        if (repoName == null || repoName.isEmpty()) {
            throw new IllegalArgumentException("Repository name cannot be null or empty");
        }

        CreateRepositoryRequest request = CreateRepositoryRequest.builder()
            .repositoryName(repoName)
            .build();

        // Execute the request asynchronously.
        CompletableFuture<CreateRepositoryResponse> response = getAsyncClient().createRepository(request);

        // Use whenComplete to handle the response.
        response.whenComplete((createRepositoryResponse, ex) -> {
            if (createRepositoryResponse != null) {
                System.out.println("Repository created successfully. ARN: " + createRepositoryResponse.repository().repositoryArn());
            } else {
                if (ex.getCause() instanceof EcrException) {
                    EcrException e = (EcrException) ex.getCause();
                    System.err.println("Error creating ECR repository: " + e.awsErrorDetails().errorMessage());
                } else {
                    System.err.println("Unexpected error occurred: " + ex.getMessage());
                }
            }
        });

        // Wait for the CompletableFuture to complete and return the result.
        CreateRepositoryResponse result = response.join();
        if (result != null) {
            return result.repository().repositoryArn();
        } else {
            throw new RuntimeException("Unexpected response type");
        }
    }

Examples should use JDK 17+ and use a Java Text blocks for large amount of text. Single sentences can still use System.out.println().

System.out.println("""
            The Amazon Elastic Container Registry (ECR) is a fully-managed Docker container registry 
            service provided by AWS. It allows developers and organizations to securely 
            store, manage, and deploy Docker container images. 
            ECR provides a simple and scalable way to manage container images throughout their lifecycle, 
            from building and testing to production deployment.\s
                        
            The `EcrAsyncClient` interface in the AWS SDK provides a set of methods to 
            programmatically interact with the Amazon ECR service. This allows developers to 
            automate the storage, retrieval, and management of container images as part of their application 
            deployment pipelines. With ECR, teams can focus on building and deploying their 
            applications without having to worry about the underlying infrastructure required to 
            host and manage a container registry.
            
           This scenario walks you through how to perform key operations for this service.  
           Let's get started...
          """);

Java methods should provide JavaDoc details that provides a summary, parameters, exceptions, and return type below the snippet tag.

// snippet-start:[ecr.java2.create.repo.main]
/**
 * Creates an Amazon Elastic Container Registry (Amazon ECR) repository.
 *
 * @param repoName the name of the repository to create
 * @return the Amazon Resource Name (ARN) of the created repository, or an empty string if the operation failed
 * @throws IllegalArgumentException if the repository name is null or empty
 * @throws RuntimeException         if an error occurs while creating the repository
 */
public String createECRRepository(String repoName) {

Java Single Actions/Hello Service examples can use Sync clients and where available, use Paginator method calls.

public static void listImageTags( EcrClient ecrClient, String repoName){
        ListImagesRequest listImagesPaginator = ListImagesRequest.builder()
            .repositoryName(repoName)
            .build();

       try {
           ListImagesIterable imagesIterable = ecrClient.listImagesPaginator(listImagesPaginator);
           imagesIterable.stream()
               .flatMap(r -> r.imageIds().stream())
               .forEach(image -> System.out.println("The docker image tag is: " +image.imageTag()));

       } catch (EcrException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
        } finally {
            ecrClient.close();
        }
    }

When a service is added or updated, update the Java V2 Github repo so it will be included in the build/lint/format and Weathertop tests.

New scenarios should have two classes. One class that uses main() controls the flow of the program. The other class, which is the Action class contains SDK method calls that uses the Async Java client.

You can create Request objects separately for service method calls. You can also use lambda expressions if you feel that makes sense for the example.

Use parameterized values for any AWS database query operations. (See the Redshift scenario as an example).

Import statements should not include any unused imports, wildcards, and be ordered alphabetically.

All Java code examples should be lintered using Checkstyle.

Java tests must use @TestInstance and @TestMethodOrder JUNT annotations.

@TestInstance(TestInstance.Lifecycle.PER_METHOD)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class AWSPolly

Integration tests should be marked with @Tag("IntegrationTest"). Also, use @Order(1) for ordering tests.

    @Test
    @Tag("IntegrationTest")
    @Order(1)
    public void describeVoicesSample() {
        assertDoesNotThrow(() ->DescribeVoicesSample.describeVoice(polly));
        System.out.println("describeVoicesSample test passed");
    }

Use Maven/POM for dependency management.

Recommend keeping dependencies up-to-date and following best practices for dependency management. That is, every 3-4 months - update the Java SDK build.

Metadata for Action examples should contain at minimum the following snippets.

  • A snippet to show the action itself within context.
  • If more than one variation of the Action is included, use descriptions in the metadata to explain the differences.

Metadata for scenario examples should contain the Action class and Scenario that contains the main() that contains the output of the program.

Clone this wiki locally