如何在IntelliJ中调试Gradle Worker Daemon?遇端口占用报错
问题背景
我在自定义Gradle任务中使用Worker Daemon实现并行处理。
Worker API可通过
processIsolation()方法将任务在独立的worker daemon中执行,这些进程会跨构建保留并可在后续构建中复用,当系统资源不足时Gradle会停止闲置的worker daemon。请注意,这与Gradle Daemon并非同一概念。
使用环境:Gradle 7.5.1、IntelliJ IDEA 2022.3.2(旗舰版)
基础实现示例 - GenerateMD5 WorkAction
基于Gradle文档示例,用Apache Commons Codec实现生成MD5的任务,代码如下:
// build.gradle.kts import org.apache.commons.codec.digest.DigestUtils buildscript { repositories { gradlePluginPortal() mavenCentral() } dependencies { classpath("commons-codec:commons-codec:1.15") } } plugins { `java-library` } repositories { gradlePluginPortal() mavenCentral() } abstract class GenerateMD5 : WorkAction<GenerateMD5.Parameters> { interface Parameters : WorkParameters { val sourceFile: RegularFileProperty val md5File: RegularFileProperty } override fun execute() { val sourceFile = parameters.sourceFile.asFile.get() val md5File = parameters.md5File.asFile.get() val md5Hex = DigestUtils.md5Hex(sourceFile.inputStream()) println("Generated MD5 for ${sourceFile.name}: $md5Hex") md5File.writeText(md5Hex) } } dependencies { implementation("commons-codec:commons-codec:1.15") } abstract class CreateMD5 : DefaultTask() { @get:InputFiles abstract val source: ConfigurableFileCollection @get:Classpath abstract val codecClasspath: ConfigurableFileCollection @get:OutputDirectory abstract val destinationDirectory: DirectoryProperty @get:Inject protected abstract val workerExecutor: WorkerExecutor @TaskAction fun createHashes() { val workQueue: WorkQueue = workerExecutor.processIsolation { classpath.from(codecClasspath) forkOptions { maxHeapSize = "64m" //debug = true } } source.files.forEach { file -> workQueue.submit(GenerateMD5::class) { sourceFile.set(file) md5File.set(destinationDirectory.file("${file.name}.md5")) } } } } val createMd5 by tasks.registering(CreateMD5::class) { group = "md5" codecClasspath.from(configurations.runtimeClasspath) destinationDirectory.set(temporaryDir) source.from( resources.text.fromString( """ blah blah some file """.trimIndent() ) ) }
非调试模式运行正常
执行./gradlew createMd5,任务成功完成:
Executing 'createMd5'... > Task :createMd5 Generated MD5 for string12197505505076104021.txt: 7a55d3ab41f37979cd7cccc92b7fc8fa BUILD SUCCESSFUL in 866ms 1 actionable task: 1 executed Execution finished 'createMd5'.
调试模式运行报错
启用worker的调试选项:
@TaskAction fun createHashes() { val workQueue: WorkQueue = workerExecutor.processIsolation { classpath.from(codecClasspath) forkOptions { maxHeapSize = "64m" debug = true // 启用调试 } } // ... }
在DigestUtils.java设置断点后,用IntelliJ调试运行任务,出现以下错误:
Executing 'createMd5'... Starting Gradle Daemon... Connected to the target VM, address: '127.0.0.1:59032', transport: 'socket' Gradle Daemon started in 1 s 460 ms ERROR: transport error 202: bind failed: Address already in use ERROR: JDWP Transport dt_socket failed to initialize, TRANSPORT_INIT(510) JDWP exit error AGENT_ERROR_TRANSPORT_INIT(197): No transports initialized [./src/jdk.jdwp.agent/share/native/libjdwp/debugInit.c:735] Could not write standard input to Gradle Worker Daemon 1. java.io.IOException: Broken pipe at java.base/java.io.FileOutputStream.writeBytes(Native Method) at java.base/java.io.FileOutputStream.write(FileOutputStream.java:354) at java.base/java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:81) at java.base/java.io.BufferedOutputStream.flush(BufferedOutputStream.java:142) at org.gradle.process.internal.streams.ExecOutputHandleRunner.forwardContent(ExecOutputHandleRunner.java:68) at org.gradle.process.internal.streams.ExecOutputHandleRunner.run(ExecOutputHandleRunner.java:53) at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64) at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at java.base/java.lang.Thread.run(Thread.java:829) > Task :createMd5 FAILED 1 actionable task: 1 executed FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':createMd5'. > A failure occurred while executing Build_gradle$GenerateMD5 > Failed to run Gradle Worker Daemon > Process 'Gradle Worker Daemon 1' finished with non-zero exit value 2 * Try: > Run with --stacktrace option to get the stack trace. > Run with --info or --debug option to get more log output. > Run with --scan to get full insights. * Get more help at https://help.gradle.org BUILD FAILED in 6s Disconnected from the target VM, address: '127.0.0.1:59032', transport: 'socket' Execution finished 'createMd5'.
已尝试的无效解决方法
- 执行
./gradlew --stop终止Gradle Daemon,无效 - 执行
pkill -f '.*GradleDaemon.*'杀死Gradle Daemon进程,无效
需求
寻求在IntelliJ中调试Gradle Worker Daemon的正确方法,以及解决上述端口占用报错的方案。
内容的提问来源于stack exchange,提问作者aSemy
相关产品推荐
相关产品推荐

