You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 23:05:27