1. 소개

디버깅은 소프트웨어 작성을 위한 가장 중요한 도구 중 하나입니다.

이 사용방법(예제)에서는 Spring 애플리케이션을 디버깅할 수 있는 몇 가지 방법을 검토합니다.

또한 Spring Boot, 기존 애플리케이션 서버 및 IDE가 이를 단순화하는 방법도 보여줍니다.

2. Java 디버그 인수

먼저 Java가 즉시 제공하는 기능을 살펴보겠습니다.

기본적으로 JVM은 디버깅을 활성화하지 않습니다 . 이는 디버깅이 JVM 내부에 추가 오버헤드를 생성하기 때문입니다. 또한 공개적으로 액세스할 수 있는 응용 프로그램에 대한 Security 문제가 될 수 있습니다.

따라서 디버깅은 개발 중에만 수행해야 하며 프로덕션 시스템에서는 수행해서는 안 됩니다.

디버거를 연결하기 전에 먼저 디버깅을 허용하도록 JVM을 구성해야 합니다. JVM에 대한 명령줄 인수를 설정하여 이를 수행합니다.

-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000

각 값의 의미를 분석해 보겠습니다.

-에이전트립:jdwp

그러면 JVM 내에서 JDWP(Java Debug Wire Protocol) 에이전트가 활성화됩니다. 이것은 디버깅을 가능하게 하는 기본 명령줄 인수입니다.

수송=dt_socket

이것은 디버그 연결을 위해 네트워크 소켓을 사용합니다. 다른 옵션으로는 Unix 소켓과 공유 메모리가 있습니다.

서버=y

들어오는 디버거 연결을 수신 대기합니다. n 으로 설정 하면 프로세스는 들어오는 연결을 기다리는 대신 디버거에 연결을 시도합니다. 이것이 n 으로 설정된 경우 추가 인수가 필요합니다 .

정지=n

이는 시작 시 디버그 연결을 기다리지 않음을 의미합니다. 응용 프로그램은 디버거가 연결될 때까지 정상적으로 시작되고 실행됩니다. y 로 설정하면 디버거가 연결될 때까지 프로세스가 시작되지 않습니다.

주소=8000

이것은 JVM이 디버그 연결을 위해 청취할 네트워크 포트입니다.

위의 값은 표준이며 대부분의 사용 사례 및 운영 체제에서 작동합니다. JPDA 연결 사용방법(예제)가능한 모든 값을 더 자세히 다룹니다.

2.1. JDK9+의 바인딩 주소

JDK8 이하에서 address 속성을 포트 번호로만 설정하면(위의 예에서 address=8000) JVM이 사용 가능한 모든 IP 주소에서 수신 대기함을 의미합니다. 따라서 즉시 원격 연결을 사용할 수 있습니다.

이는 Security상의 이유로 JDK9+에서 변경되었습니다. 현재 기본 설정은 localhost 연결만 허용합니다.

즉, 원격 연결을 사용 가능하게 하려면 포트 번호 앞에 호스트 이름 address =myhost:8000을 붙이거나 별표를 사용하여 사용 가능한 모든 IP 주소 address =*:8000을 수신 대기해야 합니다.

3. 스프링 부트 애플리케이션

Spring Boot 애플리케이션을 시작 하는 방법에는 여러 가지가 있습니다 . 가장 간단한 방법은 명령줄에서 java 명령을 -jar 옵션과 함께 사용하는 것입니다.

디버깅을 활성화하려면 -D 옵션 을 사용하여 디버그 인수를 추가하기만 하면 됩니다 .

java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000 -jar myapp.jar

Maven을 사용하면 제공된 실행 목표를 사용하여 디버깅이 활성화된 상태에서 애플리케이션을 시작할 수 있습니다.

mvn spring-boot:run -Dspring-boot.run.jvmArguments="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000"

마찬가지로 Gradle을 사용하면 bootRun 작업을 사용할 수 있습니다. 먼저 Gradle이 JVM에 명령줄 인수를 전달하도록 build.gradle 파일을 업데이트해야 합니다.

bootRun {
   systemProperties = System.properties
}

이제 bootRun 작업을 실행할 수 있습니다.

gradle bootRun -Dagentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000

4. 애플리케이션 서버

