4
votes

I'm trying to get a file from an S3 bucket as part of the Setup Thread Group for a JMeter test, and I have the following Groovy script in a JSR223 Sampler:

import java.io.IOException
import java.io.InputStream
import java.util.Properties

import com.amazonaws.services.s3.AmazonS3
import com.amazonaws.services.s3.AmazonS3ClientBuilder
import com.amazonaws.services.s3.model.GetObjectRequest
import com.amazonaws.services.s3.model.S3Object
import com.amazonaws.auth.BasicAWSCredentials
import com.amazonaws.auth.AWSStaticCredentialsProvider
import com.amazonaws.services.s3.S3CredentialsProviderChain

def awsAccessKey = "my_key"
def awsSecretAccessKey = "my_secret_key"
System.setProperty("aws.accessKeyId", awsAccessKey)
System.setProperty("aws.secretKey", awsSecretAccessKey)

def awsCreds = new BasicAWSCredentials(awsAccessKey, awsSecretAccessKey)
def s3Client = AmazonS3ClientBuilder.standard()
                .withRegion("us-west-2")
                .build()
def s3Object = s3Client.getObject(new GetObjectRequest("bucket-name", "filename"))
def is = s3Object.getObjectContent()

The code throws the following, both when I use .withCredentials(awsCreds) and when I set the system properties:

java.lang.NoClassDefFoundError: Could not initialize class com.amazonaws.services.s3.S3CredentialsProviderChain

I've also converted the same code to the following Beanshell Sampler:

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.auth.BasicAWSCredentials;

String awsAccessKey = "my_key";
String awsSecretAccessKey = "my_secret_key";
System.setProperty("aws.accessKeyId", awsAccessKey);
System.setProperty("aws.secretKey", awsSecretAccessKey);

BasicAWSCredentials awsCreds = new BasicAWSCredentials(awsAccessKey, awsSecretAccessKey);
AmazonS3 s3Client = AmazonS3ClientBuilder.standard().withRegion("us-west-2").build();
S3Object s3Object = s3Client.getObject(new GetObjectRequest("bucket-name", "filename"));
InputStream is = s3Object.getObjectContent();

However, this results in the following:

org.apache.jorphan.util.JMeterException: Error invoking bsh method: eval    
Sourced file: inline evaluation of: ``import java.io.IOException; import java.io.InputStream; import java.util.Propert . . . '' : Typed variable declaration : Method Invocation AmazonS3ClientBuilder.standard

When I put this same code into a test Java class, it runs with no issues. I have aws-java-sdk-1.11.160.jar and aws-java-sdk-core-1.11.160.jar in my jmeter/lib, so I don't believe it's a missing dependency. Am I missing something else?

4
are you certain the aws-java-sdk jar covers S3CredentialsProviderChain? Feels like you'll need some sort of s3 jar as well.RaGe
So the aws-java-sdk covers everything, and then if the develop doesn't want load all of it they can use a more specific jar like aws-java-sdk-s3. However, your comment prompted me to look into other possible missing dependencies, where I stumbled across this: stackoverflow.com/a/34133723 -- Adding the Jackson jars worked! So thanks!user901616

4 Answers

0
votes

Try to set credentials explicitly, as you build your client instance.

Like,

...
BasicAWSCredentials awsCreds = new BasicAWSCredentials(awsAccessKey, awsSecretAccessKey);
AWSStaticCredentialsProvider awsCredsProvider = new AWSStaticCredentialsProvider(awsCreds);
AmazonS3 s3Client = AmazonS3ClientBuilder.standard().withRegion("us-west-2").withCredentials(awsCredsProvider).build();
0
votes

For the groovy way, for class class com.amazonaws.services.s3.S3CredentialsProviderChain, you need aws-java-sdk-s3-1.11.161.jar in your path. https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-s3

The beanshell error message isn't helpful, it is just saying there is an error in your code somewhere but doesn't really say where. I guess you could turn on additional debugging to find out, but I'd stick with groovy.

0
votes

In aws sdk java it stated:

To use the SDK, add the full path to the lib and third-party directories to the dependencies in your build file, and add them to your java CLASSPATH to run your code.

0
votes

You need to include the three specified Jackson libraries as well. That will correct the issue.