AWS SAM with Java - 构建一个瘦罐子

发布于 2025-01-09 12:38:05 字数 4066 浏览 0 评论 0原文

我正在使用 AWS SAM 构建 Java Lambda。我还使用 Gradle 进行打包。

我正在尝试使用层来分离我的依赖项和代码。

当我在代码文件夹中运行 gradle build 时,我得到一个干净的构建文件夹,没有依赖项 jar。这使用 packageSkinny 目标。

当我在 deps 文件夹中运行 gradle build 时,我也得到了所需的结果 - 所有依赖项,没有代码。这使用 packageLibs 目标。

但是,当我运行 sam build 时,我会得到一个构建文件夹,其中两个文件夹(层和函数)中都包含依赖项 JAR。

如何阻止 AWS SAM 在主函数层中包含我的所有依赖项,并为我的编译代码获取一个漂亮的精简 zip 文件?

函数 Gradle 文件:

plugins {
    id 'java'
}

repositories {
    mavenCentral()
}

dependencies {
    implementation platform('software.amazon.awssdk:bom:2.16.60')
    implementation platform('com.amazonaws:aws-xray-recorder-sdk-bom:2.11.0')
//    implementation 'software.amazon.awssdk:lambda'
    implementation 'com.amazonaws:aws-xray-recorder-sdk-core'
    implementation 'com.amazonaws:aws-xray-recorder-sdk-aws-sdk-v2'
    implementation 'com.amazonaws:aws-xray-recorder-sdk-aws-sdk-v2-instrumentor'
    implementation 'com.amazonaws:aws-lambda-java-core:1.2.1'
    implementation 'com.amazonaws:aws-lambda-java-events:3.11.0'
    implementation 'com.google.code.gson:gson:2.8.6'
    implementation 'org.apache.logging.log4j:log4j-api:[2.17.1,)'
    implementation 'org.apache.logging.log4j:log4j-core:[2.17.1,)'
    runtimeOnly 'org.apache.logging.log4j:log4j-slf4j18-impl:[2.17.1,)'
    runtimeOnly 'com.amazonaws:aws-lambda-java-log4j2:1.5.0'
    testImplementation 'junit:junit:4.13.2'
//    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.0'
}

task packageFat(type: Zip) {
    from compileJava
    from processResources
    into('lib') {
        from configurations.runtimeClasspath
    }
    dirMode = 0755
    fileMode = 0755
}

task packageLibs(type: Zip) {
    into('java/lib') {
        from configurations.runtimeClasspath
    }
    dirMode = 0755
    fileMode = 0755
}

task packageSkinny(type: Zip) {
    from compileJava
    from processResources
}

sourceCompatibility = 11
targetCompatibility = 11

build.dependsOn packageSkinny

SAM 模板:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  HelloWorld

  Sample SAM Template for HelloWorld

Globals:
  Function:
    Timeout: 20

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: HelloWorldFunction
      Handler: HelloWorld.Handler::handleRequest
      Runtime: java11
      Description: Handler to process and encode the voice print
      Architectures:
        - arm64
      MemorySize: 512
      Policies:
        - AWSLambdaBasicExecutionRole
        - AWSLambda_ReadOnlyAccess
        - AWSXrayWriteOnlyAccess
        - AWSLambdaVPCAccessExecutionRole
      Tracing: Active
      Layers:
        - !Ref libs
  libs:
    Type: AWS::Serverless::LayerVersion
    Properties:
      ContentUri: layers
      Description: Dependencies for the HelloWorld function
      LayerName: HelloWorld-lib
      CompatibleRuntimes:
        - java11
      CompatibleArchitectures:
        - arm64
    Metadata:
      BuildMethod: java11
      BuildArchitecture: arm64

Outputs:
  HelloWorldFunction:
    Description: "Lambda Function ARN"
    Value: !GetAtt HelloWorldFunction.Arn

文件夹结构:

❯ tree
.
├── README.md
├── events
│   └── event.json
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── layers
│   └── build.gradle
├── out.json
├── HelloWorldFunction
│   ├── build.gradle
│   └── src
│       ├── main
│       │   └── java
│       │       └── HelloWorld
│       │           └── Handler.java
│       └── test
│           └── java
│               └── HelloWorld
│                   ├── AppTest.java
│                   ├── TestContext.java
│                   └── TestLogger.java
├── samconfig.toml
└── template.yaml

