Intellij Idea 如何在IntelliJ中调试Gradle Worker守护进程?

oymdgrw7  于 2023-02-18  发布在  其他
关注(0)|答案(1)|浏览(207)

我在自定义任务中使用Gradle Worker守护进程来支持并行工作。
Worker API可以使用processIsolation()方法来实现这一点,该方法可使工作在单独的“worker守护进程”中执行。这些worker守护进程将在构建期间持续存在,并可在后续构建期间重用。但是,如果系统资源不足,Gradle将停止任何未使用的worker守护进程。
请注意,这与Gradle Daemon不同。
我使用的是Gradle 7.5.1和IntelliJ IDEA 2022.3.2(终极版)。

基本示例-生成MD5工作操作

我在Worker Daemon文档中重新创建了一个基本示例,它将基于Gradle文档中的示例生成MD5文件。
例外的是,我使用外部库ApacheCommonsCodec来生成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'.

运行调试

然后,我尝试启用调试模式:

@TaskAction
  fun createHashes() {
    val workQueue: WorkQueue = workerExecutor.processIsolation {
      classpath.from(codecClasspath)
      forkOptions {
        maxHeapSize = "64m"
        debug = true // enable debug
      }
    }
   // ...

我在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'.

次尝试

我试过杀死Gradle守护程序

./gradlew --stop

但没有效果。
我还尝试过杀死Gradle守护程序

pkill -f '.*GradleDaemon.*';

但这也不起作用。

ltskdhd1

ltskdhd11#

请尝试将远程调试器附加到正在运行的gradlew命令。https://docs.gradle.org/current/userguide/troubleshooting.html#sec:troubleshooting_build_logic

相关问题