# aws-lambda-java-libs: the Java interfaces behind a Lambda function

> This repository is the official mirror for the Java packages that run on AWS Lambda, including the handler interfaces, the event source models, a JUnit injection library, a Log4J2 adapter and the runtime interface client for container image deployments. The code that runs your function is not here, only what wraps it.

**aws/aws-lambda-java-libs** — Official mirror for interface definitions and helper classes for Java code running on the AWS Lambda platform.

- Repository: https://github.com/aws/aws-lambda-java-libs
- Website: https://aws.amazon.com/lambda/
- Stars: 549 · Forks: 241
- Language: Java
- License: Apache-2.0
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/aws-aws-lambda-java-libs

## A mirror of interface definitions, not an application

The repository description is precise: it is the official mirror for interface definitions and helper classes for Java code running on the AWS Lambda platform. That word mirror sets the expectation properly. You do not clone this to build a service; you depend on its artifacts from Maven Central, and the repository exists so that the sources of those artifacts are readable and auditable.

The tree confirms the structure. There is a directory per artifact, matching the artifact names: aws-lambda-java-core, aws-lambda-java-events, aws-lambda-java-tests, aws-lambda-java-events-sdk-transformer, aws-lambda-java-log4j2, aws-lambda-java-runtime-interface-client and aws-lambda-java-serialization. Alongside them are samples/, lambda-integration-tests/, experimental/ for the profiler, and toolchains.xml.example, which is the Maven toolchains file pattern used to pin a JDK per module.

The primary language is Java, the licence is Apache-2.0, the default branch is main, and the last push was on 2026-10-20. The repository has no GitHub releases, which is consistent with the versioning happening in the per-artifact release notes and on Maven Central rather than through GitHub tags.

For issues and questions the project points at the AWS Lambda FAQ and the re:Post site, and the getting-started pointer is the official developer guide rather than anything in this repository.

## The core package: the handler contract and the Context object

aws-lambda-java-core is the package every Java Lambda function ends up depending on, whether it realises it or not.

It defines the Lambda Context object as well as interfaces that Lambda accepts. The Context is the runtime's handle back into the invocation environment, and the handler interfaces are the shapes the platform knows how to call.

There are two principal shapes. A request handler takes a typed event and returns a typed result.

```java
public class Handler implements RequestHandler<Map<String, String>, String>{
 @Override
 public String handleRequest(Map<String, String> event, Context context) {

 }
}
```

A request stream handler takes streams instead, which is what you use when the payload is large and you do not want it materialised as an object graph.

```java
public class HandlerStream implements RequestStreamHandler {
  @Override
  public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {

  }
}
```

The dependency coordinates are the com.amazonaws group with the aws-lambda-java-core artifact, at version 1.3.0 in the documentation.

```xml
<dependency>
 <groupId>com.amazonaws</groupId>
 <artifactId>aws-lambda-java-core</artifactId>
 <version>1.3.0</version>
</dependency>
```

The design point worth noticing is that the interface signature carries the event type as a type parameter. A handler for a specific event source is a different class from a handler for a generic map, and the platform's serialisation is chosen by which interface you implement, not by configuration.

## Event models, and the package that turns them into SDK objects

aws-lambda-java-events defines the event sources that Lambda natively accepts, and using this library you can have Java objects which represent event sources.

The example given is a queue message, and the shape is the familiar one: the handler implements RequestHandler with the event type as a parameter.

```java
import com.amazonaws.services.lambda.runtime.events.SQSEvent;

public class SqsHandler implements RequestHandler<SQSEvent, String> {

 @Override
 public String handleRequest(SQSEvent event, Context context) {

 }
}
```

The coordinates are com.amazonaws with the aws-lambda-java-events artifact at version 3.16.0.

```xml
<dependency>
 <groupId>com.amazonaws</groupId>
 <artifactId>aws-lambda-java-events</artifactId>
 <version>3.16.0</version>
</dependency>
```

The list of currently supported event sources is in the package's own README rather than the top-level one, and that is worth knowing before you pick a version, because a new event source appears there before the top-level documentation mentions it.

The companion package aws-lambda-java-events-sdk-transformer exists for a specific reason: it provides helper classes and methods to use alongside aws-lambda-java-events in order to transform Lambda input event model objects into SDK-compatible output model objects. That is the case where your function receives a Lambda event shape but your business logic wants to work with the AWS SDK's own model types, and the transformer bridges the two without you writing the mapping. Its coordinates are the same group with the aws-lambda-java-events-sdk-transformer artifact at version 3.1.0.

## Testing a handler without inventing an event by hand

aws-lambda-java-tests is the package that removes the most tedious part of testing a Lambda function, and the mechanism is worth understanding rather than just using.

It provides utils to ease Lambda Java testing, and it uses the same Lambda serialisation logic and aws-lambda-java-events to inject events in your JUnit tests. That last part is the important detail: the test injects an event by running it through the same deserialisation path the runtime uses, so the object your test sees is the object the platform would have produced.

The API is a JUnit parameterised test with an Event annotation naming a JSON fixture and the target type.

```java
@ParameterizedTest
@Event(value = "sqs/sqs_event.json", type = SQSEvent.class)
public void testInjectSQSEvent(SQSEvent event) {
        ...
}
```

So a test becomes a list of fixture files and a type, and the framework deserialises each fixture into the event class. The dependency is com.amazonaws with the aws-lambda-java-tests artifact at version 1.1.1, and it is declared with test scope.

```xml
<dependency>
  <groupId>com.amazonaws</groupId>
  <artifactId>aws-lambda-java-tests</artifactId>
  <version>1.1.1</version>
  <scope>test</scope>
</dependency>
```

