Search code examples
javaamazon-web-servicesmavenaws-java-sdk-2.x

Cannot find symbol class ResponseHeaderOverrides location: package software.amazon.awssdk.services.s3.model Java SDK v2 AWS


I am a beginner to Java programming.

I am trying to do a GET on a object in S3 using the AWS Java SDK v2. The code is staightforward hello world code that I have from a video tutorial.

    //get object 
    public static void getObject(S3Client s3Client, String bucketName, String key) {
        System.out.println("Checking if bucket exists. Bucket Name: " + bucketName);
        System.out.printf("%n");
        try {
             ResponseHeaderOverrides headerOverrides = new ResponseHeaderOverrides()
                .withCacheControl("No-cache")
                .withContentDisposition("attachment; filename=key.txt"); 
            GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, key)
                .withResponseHeaders(headerOverrides);

        headerOverrideObject = s3Client.getObject(getObjectRequest);
        displayTextInputStream(headerOverrideObject.getObjectContent());
        } catch (S3Exception e) {
        System.err.println(e.awsErrorDetails().errorMessage());
        }        
    }

I have errors related to ResponseHeaderOverrides class.

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.6.1:compile (default-compile) on project getstarted: Compilation failure: Compilation failure: [ERROR] /home/ec2-user/environment/aai_demos/java/getstarted/src/main/java/org/example/Handler.java:[15,48] cannot find symbol

Line 15 is

import software.amazon.awssdk.services.s3.model.ResponseHeaderOverrides;

[ERROR] symbol: class ResponseHeaderOverrides [ERROR] location: package software.amazon.awssdk.services.s3.model [ERROR] /home/ec2-user/environment/aai_demos/java/getstarted/src/main/java/org/example/Handler.java:[153,14] cannot find symbol

Line 153 is:

ResponseHeaderOverrides headerOverrides = new ResponseHeaderOverrides()
                .withCacheControl("No-cache")
                .withContentDisposition("attachment; filename=key.txt"); 

My pom.xml looks like this. I did not write this - this was generated by maven.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>getstarted</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.shade.plugin.version>3.2.1</maven.shade.plugin.version>
        <maven.compiler.plugin.version>3.6.1</maven.compiler.plugin.version>
        <exec-maven-plugin.version>1.6.0</exec-maven-plugin.version>
        <aws.java.sdk.version>2.20.43</aws.java.sdk.version>
        <slf4j.version>1.7.28</slf4j.version>
        <junit5.version>5.8.1</junit5.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>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>

        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>sso</artifactId>
        </dependency>

        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>ssooidc</artifactId>
        </dependency>

        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>apache-client</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>commons-logging</groupId>
                    <artifactId>commons-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>${slf4j.version}</version>
        </dependency>

        <!-- Needed to adapt Apache Commons Logging used by Apache HTTP Client to Slf4j to avoid
        ClassNotFoundException: org.apache.commons.logging.impl.LogFactoryImpl during runtime -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>${slf4j.version}</version>
        </dependency>

        <!-- Test Dependencies -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>${junit5.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven.compiler.plugin.version}</version>
            </plugin>
        </plugins>
    </build>

</project>

Solution

  • I recommend that when you want to work with AWS SDK for Java V2, refer to the Official AWS Code Library.

    The above code is not vaid either. V2 does not use the new operator:

    new GetObjectRequest
    

    Only V1 uses the new operator.

    Assume, you want to get a byte[] that represents an object from an S3 bucket. For example, you have a PDF in a bucket and want to save it to a local folder. This code can be used:

    import software.amazon.awssdk.core.ResponseBytes;
    import software.amazon.awssdk.regions.Region;
    import software.amazon.awssdk.services.s3.S3Client;
    import software.amazon.awssdk.services.s3.model.GetObjectRequest;
    import software.amazon.awssdk.services.s3.model.S3Exception;
    import software.amazon.awssdk.services.s3.model.GetObjectResponse;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    // snippet-end:[s3.java2.getobjectdata.import]
    
    /**
     * Before running this Java V2 code example, set up your development
     * environment, including your credentials.
     *
     * For more information, see the following documentation topic:
     *
     * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
     */
    
    public class GetObjectData {
        public static void main(String[] args) {
            final String usage = """
    
                    Usage:
                        <bucketName> <keyName> <path>
    
                    Where:
                        bucketName - The Amazon S3 bucket name.\s
                        keyName - The key name.\s
                        path - The path where the file is written to.\s
                    """;
    
            if (args.length != 3) {
                System.out.println(usage);
                System.exit(1);
            }
    
            String bucketName = args[0];
            String keyName = args[1];
            String path = args[2];
            Region region = Region.US_EAST_1;
            S3Client s3 = S3Client.builder()
                    .region(region)
                    .build();
    
            getObjectBytes(s3, bucketName, keyName, path);
        }
    
        public static void getObjectBytes(S3Client s3, String bucketName, String keyName, String path) {
            try {
                GetObjectRequest objectRequest = GetObjectRequest
                        .builder()
                        .key(keyName)
                        .bucket(bucketName)
                        .build();
    
                ResponseBytes<GetObjectResponse> objectBytes = s3.getObjectAsBytes(objectRequest);
                byte[] data = objectBytes.asByteArray();
    
                // Write the data to a local file.
                File myFile = new File(path);
                OutputStream os = new FileOutputStream(myFile);
                os.write(data);
                System.out.println("Successfully obtained bytes from an S3 object");
                os.close();
    
            } catch (IOException ex) {
                ex.printStackTrace();
            } catch (S3Exception e) {
                System.err.println(e.awsErrorDetails().errorMessage());
                System.exit(1);
            }
        }
    } 
    

    You will find the POM and other S3 Java V2 examples in AWS Github here:

    https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2/example_code/s3

    As you are new to AWS SDK for Java V2, start with this Hello S3 example:

    Hello Amazon S3

    enter image description here