Gradle多项目Spring Boot:验收测试模块依赖核心可执行Jar配置
Got it, let's sort out this Gradle automation for your acceptance tests. Here's a step-by-step setup that will handle building the core jar, copying it to your acceptance module, starting the service, running tests, and cleaning up automatically:
Step 1: Configure the Core Module
First, make sure your client-stp-grid-publisher-core/build.gradle is set up to generate the executable Spring Boot jar (the bootJar task replaces the older bootRepackage in modern Spring Boot Gradle plugins):
plugins { id 'org.springframework.boot' version '3.2.0' // Use your project's Spring Boot version id 'java' } // Optional: Customize the jar name for easier reference later bootJar { archiveFileName = "core-service.jar" }
Step 2: Wire Up the Acceptance Test Module
In client-stp-grid-publisher-acceptance/build.gradle, we'll add tasks to copy the core jar, start the service, run tests, and stop the service.
2.1 Declare Dependencies on the Core Jar
First, add a configuration to pull in the core module's executable jar:
plugins { id 'java' id 'org.springframework.boot' version '3.2.0' apply false // Only if you need Spring dependencies for tests } configurations { coreExecutableJar } dependencies { // Pull in the core module's bootJar artifact coreExecutableJar project(path: ':client-stp-grid-publisher-core', configuration: 'bootArchives') // Add your acceptance test dependencies here testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.1' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.10.1' testImplementation 'org.springframework.boot:spring-boot-test' }
2.2 Copy the Core Jar to the Acceptance Module
Create a task to copy the core jar to a dedicated directory in the acceptance module:
task copyCoreJar(type: Copy) { from configurations.coreExecutableJar into "${buildDir}/core-service" // Target directory for the jar rename { "core-service.jar" } // Ensure consistent naming }
2.3 Start the Core Service
Create a task to launch the executable jar in the background, and track its PID for cleanup:
task startCoreService(type: Exec) { dependsOn copyCoreJar workingDir "${buildDir}/core-service" commandLine 'java', '-jar', 'core-service.jar', '--spring.profiles.active=test' // Add any test-specific config here // Redirect service logs to a file for debugging standardOutput = new FileOutputStream("${buildDir}/core-service/service.log") errorOutput = standardOutput // Run the service in the background ignoreExitValue = true // Save the service PID to a file for later shutdown doLast { // Find the PID of the started service ProcessHandle serviceProcess = ProcessHandle.current().children() .find { it.info().command().orElse("").contains("core-service.jar") } if (serviceProcess != null) { new File("${buildDir}/core-service/service.pid").text = serviceProcess.pid() println "Core service started with PID: ${serviceProcess.pid()}" } else { throw new GradleException("Failed to find core service process") } } }
2.4 Stop the Core Service
Create a task to stop the service after tests finish, with cross-platform support:
task stopCoreService(type: Exec) { def pidFile = new File("${buildDir}/core-service/service.pid") onlyIf { pidFile.exists() } def servicePid = pidFile.text.trim() // Handle Windows and Unix-like systems if (System.getProperty('os.name').toLowerCase().contains('windows')) { commandLine 'taskkill', '/F', '/PID', servicePid } else { commandLine 'kill', servicePid } doLast { pidFile.delete() println "Core service stopped" } }
2.5 Tie Everything to the Test Task
Configure the acceptance test task to depend on starting the service, wait for it to be ready, and clean up afterward:
test { dependsOn startCoreService finalizedBy stopCoreService // Wait for the service to be fully operational before running tests doFirst { def healthCheckUrl = "http://localhost:8080/actuator/health" // Replace with your service's health endpoint def maxWaitSeconds = 30 def attempts = 0 println "Waiting for core service to start..." while (attempts < maxWaitSeconds) { try { new URL(healthCheckUrl).openConnection().with { connectTimeout = 1000 readTimeout = 1000 if (responseCode == 200) { println "Core service is ready!" break } } } catch (Exception e) { // Service not yet available, keep waiting } attempts++ sleep(1000) } if (attempts >= maxWaitSeconds) { throw new GradleException("Core service failed to start within ${maxWaitSeconds} seconds") } } // Use JUnit Platform for tests (adjust if you use a different framework) useJUnitPlatform() }
How It Works
Now when you run:
./gradlew :client-stp-grid-publisher-acceptance:test
Gradle will automatically:
- Build the core module's executable jar
- Copy the jar to the acceptance module's build directory
- Start the core service in the background
- Wait for the service to be healthy
- Run all acceptance tests
- Stop the core service once tests complete (even if tests fail)
内容的提问来源于stack exchange,提问作者Shashi Shankar