I'm using AWS SAM to build a Java Lambda. I'm also using Gradle for the packaging.

I'm trying to use Layers to separate my dependencies and my code.

When I run gradle build in my code folder, I get a nice clean build folder with no dependency jars. This uses the packageSkinny target.

When I run gradle build in the deps folder, I get the desired result too - all my dependencies, no code. This uses the packageLibs target.

However, when I run sam build, I get a build folder that has the dependency JARs in both folders - the layer and the function.

How do I stop AWS SAM from including all my dependencies in the main function layer, and get a nice thin zip file for my compiled code?

Function Gradle file:

plugins {
    id 'java'
}

repositories {
    mavenCentral()
}

dependencies {
    implementation platform('software.amazon.awssdk:bom:2.16.60')
    implementation platform('com.amazonaws:aws-xray-recorder-sdk-bom:2.11.0')
//    implementation 'software.amazon.awssdk:lambda'
    implementation 'com.amazonaws:aws-xray-recorder-sdk-core'
    implementation 'com.amazonaws:aws-xray-recorder-sdk-aws-sdk-v2'
    implementation 'com.amazonaws:aws-xray-recorder-sdk-aws-sdk-v2-instrumentor'
    implementation 'com.amazonaws:aws-lambda-java-core:1.2.1'
    implementation 'com.amazonaws:aws-lambda-java-events:3.11.0'
    implementation 'com.google.code.gson:gson:2.8.6'
    implementation 'org.apache.logging.log4j:log4j-api:[2.17.1,)'
    implementation 'org.apache.logging.log4j:log4j-core:[2.17.1,)'
    runtimeOnly 'org.apache.logging.log4j:log4j-slf4j18-impl:[2.17.1,)'
    runtimeOnly 'com.amazonaws:aws-lambda-java-log4j2:1.5.0'
    testImplementation 'junit:junit:4.13.2'
//    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.0'
}

task packageFat(type: Zip) {
    from compileJava
    from processResources
    into('lib') {
        from configurations.runtimeClasspath
    }
    dirMode = 0755
    fileMode = 0755
}

task packageLibs(type: Zip) {
    into('java/lib') {
        from configurations.runtimeClasspath
    }
    dirMode = 0755
    fileMode = 0755
}

task packageSkinny(type: Zip) {
    from compileJava
    from processResources
}

sourceCompatibility = 11
targetCompatibility = 11

build.dependsOn packageSkinny

SAM Template:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  HelloWorld

  Sample SAM Template for HelloWorld

Globals:
  Function:
    Timeout: 20

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: HelloWorldFunction
      Handler: HelloWorld.Handler::handleRequest
      Runtime: java11
      Description: Handler to process and encode the voice print
      Architectures:
        - arm64
      MemorySize: 512
      Policies:
        - AWSLambdaBasicExecutionRole
        - AWSLambda_ReadOnlyAccess
        - AWSXrayWriteOnlyAccess
        - AWSLambdaVPCAccessExecutionRole
      Tracing: Active
      Layers:
        - !Ref libs
  libs:
    Type: AWS::Serverless::LayerVersion
    Properties:
      ContentUri: layers
      Description: Dependencies for the HelloWorld function
      LayerName: HelloWorld-lib
      CompatibleRuntimes:
        - java11
      CompatibleArchitectures:
        - arm64
    Metadata:
      BuildMethod: java11
      BuildArchitecture: arm64

Outputs:
  HelloWorldFunction:
    Description: "Lambda Function ARN"
    Value: !GetAtt HelloWorldFunction.Arn

Folder structure:

❯ tree
.
├── README.md
├── events
│   └── event.json
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── layers
│   └── build.gradle
├── out.json
├── HelloWorldFunction
│   ├── build.gradle
│   └── src
│       ├── main
│       │   └── java
│       │       └── HelloWorld
│       │           └── Handler.java
│       └── test
│           └── java
│               └── HelloWorld
│                   ├── AppTest.java
│                   ├── TestContext.java
│                   └── TestLogger.java
├── samconfig.toml
└── template.yaml

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文