The trade-off is that the fixtures become a contract. They live in the repository and they encode what the platform sends, so when a source changes its event shape, the tests are what tell you, provided someone updates the fixture. That is a benefit if you maintain them and a liability if you let them drift.

## Logging, profiling and the container image runtime

Three more artifacts round out the set, and they address different operational problems.

aws-lambda-java-log4j2 defines the Lambda adapter to use with Log4J version 2, at version 1.6.0. On a platform where stdout is the log transport, an adapter is what makes a conventional logging framework's configuration, including asynchronous appenders and JSON layouts, produce something the platform can capture.

The experimental profiler is the more interesting one. It allows you to profile your Java functions invoke by invoke, with high fidelity, and no code changes, using the async-profiler project to produce profiling data and automatically uploading the data as flame graphs to S3. A flame graph of a cold start is included in the documentation. The trade is that it is under experimental/, so it is not held to the same stability promise as the other packages, and it depends on a native profiler agent inside your function image.

aws-lambda-java-runtime-interface-client is the one that unlocks container image deployments. It defines the Lambda Runtime Interface Client package, a Lambda Runtime component that starts the runtime and interacts with the Runtime API, calling the API for invocation events, starting the function code, and calling the API to return the response. The stated purpose is to allow developers to deploy their applications in Lambda under the form of Container Images, at version 2.10.1.

There is also aws-lambda-java-serialization for Lambda provided serialization support, and the samples directory shows custom-serialization alongside Kinesis Firehose and MSK Firehose event handlers.

## Where this set of libraries stops being useful

There are three limits, and they follow from being a platform interface rather than a product.

The first is that you do not choose these libraries, you inherit them. The handler interface, the Context object and the event models are the platform's contract, and the versions in the documentation are the versions the platform currently expects. Forking or patching them is not a sensible option, so the practical upgrade question is not whether to update but when the platform's expectations and your pinned versions diverge. That is why each package carries its own release notes file, and why reading those before bumping a version is the sensible habit.

The second is that the event models are a snapshot of the platform's event shapes. A new event source, or a changed field in an existing one, shows up in the events package first and in your compile errors second. The samples in the repository, custom-serialization, kinesis-firehose-event-handler and msk-firehose-event-handler, exist because that boundary is where teams actually get stuck.

The third is the profiler, which is the one part here that is not a stable interface. It runs inside your function, it uploads data to S3, and it changes the shape of your deployment. It is genuinely useful for understanding cold starts and per-invocation behaviour, and it is also the piece to treat as experimental.

On alternatives, the honest comparison is with writing the handler yourself. A handler is an interface, and the platform's contract can be implemented without these packages, using plain serialisation. What you give up is the event models, the Context object, the serialisation logic the test package reuses, and the compatibility work the maintainers do when the platform changes. For a Java team on Lambda, that is a good trade, and for a team that has a strong reason to control its own serialisation, the custom-serialization sample is the documented path.

## Conclusion

Adopt these libraries as a dependency, not as a codebase, since they are the official Java artifacts every Lambda function pulls in and they are what makes the platform's handler contract expressible in Java. Do not vendor them or expect to change them, because they track the platform's Runtime API. Before you pin versions, read the per-package release notes in the repository, and note the last push was on 2026-10-20 with no GitHub releases.

## FAQ

### What does the aws-lambda-java-libs repository contain?

It is the official mirror for the interface definitions and helper classes for Java code running on the Lambda platform, with a directory per artifact: aws-lambda-java-core, aws-lambda-java-events, aws-lambda-java-tests, aws-lambda-java-events-sdk-transformer, aws-lambda-java-log4j2, aws-lambda-java-runtime-interface-client and aws-lambda-java-serialization.

### What is the difference between aws-lambda-java-core and aws-lambda-java-events?

The core package defines the Lambda Context object and the interfaces Lambda accepts, such as RequestHandler and RequestStreamHandler. The events package defines the event sources that Lambda natively accepts, so you can have Java objects which represent event sources, with aws-lambda-java-events-sdk-transformer converting them into SDK-compatible output model objects.

### How do I test a Java Lambda handler with real event payloads?

Use the aws-lambda-java-tests package, which uses the same Lambda serialisation logic and aws-lambda-java-events to inject events in your JUnit tests. Annotate a parameterised test with @Event naming a JSON fixture and the target type, as in @Event(value = "sqs/sqs_event.json", type = SQSEvent.class).

### Which package do I need to deploy a Java function as a container image?

The aws-lambda-java-runtime-interface-client, which defines a Lambda Runtime component that starts the runtime and interacts with the Runtime API, calling it for invocation events, starting the function code and returning the response. Its stated purpose is to allow deploying applications to Lambda under the form of Container Images.

### How do I profile a Java Lambda function without changing the code?

The experimental aws-lambda-java-profiler does that, using the async-profiler project to produce profiling data and automatically uploading it as flame graphs to S3, profiling your functions invoke by invoke. It is under experimental, so it carries less of a stability guarantee than the published packages.

## Sources

- [aws/aws-lambda-java-libs on GitHub](https://github.com/aws/aws-lambda-java-libs)
- [Issues](https://github.com/aws/aws-lambda-java-libs/issues)
- [License: Apache-2.0](https://github.com/aws/aws-lambda-java-libs/blob/main/LICENSE)
- [Project website](https://aws.amazon.com/lambda/)
- [README](https://github.com/aws/aws-lambda-java-libs/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/aws-aws-lambda-java-libs
