sam build with Gradle packages unnecessary JARs.
shearn89 opened this issue · 3 comments
Description:
Possibly duplicate of #138, not sure.
I have a SAM project that uses Gradle, and I want to use a layer for my libraries (it's Java). Running gradle build
correctly produces the right zip files, one of 32MB (my dependencies) and one of 109K (my lambda):
❯ gradle build
BUILD SUCCESSFUL in 1s
8 actionable tasks: 8 up-to-date
❯ ll myFunction/build/distributions/myFunction.zip
-rw-r--r-- 1 ajshearn staff 109K 2 Mar 14:08 myFunction/build/distributions/myFunction.zip
❯ ll layers/build/distributions/layers.zip
-rw-r--r-- 1 ajshearn staff 32M 2 Mar 14:08 layers/build/distributions/layers.zip
When I run sam build
, it bundles all the libraries into my main function folder:
❯ rm -rf .aws-sam; sam build
Test the latest build changes for Java runtime 'SAM_CLI_BETA_MAVEN_SCOPE_AND_LAYER=1 sam build'. These changes will replace the existing flow on 1st of April 2022. Check https://github.com/aws/aws-sam-cli/issues/3639 for more information.
Building layer 'libs'
Running JavaGradleWorkflow:GradleBuild
Running JavaGradleWorkflow:JavaGradleCopyArtifacts
Building codeuri: /Users/ajshearn/repos/myLambda/nodeFunctions runtime: nodejs14.x metadata: {} architecture: arm64 functions: ['connectTriggerFunction']
package.json file not found. Continuing the build without dependencies.
Running NodejsNpmBuilder:CopySource
Building codeuri: /Users/ajshearn/repos/myLambda/myFunction runtime: java11 metadata: {} architecture: arm64 functions: ['myFunction']
Running JavaGradleWorkflow:GradleBuild
Running JavaGradleWorkflow:JavaGradleCopyArtifacts
Build Succeeded
Built Artifacts : .aws-sam/build
Built Template : .aws-sam/build/template.yaml
Commands you can use next
=========================
[*] Invoke Function: sam local invoke
[*] Test Function in the Cloud: sam sync --stack-name {stack-name} --watch
[*] Deploy: sam deploy --guided
❯ du -sh .aws-sam/build/*
4.0K .aws-sam/build/connectTriggerFunction
36M .aws-sam/build/libs
36M .aws-sam/build/processVoicePrintFunction
4.0K .aws-sam/build/template.yaml
Steps to reproduce the issue:
- Clone this repo, which is pretty much
sam init
with the requiredgradle
andtemplate.yml
modifications to add the layers. - Check the README for the commands
Observed result:
JAR files packaged into main function zip even though they don't need to be.
Expected result:
Layers packaged correctly resulting in a "skinny" function zip.
Additional environment details (Ex: Windows, Mac, Amazon Linux etc)
M1 Macbook Pro with MacOS 12.2.1, SAM CLI version 1.40.1. Java 11 (Coretto). Gradle 7.4.
I found a workaround, which is tracked in the workaround
branch in the linked repo.
I had to change the build method to makefile
and then create and copy the files myself:
❯ git diff main
diff --git a/HelloWorldFunction/Makefile b/HelloWorldFunction/Makefile
new file mode 100644
index 0000000..e2a98f3
--- /dev/null
+++ b/HelloWorldFunction/Makefile
@@ -0,0 +1,5 @@
+.PHONY: build-HelloWorldFunction
+
+build-HelloWorldFunction:
+ gradle build
+ unzip -d $(ARTIFACTS_DIR)/ ./build/libs/HelloWorldFunction*.jar
diff --git a/template.yaml b/template.yaml
index 403565b..9c902cb 100644
--- a/template.yaml
+++ b/template.yaml
@@ -31,6 +31,8 @@ Resources:
Properties:
Path: /hello
Method: get
+ Metadata:
+ BuildMethod: makefile
libs:
Type: AWS::Serverless::LayerVersion
Properties:
But I do now get:
❯ tree .aws-sam
.aws-sam
├── build
│ ├── HelloWorldFunction
│ │ ├── META-INF
│ │ │ └── MANIFEST.MF
│ │ └── helloworld
│ │ └── App.class
│ ├── libs
│ │ └── java
│ │ ├── META-INF
│ │ │ └── MANIFEST.MF
│ │ └── lib
│ │ ├── aws-lambda-java-core-1.2.1.jar
│ │ ├── aws-lambda-java-events-3.11.0.jar
│ │ └── joda-time-2.6.jar
│ └── template.yaml
└── build.toml
8 directories, 8 files
@shearn89 Unfortunately this is by design (https://github.com/aws/aws-lambda-builders/blob/develop/aws_lambda_builders/workflows/java_gradle/DESIGN.md has more details) and partially due to Layers not being a build-able target (I don't think Layers was even a thing when we launch sam build
).
I am not sure how we can unwind this and still get what we are getting today. So I think what you called out as a workaround is actually the solution here. Makefile will give you the ability to escape out of our "canned" builders and therefore more power. Maybe there is a better way to handle this and open to hear thoughts (if you have any).
I do think this is a duplicate of #138 or at least #138 would also solve this.
I would prefer to push conversations into #138 so we can keep everything in one place (best we can) but let me know if you feel differently.