최근 몇 년 동안 Spring Boot가 매우 인기를 얻었지만 전통적인 애플리케이션 서버 는 여전히 최신 소프트웨어 아키텍처에서 널리 보급되어 있습니다. 이 섹션에서는 널리 사용되는 일부 애플리케이션 서버에 대해 디버그를 활성화하는 방법을 살펴보겠습니다.

대부분의 애플리케이션 서버는 애플리케이션 시작 및 중지를 위한 스크립트를 제공합니다. 디버그를 활성화하는 것은 일반적으로 이 스크립트에 추가 인수를 추가하거나 추가 환경 변수를 설정하는 문제입니다.

4.1. 수코양이

Tomcat 의 시작 스크립트 이름은 catalina.sh ( Windows의 경우 catalina.bat)입니다 . 디버그가 활성화된 상태에서 Tomcat 서버를 시작하려면 jpda 를 인수 앞에 추가할 수 있습니다 .

catalina.sh jpda start

기본 디버그 인수는 suspend=n 으로 포트 8000에서 청취하는 네트워크 소켓을 사용합니다 . JPDA_TRANSPORT , JPDA_ADDRESSJPDA_SUSPEND 환경 변수 중 하나 이상을 설정하여 변경할 수 있습니다 .

JPDA_OPTS 를 설정하여 디버그 인수를 완전히 제어할 수도 있습니다 . 이 변수가 설정되면 다른 JPDA 변수보다 우선합니다. 따라서 JVM에 대한 완전한 디버그 인수여야 합니다.

4.2. 들파리

Wildfly 의 시작 스크립트 stand-alone.sh 입니다. 디버그가 활성화된 Wildfly 서버를 시작하려면 –debug 를 추가할 수 있습니다 .

기본 디버그 모드는 suspend=n 인 포트 8787에서 네트워크 수신기를 사용합니다 . –debug 인수 뒤에 포트를 지정하여 포트를 재정의할 수 있습니다 .

디버그 인수에 대한 더 많은 제어를 위해 전체 디버그 인수를 JAVA_OPTS 환경 변수에 추가할 수 있습니다.

4.3. 웹로직

Weblogic의 시작 스크립트는 startWeblogic.sh 입니다. 디버그가 활성화된 Weblogic 서버를 시작하려면 환경 변수 debugFlagtrue 로 설정할 수 있습니다 .

기본 디버그 모드는 suspend=n 인 포트 8453에서 네트워크 수신기를 사용합니다 . DEBUG_PORT 환경 변수 를 설정하여 포트를 재정의할 수 있습니다 .

디버그 인수에 대한 더 많은 제어를 위해 전체 디버그 인수를 JAVA_OPTIONS 환경 변수에 추가할 수 있습니다.

최신 버전의 Weblogic은 서버를 시작하고 중지하는 Maven 플러그인도 제공합니다. 이 플러그인은 시작 스크립트와 동일한 환경 변수를 사용합니다 .

4.4. 글래스피쉬

Glassfish의 시작 스크립트는 asadmin 입니다. 디버그가 활성화된 Glassfish 서버를 시작하려면 –debug 를 사용해야 합니다 .

asadmin start-domain --debug

기본 디버그 모드는 suspend=n 인 포트 9009에서 네트워크 수신기를 사용합니다 .

4.5.

Jetty 애플리케이션 서버는 시작 스크립트와 함께 제공되지 않습니다. 대신 Jetty 서버는 java 명령을 사용하여 시작됩니다.

따라서 디버깅을 활성화하는 것은 표준 JVM 명령줄 인수를 추가하는 것만큼 간단합니다.

5. IDE에서 디버깅

다양한 애플리케이션 유형에서 디버깅을 활성화하는 방법을 살펴보았으므로 이제 디버거 연결을 살펴보겠습니다.

모든 최신 IDE는 디버깅 지원을 제공합니다. 여기에는 디버깅이 활성화된 상태에서 새 프로세스를 시작하는 기능과 이미 실행 중인 프로세스를 디버깅하는 기능이 모두 포함됩니다.

5.1. IntelliJ

IntelliJ 는 Spring 및 Spring Boot 애플리케이션에 대한 최고 수준의 지원을 제공합니다. 디버깅은 기본 메서드가 있는 클래스로 이동하고 삼각형 아이콘을 마우스 오른쪽 단추로 클릭한 다음 디버그를 선택하는 것만큼 간단합니다 .

