如何通用化template.yml中的CodeUri以实现AWS Lambda本地测试
Great question! Having to tweak the CodeUri path every time your Java Lambda's JAR version changes is such a tedious, repetitive task. Here are a few practical, maintainable solutions to make your configuration generic:
1. Fix the JAR Output Name (Recommended)
The simplest approach is to configure your build tool (Maven/Gradle) to generate a JAR file without version numbers in its name. This way, your CodeUri can point to a fixed path that never changes.
For Maven:
Update your pom.xml to set a static final name for the JAR via the maven-jar-plugin:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.3.0</version> <configuration> <finalName>lambda-sns-listener</finalName> <!-- No version here --> </configuration> </plugin> </plugins> </build>
Then update your template.yml to use this fixed path:
AWSTemplateFormatVersion: 2010-09-09 Transform: AWS::Serverless-2016-10-31 Resources: ExampleJavaFunction: Type: AWS::Serverless::Function Properties: Handler: com.someCompany.SNSListener::handleRequest CodeUri: ./target/lambda-sns-listener.jar # Fixed, version-agnostic path Runtime: java8
Every build will overwrite the same JAR file, so you’ll never need to edit the template again.
2. Use SAM Template Parameters with Dynamic Version Injection
If you prefer keeping version numbers in your JAR filenames, use SAM parameters to inject the version dynamically instead of hardcoding it.
Step 1: Update the Template
Add a parameter for the JAR version and use !Sub to interpolate it into the CodeUri:
AWSTemplateFormatVersion: 2010-09-09 Transform: AWS::Serverless-2016-10-31 Parameters: LambdaJarVersion: Type: String Default: "0.0.1-SNAPSHOT" # Fallback for local testing Resources: ExampleJavaFunction: Type: AWS::Serverless::Function Properties: Handler: com.someCompany.SNSListener::handleRequest CodeUri: !Sub "./target/aws-lambda-sqs-${LambdaJarVersion}.jar" Runtime: java8
Step 2: Pass the Version During Local Testing
You can manually pass the version when invoking locally:
sam local invoke --event event_file.json --parameter-overrides LambdaJarVersion=0.0.2-SNAPSHOT
To automate this (so you don’t have to type the version every time), extract it directly from your pom.xml with Maven:
VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) sam local invoke --event event_file.json --parameter-overrides LambdaJarVersion=$VERSION
3. Local Symbol Link (Quick Temporary Fix)
For a quick, no-build-config change solution, create a symbolic link that points to your current versioned JAR, then reference the link in your template.
Create the link (run this once after each version update):
ln -sf ./target/aws-lambda-sqs-0.0.1-SNAPSHOT.jar ./target/lambda-current.jar
Update CodeUri to use the link:
CodeUri: ./target/lambda-current.jar
The -f flag ensures re-running the command overwrites the link to point to the new JAR. This is great for short-term use but less maintainable than the first two options.
内容的提问来源于stack exchange,提问作者best wishes

