如何在intellij idea中调试JDK docker容器?

How to debug a JDK docker container in intellij idea?

我想用如下调试选项启动一个 docker 容器,但启动不成功:

Dockerfile:

# syntax=docker/dockerfile:1
FROM maven:3-eclipse-temurin-11 as dependencies
WORKDIR /opt/app
COPY .dockerdev/settings.xml .
COPY pom.xml .
COPY src src
ENTRYPOINT["mvn", "spring-boot:run"]

docker-compose.yml:

version: '3.7'
services:
  app:
    environment:
      - "JAVA_TOOL_OPTIONS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005"
    ports:
      - 8080:8080
      - 5005:5005
      

结果:

docker-compose up
Recreating my_app ... done
Attaching to my_app
app_1  | Picked up JAVA_TOOL_OPTIONS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005
app_1  | Listening for transport dt_socket at address: 5005
app_1  | [INFO] Scanning for projects...
app_1  | [INFO] --- maven-resources-plugin:3.2.0:resources (default-resources) @ my_app ---
app_1  | [INFO] Using 'UTF-8' encoding to copy filtered resources.
app_1  | [INFO] Using 'UTF-8' encoding to copy filtered properties files.
app_1  | [INFO] Copying 3 resources
app_1  | [INFO] Copying 3 resources
app_1  | [INFO] 
app_1  | [INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ my_app ---
app_1  | [INFO] Changes detected - recompiling the module!
app_1  | [INFO] 
app_1  | [INFO] --- maven-resources-plugin:3.2.0:testResources (default-testResources) @ my_app ---
app_1  | [INFO] Using 'UTF-8' encoding to copy filtered resources.
app_1  | [INFO] Using 'UTF-8' encoding to copy filtered properties files.
app_1  | [INFO] Copying 3 resources
app_1  | [INFO] 
app_1  | [INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ my_app ---
app_1  | [INFO] Changes detected - recompiling the module!
app_1  | [INFO] Compiling 5 source files to /opt/app/target/test-classes
app_1  | [INFO] 
app_1  | [INFO] <<< spring-boot-maven-plugin:2.6.7:run (default-cli) < test-compile @ my_app <<<
app_1  | [INFO] 
app_1  | [INFO] 
app_1  | [INFO] --- spring-boot-maven-plugin:2.6.7:run (default-cli) @ my_app ---
app_1  | [INFO] Attaching agents: []
app_1  | Picked up JAVA_TOOL_OPTIONS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005
app_1  | ERROR: transport error 202: bind failed: Address already in use
app_1  | ERROR: JDWP Transport dt_socket failed to initialize, TRANSPORT_INIT(510)
app_1  | JDWP exit error AGENT_ERROR_TRANSPORT_INIT(197): No transports initialized [./src/jdk.jdwp.agent/share/native/libjdwp/debugInit.c:735]
app_1  | [INFO] ------------------------------------------------------------------------
app_1  | [INFO] BUILD FAILURE
app_1  | [INFO] ------------------------------------------------------------------------
app_1  | [INFO] Total time:  3.000 s
app_1  | [INFO] Finished at: 2022-05-23T12:30:50Z
app_1  | [INFO] ------------------------------------------------------------------------
app_1  | [ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.6.7:run (default-cli) on project my_app: Application finished with exit code: 2 -> [Help 1]
app_1  | [ERROR] 
app_1  | [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
app_1  | [ERROR] Re-run Maven using the -X switch to enable full debug logging.
app_1  | [ERROR] 
app_1  | [ERROR] For more information about the errors and possible solutions, please read the following articles:
app_1  | [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
my_app exited with code 1

旁注:端口 5005 当然 不是 running/listening 在我的主机上! 另外,如果我将端口更改为 5006、5007 等,错误始终相同。

那么为什么 mvn spring-boot:run 上的端口被阻止了?

您的解决方案的问题是启动了 2 个调试会话。 1 个用于 maven 命令,1 个用于分叉的 JVM voor Spring Boot。因此错误和更改端口不会解决这个问题,因为问题仍然存在。

您需要做的是从 docker 撰写文件中删除 JAVA_TOOL_OPTIONS,然后将以下内容添加到您的入口点

-Dspring-boot.run.jvmArguments=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005

这样它将仅适用于 Spring 引导插件,并且在新的 JVM 中启动应用程序时将被考虑在内。