intellij 실행 여백 - 아이콘

프로젝트에 여러 Spring Boot 애플리케이션이 포함된 경우 IntelliJ는 대시보드 실행 도구 창을 제공합니다. 이 창을 사용하면 단일 위치에서 여러 Spring Boot 애플리케이션을 디버그할 수 있습니다.

intellij 스프링 실행 대시보드

Tomcat 또는 기타 웹 서버를 사용하는 애플리케이션의 경우 디버깅을 위한 사용자 지정 구성을 만들 수 있습니다. Run > Edit Configurations 아래 에는 가장 널리 사용되는 애플리케이션 서버에 대한 여러 템플릿이 있습니다.

intellij 실행 디버그 템플릿

마지막으로 IntelliJ를 사용하면 실행 중인 모든 프로세스에 연결하고 디버그하기가 매우 쉽습니다. 애플리케이션이 적절한 디버그 인수로 시작되는 한 IntelliJ는 애플리케이션이 다른 호스트에 있더라도 연결할 수 있습니다.

실행 /디버그 구성 화면에서 원격 템플릿을 사용하면 이미 실행 중인 애플리케이션에 연결하는 방법을 구성할 수 있습니다.

intellij 원격 디버그 구성

IntelliJ는 호스트 이름과 디버그 포트만 알면 됩니다. 편의상 디버깅하려는 애플리케이션에서 사용해야 하는 적절한 JVM 명령줄 인수를 알려줍니다.

5.2.

Eclipse에서 Spring Boot 애플리케이션을 디버그하는 가장 빠른 방법은 Package Explorer 또는 Outline에서 기본 메서드를 마우스 오른쪽 버튼으로 클릭하는 것입니다 .

이클립스 디버그 자바 애플리케이션

Eclipse의 기본 설치는 기본적으로 Spring 또는 Spring Boot를 지원하지 않습니다. 그러나 Eclipse Marketplace에는 IntelliJ에 필적하는 Spring 지원을 제공 하는 Spring Tools 애드온이 있습니다.

특히 이 애드온은 단일 위치에서 여러 Spring Boot 애플리케이션을 관리할 수 있는 Boot Dashboard를 제공합니다 .

이클립스 스프링 부트 대시보드

추가 기능은 단일 Spring Boot 애플리케이션의 디버그를 사용자 지정할 수 있는 Spring Boot 실행/디버그 구성도 제공합니다. 이 사용자 지정 보기는 표준 Java 응용 프로그램 구성 과 동일한 모든 위치에서 사용할 수 있습니다 .

로컬 또는 원격 호스트에서 이미 실행 중인 프로세스를 디버깅하려면 원격 Java 애플리케이션 구성을 사용할 수 있습니다.

eclipse ide 원격 디버그 구성

6. 도커로 디버깅하기

Docker 컨테이너 내 에서 Spring 애플리케이션을 디버깅 하려면 추가 구성이 필요할 수 있습니다. 컨테이너가 로컬에서 실행 중이고 호스트 네트워크 모드를 사용 하지 않는 경우 컨테이너 외부에서 디버그 포트에 액세스할 수 없습니다.

Docker에서 디버그 포트를 노출하는 방법에는 여러 가지가 있습니다.

docker run 명령 과 함께 –expose 를 사용할 수 있습니다 .

docker run --expose 8000 mydockerimage

Dockerfile 에 EXPOSE 지시문을 추가할 수도 있습니다 .

EXPOSE 8000

또는 Docker Compose를 사용하는 경우 YAML에 추가할 수 있습니다.

expose:
 - "8000"

7. 결론

이 기사에서는 모든 Java 애플리케이션에 대해 디버깅을 활성화하는 방법에 대해 설명했습니다.

단일 명령줄 인수를 추가하기만 하면 모든 Java 애플리케이션을 쉽게 디버깅할 수 있습니다.

우리는 또한 가장 인기 있는 IDE뿐만 아니라 Maven과 Gradle 모두에 Spring 및 Spring Boot 애플리케이션 디버깅을 더욱 쉽게 해주는 특수 추가 기능이 있다는 것도 알게 되었습니다.

Generic footer banner