13
votes

I have created simple Lambda function and upload this to AWS Lambda.

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;

public class Hello implements RequestHandler<String, String> {

    @Override
    public String handleRequest(String input, Context context) {
         String output = "Bonjour, " + input + "!";
         return output;
    }

}

}

I want to invoke this Lambda function from some other project using java class. I am using aws-java-sdk-lambda-1.10.22 to call the function. But I am not able to succeed in that.

Here is my InvokeLambda class which is a separate project.

import java.nio.ByteBuffer;
import java.nio.charset.Charset;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.lambda.AWSLambdaClient;
import com.amazonaws.services.lambda.model.InvokeRequest;

public class InvokeLambda {
    private static final Log logger = LogFactory.getLog(InvokeLambda.class);
    private static final String awsAccessKeyId = "XXXXXX";
    private static final String awsSecretAccessKey = "YYYY";
    private static final String regionName = "us-west-2";
    private static final String functionName = "Hello";
    private static Region region;
    private static AWSCredentials credentials;
    private static AWSLambdaClient lambdaClient;

    /**
     * The entry point into the AWS lambda function.
     */
    public static void main(String... args) {
        credentials = new BasicAWSCredentials(awsAccessKeyId,
                awsSecretAccessKey);

        lambdaClient = (credentials == null) ? new AWSLambdaClient()
                : new AWSLambdaClient(credentials);
        //lambdaClient.configureRegion(Regions.US_WEST_2);
        region = Region.getRegion(Regions.fromName(regionName));
        lambdaClient.setRegion(region);

        try {
            InvokeRequest invokeRequest = new InvokeRequest();
            invokeRequest.setFunctionName(functionName);
            invokeRequest.setPayload("\" AWS Lambda\"");
            System.out.println(byteBufferToString(
                    lambdaClient.invoke(invokeRequest).getPayload(),
                    Charset.forName("UTF-8")));
        } catch (Exception e) {
            logger.error(e.getMessage());
            // System.out.println(e.getMessage());

        }
    }

    public static String byteBufferToString(ByteBuffer buffer, Charset charset) {
        byte[] bytes;
        if (buffer.hasArray()) {
            bytes = buffer.array();
        } else {
            bytes = new byte[buffer.remaining()];
            buffer.get(bytes);
        }
        return new String(bytes, charset);
    }
}

How to call the lambda function using java?

2
What problem are you having exactly? Have you tried running the InvokeLambda program? It looks correct to me.Joe Taylor
@JoeTaylor : Yes I tried to run the class. I am getting {"errorMessage":"Class not found: com.aws.HelloLambda","errorType":"class java.lang.ClassNotFoundException"} errorUnknown
in your question, I got my answer...thanks for uploading the code.Suraj Kumar Singh

2 Answers

9
votes

Given the information in your comment, your client code to invoke the function is fine. The problem appears to be with the configuration of the function itself. Specifically, AWS Lambda is not able to find the handler you've specified (com.aws.HelloLambda::handleRequest) because that doesn't match the name and package of your handler class (Hello) and the name of your method in that class (handleRequest).

You can update the function handler name through the AWS Console. Choose your function, then the configuration tab and then the Handler property.

You probably want to change it from com.aws.HelloLambda::handleRequest to Hello::handleRequest.

example of how to update the Handler name in the console

Before testing the function from your Java client, you could test it directly through the console, this will help you ensure the function is configured correctly.

2
votes

Another way to invoke lambda from java code is to use LambdaInvokerFactory and I found this approach cleaner. You need to do the following:

  1. Define interface representing your function and annotate method with @LambdaFunction

  2. Create implementation of the above interface using LambdaInvokerFactory

  3. Invoke lambda function using just created proxy object (interface implementation)

    More detailed example can be found here.