在Gradle Java项目中运行Dynamodb本地实例

15
我想为测试目的运行DynamoDB本地版本。我遵循了亚马逊提供的设置步骤,并且单独运行jar文件可以正常工作(链接到亚马逊教程Here)。然而,该教程没有介绍如何在项目中运行jar文件。我不希望其他开发人员每次测试其代码时都必须获取jar文件并在本地运行它。
这就是我的问题所在。我一直在网上寻找如何配置Gradle项目以在我的测试中运行DynamoDB本地服务器的示例,但是一直没有找到。我找到了下面的maven示例https://github.com/awslabs/aws-dynamodb-examples/blob/master/src/test/java/com/amazonaws/services/dynamodbv2/DynamoDBLocalFixture.java#L32并尝试将其转换为Gradle,但是他们使用的所有com.amazonaws.services.dynamodbv2.local导入语句都出现错误,错误是资源找不到。
我进入了他们项目的pom文件并将以下内容放入了我的build.gradle文件中以进行模拟。
//dynamodb local dependencies
testCompile('com.amazonaws:aws-java-sdk-dynamodb:1.10.42')
testCompile('com.amazonaws:aws-java-sdk-cloudwatch:1.10.42')
testCompile('com.amazonaws:aws-java-sdk:1.3.0')
testCompile('com.amazonaws:amazon-kinesis-client:1.6.1')
testCompile('com.amazonaws:amazon-kinesis-connectors:1.1.1')
testCompile('com.amazonaws:dynamodb-streams-kinesis-adapter:1.0.2')
testCompile('com.amazonaws:DynamoDBLocal:1.10.5.1')
导入语句仍然失败。这是一个失败的示例。
import com.amazonaws.services.dynamodbv2.local.embedded.DynamoDBEmbedded;

有人能够将DynamoDB本地JAR作为Gradle项目的一部分执行,或者有一个好的教程链接吗?(它不必是我提供的那个链接的教程)。

简而言之:


我意识到,如果我能让gradle运行以下命令,就可以解决我的问题: java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar -sharedDb - OrwellHindenberg
7个回答

24

我们已经将本地 DynamoDB 和 Gradle 集成起来了。以下是您需要在 gradle.build 文件中添加的内容:

对于 gradle 4.x 及以下版本

1)在仓库部分添加:

    maven {
        url 'http://dynamodb-local.s3-website-us-west-2.amazonaws.com/release'
    }

2) 在依赖项部分添加以下内容(假设您将其用于测试):

    testCompile group: 'com.amazonaws', name: 'DynamoDBLocal', version: 1.11.0

3) 接下来的两个步骤比较棘手。首先将本地文件复制到一个目录中:

task copyNativeDeps(type: Copy) {
    from (configurations.testCompile) {
        include "*.dylib"
        include "*.so"
        include "*.dll"
    }
    into 'build/libs'
}

4) 然后,确保在Java库路径中包含此目录(在我们的情况下是build/libs),如下所示:

test.dependsOn copyNativeDeps
test.doFirst {
    systemProperty "java.library.path", 'build/libs'
}

现在你应该能够运行./gradlew test并使你的测试命中本地DynamoDB。


谢谢你的回答,Serega。我已经不再从事这个项目了,所以测试和验证你的答案需要一些时间... - OrwellHindenberg
没问题。希望这对其他遇到类似问题的人有所帮助。 - Serega
我在哪里可以获取最新版本的DynamoDBLocal...我已经设置了一个Gradle项目并使用1.11.0版本 - 请回复。 - Abdeali Chandanwala
1
http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.html - Serega

8

对于Gradle 5.x,以下解决方案有效:

 maven {
        url 'http://dynamodb-local.s3-website-us-west-2.amazonaws.com/release'
    }

configurations {
        dynamodb
    }

dependencies {
    testImplementation 'com.amazonaws:DynamoDBLocal:1.11.477'
    dynamodb fileTree (dir: 'lib', include: ["*.dylib", "*.so", "*.dll"])
    dynamodb 'com.amazonaws:DynamoDBLocal:1.11.477'
}

task copyNativeDeps(type: Copy) {
    from configurations.dynamodb
    into "$project.buildDir/libs/"
}

test.dependsOn copyNativeDeps
test.doFirst {
    systemProperty "java.library.path", 'build/libs'
}

如果你想从Gradle 5升级,这也适用于Gradle 6.0.1。 - RBrink
如果你在使用Gradle时遇到了找不到依赖的问题,请参考:https://dev59.com/obH3oIgBc1ULPQZFONgj - BRasmussen

4

我遇到了同样的问题,首先我尝试在Gradle脚本中添加sqlite4java.library.path,正如其他评论中提到的那样。

