Releases: aws-powertools/powertools-lambda-java
v2.1.1
Summary
This update improves the Kafka utility to work seamlessly with both AWS Glue Schema Registry and Confluent Schema Registry when processing Protocol Buffer messages. You can now confidently process Kafka messages regardless of which schema registry you're using, without worrying about compatibility issues or message format differences. The enhancement automatically detects the schema registry type and applies the appropriate deserialization logic, making the utility more reliable and flexible for all use cases.
Changes
- chore(ci): bump version to 2.1.1 (#1910) by @github-actions[bot]
- fix(kafka): Handle message indices in proto data also for Glue Schema Registry (#1907) by @phipag and @karthikpswamy
- chore(ci): bump version to 2.1.0 (#1904) by @github-actions[bot]
This release was made possible by the following contributors:
@github-actions[bot], @phipag, @karthikpswamy, and github-actions[bot]
v2.1.0
Summary
We're excited to announce the Kafka Consumer utility for Java, which transparently handles message deserialization, provides an intuitive developer experience, and integrates seamlessly with the rest of the Powertools for AWS Lambda ecosystem.
Key features
- Automatic deserialization of Kafka messages (JSON, Avro, and Protocol Buffers)
- Simplified event record handling with familiar Kafka
ConsumerRecords
interface - Support for key and value deserialization
- Support for Event Source Mapping (ESM) with and without Schema Registry integration
Getting Started
To get started, add the Powertools for AWS Lambda Kafka dependency to your project along with the required dependencies for your schema types:
Maven:
<dependency>
<groupId>software.amazon.lambda</groupId>
<artifactId>powertools-kafka</artifactId>
<version>2.1.0</version>
</dependency>
<!-- Kafka clients dependency - compatibility works for >= 3.0.0 -->
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<version>4.0.0</version>
</dependency>
Gradle:
dependencies {
implementation 'software.amazon.lambda:powertools-kafka:2.1.0'
// Kafka clients dependency - compatibility works for >= 3.0.0
implementation 'org.apache.kafka:kafka-clients:4.0.0'
}
Processing Kafka events
You can use the Kafka consumer utility to transform raw Kafka events into an intuitive format for processing using the @Deserialization
annotation.
The @Deserialization
annotation can deserialize both keys and values independently based on your schema configuration. This flexibility allows you to easily combine primitive types (strings, integers) with complex types (Avro, Protocol Buffers, JSON) in the same message.
Working with Avro:
public class AvroKafkaHandler implements RequestHandler<ConsumerRecords<String, User>, String> {
private static final Logger LOGGER = LoggerFactory.getLogger(AvroKafkaHandler.class);
@Override
@Logging
@Deserialization(type = DeserializationType.KAFKA_AVRO)
public String handleRequest(ConsumerRecords<String, User> records, Context context) {
for (ConsumerRecord<String, User> record : records) {
User user = record.value(); // User class is auto-generated from Avro schema
LOGGER.info("Processing user: {}, age {}", user.getName(), user.getAge());
}
return "OK";
}
}
Working with Protocol Buffers:
public class ProtobufKafkaHandler implements RequestHandler<ConsumerRecords<String, UserProto.User>, String> {
private static final Logger LOGGER = LoggerFactory.getLogger(ProtobufKafkaHandler.class);
@Override
@Logging
@Deserialization(type = DeserializationType.KAFKA_PROTOBUF)
public String handleRequest(ConsumerRecords<String, UserProto.User> records, Context context) {
for (ConsumerRecord<String, UserProto.User> record : records) {
UserProto.User user = record.value(); // UserProto.User class is auto-generated from Protocol Buffer schema
LOGGER.info("Processing user: {}, age {}", user.getName(), user.getAge());
}
return "OK";
}
}
Working with JSON messages:
public class JsonKafkaHandler implements RequestHandler<ConsumerRecords<String, User>, String> {
private static final Logger LOGGER = LoggerFactory.getLogger(JsonKafkaHandler.class);
@Override
@Logging
@Deserialization(type = DeserializationType.KAFKA_JSON)
public String handleRequest(ConsumerRecords<String, User> records, Context context) {
for (ConsumerRecord<String, User> record : records) {
User user = record.value(); // Deserialized JSON object into User POJO
LOGGER.info("Processing user: {}, age {}", user.getName(), user.getAge());
}
return "OK";
}
}
Error handling
The Java Kafka utility uses Lambda custom serializers and performs eager deserialization of all records in the batch before your handler method is invoked.
This means that if any record in the batch fails deserialization, a RuntimeException
will be thrown with a concrete error message explaining why deserialization failed, and your handler method will never be called.
Key implications:
- Batch-level failure: If one record fails deserialization, the entire batch fails
- Early failure detection: Deserialization errors are caught before your business logic runs
- Clear error messages: The
RuntimeException
provides specific details about what went wrong - No partial processing: You cannot process some records while skipping failed ones within the same batch
Example of deserialization failure:
// If any record in the batch has invalid Avro data, you'll see:
// RuntimeException: Failed to deserialize Kafka record: Invalid Avro schema for record at offset 12345
Handling deserialization failures:
Since deserialization happens before your handler is called, you cannot catch these exceptions within your handler method. Instead, configure your Event Source Mapping with appropriate error handling:
- Dead Letter Queue (DLQ): Configure a DLQ to capture failed batches for later analysis
- Maximum Retry Attempts: Set appropriate retry limits to avoid infinite retries
- Batch Size: Use smaller batch sizes to minimize the impact of individual record failures
# Example SAM template configuration for error handling
Events:
KafkaEvent:
Type: MSK
Properties:
# ... other properties
BatchSize: 10 # Smaller batches reduce failure impact
MaximumRetryAttempts: 3
DestinationConfig:
OnFailure:
Type: SQS
Destination: !GetAtt DeadLetterQueue.Arn
To learn more about the launch, read the blog post published alongside the release.
Changes
- chore(ci): bump version to 2.1.0 (#1904) by @github-actions[bot]
- fix(kafka): Add support for confluent message indices. (#1902) by @phipag
- feat(kafka): New Kafka utility (#1898) by @phipag
- chore(ci): Update workflows to make v2 the default (#1888) by @sthulb
- chore(ci): bump version to 2.0.0 (#1876) by @github-actions[bot]
📜 Documentation updates
🐛 Bug and hot fixes
- fix(ci): Add project description for new kafka utility (#1903) by @phipag
- fix(metrics): Do not flush when no metrics were added to avoid printing root-level _aws dict (#1891) by @phipag
This release was made possible by the following contributors:
@github-actions[bot], @phipag, @sthulb and github-actions[bot]
v2.0.0
Powertools for AWS Lambda (Java) 2.0.0 🎉
We are super happy to announce our new major version – v2.0.0 🎉🎉!
We've made Java ecosystem integration the focus of this release, with a complete redesign of the Logging utility to support popular Java logging paradigms and improved modularity across all utilities to reduce deployment package size.
🌟 We couldn't have done this without you 🌟
Thanks to everyone in the community for their patience and assistance as we've been working on this release. Your feedback has been invaluable in shaping this major update.
A special thanks to @jeromevdl and @scottgerring for their amazing contributions to this milestone.
We care deeply about minimizing breaking changes
Over the past few months, we carefully selected each breaking change to make, and crafted an extensive upgrade guide to ease your transition to v2. Please let us know whether we can make your upgrade process easier.
What's New in v2 ✨
Java Version Support 🚀
- Minimum required Java version is now Java 11 (Java 8 support has been removed)
Redesigned Logging Utility 📝
- Complete redesign to support popular Java logging paradigms
- Now supports
slf4j
as logging interface with choice oflog4j2
orlogback
implementations - Replaced
LambdaJsonLayout
with standardJsonTemplateLayout
- Uses native
slf4j
primitives for better integration with Java ecosystem
The new logging utility introduces advanced structured argument serialization features, allowing for more expressive and detailed logging. You can now easily add structured context to your log messages:
// Before v2
private static final Logger LOGGER = LogManager.getLogger(PaymentFunction.class);
LoggingUtils.appendKey("cardNumber", card.getId());
// After v2
private static final Logger LOGGER = LoggerFactory.getLogger(PaymentFunction.class);
MDC.put("cardNumber", card.getId());
// Add structured data directly in log messages
LOGGER.info("Collecting payment", StructuredArguments.entry("orderId", order.getId()));
// { "message": "Collecting payment", ..., "orderId": 123}
// Add multiple structured fields at once
Map<String, String> customKeys = new HashMap<>();
customKeys.put("paymentId", payment.getId());
customKeys.put("amount", payment.getAmount());
LOGGER.info("Payment successful", StructuredArguments.entries(customKeys));
// { "message": "Payment successful", ..., "paymentId": 123, "amount": 12.99}
Updated Metrics Utility 📊
- Redesigned to be more modular and support multiple metrics providers
@Metrics
annotation renamed to@FlushMetrics
MetricsLogger.metricsLogger()
renamed toMetricsFactory.getMetricsInstance()
put
methods replaced withadd
methods (e.g.,putMetric()
→addMetric()
)
This update also brings feature parity with other Powertools for AWS Lambda runtimes, ensuring a consistent experience across Python, TypeScript, .NET, and Java implementations.
// Before v2
@Metrics(namespace = "ExampleApplication", service = "booking")
metricsLogger.putMetric("SuccessfulBooking", 1, Unit.COUNT);
// After v2
@FlushMetrics(namespace = "ExampleApplication", service = "booking")
metrics.addMetric("SuccessfulBooking", 1, MetricUnit.COUNT);
Tracing Updates 🔍
- Removed deprecated
captureResponse
andcaptureError
parameters from@Tracing
annotation - Replaced with new
captureMode
parameter
// Before v2
@Tracing(captureError = false, captureResponse = false)
// After v2
@Tracing(captureMode = CaptureMode.DISABLED)
Parallel Batch Processing ⚡
- New support for processing batch items in parallel using
processBatchInParallel()
- Available for SQS, Kinesis, and DynamoDB Streams (not supported for SQS FIFO queues)
- Automatically propagates logging context to each worker thread
- Improves throughput for IO-bound workloads
// Before v2 - Sequential processing
return handler.processBatch(sqsEvent, context);
// After v2 - Parallel processing
return handler.processBatchInParallel(sqsEvent, context);
The batch processing utility now intelligently handles logging context propagation across worker threads, ensuring that your structured logging context is maintained in parallel execution environments. This makes it easier to trace and debug parallel batch operations while maintaining the same logging experience as sequential processing.
Modularized Utilities 📦
- Idempotency: Split into sub-modules by provider to improve modularity
- Parameters: Split into sub-modules by provider to reduce deployment package size
- SQS: Removed
powertools-sqs
module in favor of the more genericpowertools-batch
utility
Custom Resources Updates 🔄
- Removed deprecated
Response.failed()
andResponse.success()
methods - Now require physical resource ID parameter
// Before v2
return Response.success();
return Response.failed();
// After v2
return Response.success(physicalResourceId);
return Response.failed(physicalResourceId);
Validation Improvements ✅
The Validation utility now better integrates with other utilities from the library, providing a more cohesive experience when combining multiple Powertools features in your applications.
- Returns
4xx
error codes instead of5xx
when used with API Gateway, aligning with HTTP standards - Validating batch event sources now adds failed events as partial batch failures instead of failing the whole batch, improving resilience
Dependencies 📚
- AspectJ runtime no longer included by default – must be added as a dependency
- Renamed
powertools-core
topowertools-common
Backwards incompatible changes
Area | Change | Code Change Required |
---|---|---|
Logging | The logging module was re-designed from scratch to support popular Java logging paradigms | Yes |
Metrics | Changed public interface to remove direct coupling with aws-embedded-metrics-java |
Yes |
Tracing | Removed deprecated captureResponse and captureError options on @Tracing annotation |
Yes |
Idempotency | The powertools-idempotency module was split by provider |
Yes |
Parameters | The powertools-parameters module was split by provider |
Yes |
Batch Processing | Removed deprecated powertools-sqs module in favor of the more generic Batch Processing utility |
Yes |
Custom Resources | Removed deprecated Response.failed() and Response.success() methods |
Yes |
Dependencies | AspectJ runtime not included by default anymore | Yes |
Language support | Removed support for Java 8. The minimum required Java version is Java 11 | N/A |
Migration Guide
For detailed migration instructions, please refer to our upgrade guide.
We've made minimal breaking changes to make your transition to v2 as smooth as possible. The upgrade guide provides step-by-step instructions for each utility.
Thank you for using Powertools for AWS Lambda (Java)! We're committed to helping you build better serverless applications with less code. ❤️
Changes
- chore: Start V2 branch by @scottgerring in #1346
- chore: v2 - fix version by @scottgerring in #1348
- chore: V2 update from main by @scottgerring in #1365
- chore: [V2] rename 'core' module to 'common' by @scottgerring in #1364
- chore: update v2 by @jeromevdl in #1409
- chore: remove aspectj-rt from the library by @jeromevdl in #1408
- fix: add aspectj-rt to batch e2e by @jeromevdl in #1410
- chore: Merge main into v2 by @scottgerring in #1477
- chore(v2): Merge main by @scottgerring in #1492
- chore: merge main into v2 by @jeromevdl in #1494
- chore(v2): clean examples by @jeromevdl in #1495
- chore: removing dynamodb local from examples by @jdoherty in #1507
- chore: Periodic merge of main into v2 by @scottgerring in #1525
- chore: remove Java 8 from v2 examples by @jdoherty in #1531
- feat(v2): Validation failures return 400s by @skal111 in #1489
- chore: fix end 2 end build by @jeromevdl in #1534
- chore(v2): Split parameters module up by parameter provider by @scottgerring in #1403
- feat(v2): new logging module by @jeromevdl in #1435
- chore: cleanup poms and reduce warning noise by @jdoherty in #1535
- chore: Support spotbugs running anywhere by @scottgerring in #1537
- fix(v2): Removing LambdaJsonLayout from logging config in examples by @ritigupt in #1545
- fix(v2): Fix params builder to provide default transformation manager by @ritigupt in https://github.com/aws-powertools/powe...
v2.0.0-RC1
chore(ci): bump version to 2.0.0-RC1
v1.20.2
chore(ci): bump version to 1.20.2
v1.20.1
v1.20.1 Release Notes
Summary
This minor release contains a bug fix that caused unwanted warnings when using Powertools Logging in combination with utilities depending on the AWS SDK.
⭐️ Thanks to @ntestor for his first contribution to Powertools for AWS Lambda in Java!
Bug fix: Append correct Powertools version to AWS SDK HTTP User-Agent header (#1813)
When consumed as a JAR, Powertools could not parse the version.properties
file which is loaded at runtime to append the running version of Powertools to the User-Agent header sent by AWS SDK HTTP calls. This caused a warning logged by Powertools Logging when used in combination with utilities depending on the AWS SDK such as Powertools Parameters.
Thanks to @epomatti for reporting this.
Changes
- docs: fix 2 typos (#1739) by @ntestor
- docs: Correct XML formatting for Maven configuration in Large Messages utility docs (#1796) by @jreijn
- fix: Load version.properties file as resource stream to fix loading when packaged as jar (#1813) by @phipag
This release was made possible by the following contributors:
v1.20.0
Summary
This release improves the CloudFormation Custom Resource module by allowing you to set a reason
field on the Response object. This is useful to report details about the resource for debugging purposes.
Response response = Response.builder()
.reason("<Some Text>")
.build();
⭐️ Thanks to @moizsh for his first contribution to Powertools for AWS Lambda in Java!
Changes
- feat(cfn-custom-resource): Add optional 'reason' field for detailed failure reporting (#1758) by @moizsh
This release was made possible by the following contributors:
v1.19.0
Summary
This release includes important improvements regarding the project’s security management. We addressed several CVEs and implemented OpenSSF Scorecard reporting.
Additionally, we fixed bugs in the Parameters module and improved our documentation and examples.
Thanks to @chrisclayson and @jasoniharris for reporting and fixing those bugs.
Security Posture
We introduced the Open Source Security Foundation (OSSF) Scorecard project to generate security health metrics, proactive security alerts, and attest we've been following OSSF Best Practices.
Thanks to this new reporting mechanism visible to the open-source community, we addressed multiple CVEs across the project, in particular log4j
and jackson-databind
related findings.
Changes
- chore(deps): Update deps for jackson (#1793) by @sthulb
- build(deps): bump log4j.version from 2.22.1 to 2.24.3 (#1777) by @dependabot
- chore(deps): update JSII to 1.108 (#1791) by @sthulb
- build(deps): bump jinja2 from 3.1.5 to 3.1.6 in /docs (#1789) by @dependabot
- chore: Update netty version (#1768) by @sthulb
- chore: Set versions of transitive dependencies (#1767) by @sthulb
- chore: update Jackson in examples (#1766) by @sthulb
- build(deps): bump org.apache.maven.plugins:maven-jar-plugin from 3.4.1 to 3.4.2 (#1731) by @dependabot
- build(deps): bump aws.xray.recorder.version from 2.15.3 to 2.18.1 (#1726) by @dependabot
- build(deps): bump aws.sdk.version from 2.26.29 to 2.27.12 (#1724) by @dependabot
- fix: Allow empty responses as well as null response in AppConfig (#1673) by @chrisclayson
- build(deps): bump aws.sdk.version from 2.27.2 to 2.27.7 (#1715) by @dependabot
- build(deps): bump aws.sdk.version from 2.26.29 to 2.27.2 (#1714) by @dependabot
- build(deps): bump aws.sdk.version from 2.25.26 to 2.26.29 (#1713) by @dependabot
- build(deps): bump aws.sdk.version from 2.26.25 to 2.26.29 (#1712) by @dependabot
- chore: deprecate java1.8 al1 (#1706) by @jeromevdl
- chore: java 1.8 AL1 is deprecated, fix E2E tests (#1692) by @jeromevdl
- build(deps): bump aws.sdk.version from 2.26.21 to 2.26.25 (#1703) by @dependabot
- build(deps): bump aws.sdk.version from 2.26.3 to 2.26.21 (#1697) by @dependabot
- build(deps): bump jackson.version from 2.17.0 to 2.17.2 (#1696) by @dependabot
- build(deps): bump org.apache.commons:commons-lang3 from 3.13.0 to 3.14.0 (#1694) by @dependabot
- build(deps): bump commons-io:commons-io from 2.15.1 to 2.16.1 (#1691) by @dependabot
- docs: improve tracing doc for sdk instrumentation (#1687) by @jeromevdl
- docs: fix tracing links for xray (#1686) by @jeromevdl
- build(deps): bump org.apache.maven.plugins:maven-failsafe-plugin from 3.2.5 to 3.3.0 (#1679) by @dependabot
- build(deps): bump aws.sdk.version from 2.25.69 to 2.26.3 (#1658) by @dependabot
- build(deps): bump com.github.spotbugs:spotbugs-maven-plugin from 4.7.3.6 to 4.8.5.0 (#1657) by @dependabot
- build(deps): bump org.apache.maven.plugins:maven-checkstyle-plugin from 3.3.0 to 3.4.0 (#1653) by @dependabot
- build(deps): bump aws.sdk.version from 2.25.50 to 2.25.69 (#1652) by @dependabot
- build(deps): bump org.apache.maven.plugins:maven-source-plugin from 3.3.0 to 3.3.1 (#1646) by @dependabot
- build(deps): bump org.assertj:assertj-core from 3.25.3 to 3.26.0 (#1644) by @dependabot
- build(deps): bump aws.xray.recorder.version from 2.15.1 to 2.15.3 (#1643) by @dependabot
- build(deps): bump aws.sdk.version from 2.25.35 to 2.25.50 (#1642) by @dependabot
- build(deps): bump com.amazonaws:aws-lambda-java-events from 3.11.2 to 3.11.4 (#1597) by @dependabot
- build(deps): bump aws.sdk.version from 2.24.10 to 2.25.6 (#1603) by @dependabot
- build(deps): bump org.apache.maven.plugins:maven-surefire-plugin from 3.1.2 to 3.2.5 (#1596) by @dependabot
- build(deps): bump org.codehaus.mojo:exec-maven-plugin from 3.1.0 to 3.2.0 (#1585) by @dependabot
- build(deps-dev): bump software.amazon.awscdk:aws-cdk-lib from 2.100.0 to 2.130.0 (#1586) by @dependabot
- build(deps): bump io.burt:jmespath-jackson from 0.5.1 to 0.6.0 (#1587) by @dependabot
- build(deps): bump aws.sdk.version from 2.21.0 to 2.24.10 (#1581) by @dependabot
- build(deps): bump commons-io:commons-io from 2.13.0 to 2.15.1 (#1584) by @dependabot
- build(deps): bump aws.xray.recorder.version from 2.14.0 to 2.15.1 (#1583) by @dependabot
- build(deps): bump org.apache.maven.plugins:maven-shade-plugin from 3.5.0 to 3.5.2 (#1582) by @dependabot
- build(deps-dev): bump org.yaml:snakeyaml from 2.1 to 2.2 (#1400) by @dependabot
- build(deps): bump log4j.version from 2.20.0 to 2.22.1 (#1547) by @dependabot
- build(deps): bump org.apache.maven.plugins:maven-artifact-plugin from 3.4.1 to 3.5.0 (#1485) by @dependabot
- build(deps): bump com.amazonaws:aws-lambda-java-serialization from 1.1.2 to 1.1.5 (#1573) by @dependabot
- build(deps): bump org.jacoco:jacoco-maven-plugin from 0.8.10 to 0.8.11 (#1509) by @dependabot
- build(deps): bump...
v1.18.0
Added
- feat: add support for extended logging environment variables (#1514) by @jeromevdl
- feat: Add support for POWERTOOLS_LOGGER_LOG_EVENT (#1510) by @AlexeySoshin
Maintenance
- fix: json schema 403 error (#1457) by @jeromevdl
- fix: array jmespath fail in idempotency module (#1420) by @jeromevdl
- chore: java21 support in our build (#1488) by @jeromevdl
- chore: Addition of Warn Message If Invalid Annotation Key While Tracing #1511 (#1512) by @jdoherty
- fix: null namespace should fallback to default namespace (#1506) by @jeromevdl
- fix: get trace id from system property when env var is not set (#1503) by @mriccia
- chore: artifacts size on good branches (#1493) by @jeromevdl
- fix: enforce jackson databind version (#1472) by @jeromevdl
- chore: add missing projects and improve workflow (#1487) by @jeromevdl
- chore: Reporting size of the jars in GitHub comments (#1196) by @jeromevdl
- Deps: Bump third party dependencies to the latest versions.
Documentation
- docs(customer-reference): add Vertex Pharmaceuticals as a customer reference (#1486) by @scottgerring
- docs: Adding Kotlin example. (#1454) by @jasoniharris
- docs: Terraform example (#1478) by @skal111
- docs: Add Serveless Framework example (#1363) by @AlexeySoshin
- docs: Fix link to SQS large message migration guide (#1422) by @scottgerring
- docs(logging): correct log example keys (#1411) by @walmsles
- docs: Update gradle configuration readme (#1359) by @scottgerring
This release was made possible by the following contributors:
@AlexeySoshin, @am29d, @dependabot, @dependabot[bot], @jasoniharris, @jdoherty, @jeromevdl, @mriccia, @scottgerring, @skal111 and @walmsles
v1.17.0
Added
- Feat: Add Batch Processor module in (#1317) by @scottgerring and @mriccia
- Feat: Add SNS+SQS large messages module (#1310) by @jeromevdl
Maintenance
- fix: use default credentials provider for all provided SDK clients in (#1303) by @roamingthings
- Chore: Make request for Logger explicitly for current class in (#1307) by @jreijn
- Chore: checkstyle formater & linter in (#1316) by @jeromevdl
- Chore: Add powertools specific user-agent-suffix to the AWS SDK v2 clients by @eldimi in (#1306)
- Chore: Add 'v2' branch to build workflows to prepare for v2 work in (#1341) by @scottgerring
- Deps: Bump third party dependencies to the latest versions.
Documentation
- Docs: Add maintainers guide in (#1326) by @scottgerring
- Docs: improve contributing guide in (#1334) by @jeromevdl
- Docs: Improve example documentation in (#1291) by @scottgerring
- Docs: Add discord + sec disclosure links to readme in (#1311) by @scottgerring
- Docs: Add external examples from AWS SAM CLI App Templates in (#1318) by @AlexeySoshin
- Docs: Add CDK example in (#1321) by @AlexeySoshin
This release was made possible by the following contributors:
@eldimi, @jreijn, @roamingthings, @AlexeySoshin, @jeromevdl, @mriccia, and @scottgerring