这对于命令行是有效的,但当我从IDE(IntelliJ IDEA)运行测试时却无效,所以最终我想出了一个简单的初始化方法,在每个集成测试的开始处调用:

AwsDynamoDbLocalTestUtils.initSqLite();
AmazonDynamoDBLocal amazonDynamoDBLocal = DynamoDBEmbedded.create();

这里可以找到实现方法:https://github.com/redskap/aws-dynamodb-java-example-local-testing/blob/master/src/test/java/io/redskap/java/aws/dynamodb/example/local/testing/AwsDynamoDbLocalTestUtils.java 我在GitHub上提供了一个完整的示例,可能会有所帮助:https://github.com/redskap/aws-dynamodb-java-example-local-testing

3
2018年8月,亚马逊宣布新的Docker镜像上搭载了Amazon DynamoDB Local。使用该镜像无需下载和运行任何JAR文件,也无需添加使用第三方特定于操作系统的二进制文件,如sqlite4java
只需在测试之前启动Docker容器即可,非常简单:
docker run -p 8000:8000 amazon/dynamodb-local

您可以按照上述说明手动进行本地开发,或在CI流水线中使用它。许多CI服务提供了在流水线期间启动额外容器的功能,这些容器可以为您的测试提供依赖项。以下是Gitlab CI/CD的示例:

test:
  stage: test
  image: openjdk:8-alpine
  services:
    - name: amazon/dynamodb-local
      alias: dynamodb-local
  script:
    - ./gradlew clean test

因此,在 测试 任务期间,DynamoDB 将在 http://dynamodb-local:8000 上可用。

另一个更强大的工具是 localstack。它支持两打 AWS 服务之一就是 DynamoDB。使用方法非常相似,您需要在运行测试之前启动它,它将在 给定端口 上公开与 AWS 兼容的 API:

test:
  stage: test
  image: openjdk:8-alpine
  services:
    - name: localstack/localstack
    alias: localstack
  script:
    - ./gradlew clean test

这个想法是将所有配置从构建工具和测试中移出,并在外部提供依赖项。把它看作依赖注入 / 控制反转,但不仅限于单个 bean,而是整个服务。这样,你的代码更加清晰易维护。你可以看到,即使在上面的例子中,你只需简单地更改image部分,就可以从 DynamoDB Local 切换到 localstack 的模拟实现!

1

1
链接可能会失效,最好编辑您的答案以包含获取jar文件或类似内容的路径。 - cst1992

1
我不想为Gradle 6+创建一个特定的Dynamo配置,因此我调整了原始答案的说明。此外,这是使用Kotlin Gradle DSL而非Groovy。
val copyNativeDeps by tasks.creating(Copy::class) {
    from(configurations.testRuntimeClasspath) {
        include("*.dylib")
        include("*.so")
        include("*.dll")
    }
    into("$buildDir/libs")
}

tasks.withType<Test> {
    dependsOn.add(copyNativeDeps)
    doFirst { systemProperty("java.library.path", "$buildDir/libs") }
}

通过利用testRuntimeClasspath配置,Gradle能够为您定位相关文件,而无需创建自定义配置。显然,这会导致一个副作用,即如果您的测试运行时有许多本地依赖项,它们也将被复制,这将使自定义配置方法更加理想。

0

Gradle 8 解决方案

借鉴 @togise 的解决方案并与 另一个 Stack Overflow 问题配对使用。

// ... Source set, plugins...

// Define a custom configuration set to allow us to configure DynamoDb local.
configurations {
    dynamoDbLocal
}


repositories {
    mavenCentral()
    // Add another Maven source
    maven {
        name "DynamoDB Local Release Repository"
        url "https://s3-us-west-2.amazonaws.com/dynamodb-local/release"
    }
}

dependencies {
    // Adds a locally running DynamoDB instance
    testImplementation 'com.amazonaws:DynamoDBLocal:2.0.0'
    configurations.dynamoDbLocal { fileTree(dir: 'lib', include: ["*.dylib", "*.so", "*.dll"]) }
    configurations.dynamoDbLocal { 'com.amazonaws:DynamoDBLocal:2.0.0' }

    // Other dependencies...
}

// Register a new Gradle task that may be called by others tasks
tasks.register('copyNativeDeps', Copy) {
    from configurations.dynamoDbLocal
    into "$project.buildDir/libs/"
}

test {
    // These two statements are required to set up DynamoDb local
    dependsOn copyNativeDeps
    doFirst {
        systemProperty "java.library.path", 'build/libs'
    }

    // Other test configuration, like useJUnitPlatform()
}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接