본문 바로가기
Old Posts/Java

[Java] 원격 디버깅 사용하기 (IntelliJ, Eclipse)

by A6K 2021. 5. 5.

자바로 만들어진 프로그램은 JVM을 통해서 실행이 된다. JVM은 '원격 디버깅(Remote Debugging)'이라는 매우 편리하면서 강력한 기능을 제공한다. 원격 디버깅 기능을 이용해서 로컬 머신이 아닌 서버에서 동작하는 자바 프로그램을 IntelliJ, Eclipase 같은 IDE를 통해 원격으로 디버깅할 수 있다.

이번 포스트에서는 도커(Docker)를 이용해 컨테이너 환경에서 자바 프로그램을 구동한 다음 호스트 머신에서 원격 디버깅으로 도커 컨테이너 안쪽에서 동작하는 자바 프로그램을 원격 디버깅해보겠다. 도커가 아닌 다른 머신에서 구동하는 자바 프로그램에 대한 원격 디버깅도 크게 다르지 않을 것이다.

실행할 자바 프로그램

우선 다음 자바 프로그램을 도커 컨테이너에서 실행해보자.

public class Test {
   public static void main(String[] args) {
      for (int i = 0; i < 100; i++) {
         System.out.println("Hello, World - " + i);
      }
   }
}

"Hello, World"라는 문자열을 100번 출력하는 간단한 프로그램이다. 이 소스코드를 컴파일해서 Test.class 혹은 jar 파일로 만들자. (javac를 이용하거나 IDE의 기능을 이용하면 된다.)

도커 컨테이너 구동

이 프로그램을 구동할 도커 이미지를 만들자. 다음 '도커파일(Dockerfile)'을 이용해서 도커 이미지를 만들자.

FROM openjdk:8
COPY Test.class /root
WORKDIR /root
EXPOSE 5005
ENTRYPOINT ["java", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005", "Test"]

아까 만들었던 Test.class 파일 혹은 jar 파일이 위치한 경로에서 다음 명령으로 도커 이미지를 만들어준다.

docker build . --tag test_container

이 명령을 실행하면 Test.class 파일을 컨테이너 안쪽으로 복사한다. 복사하는 위치는 컨테이너 환경의 /root 디렉토리 밑이다. (만약 jar 파일로 만들었다면 Test.class 대신 jar 파일 이름을 입력해준다)

이제 만들어진 이미지를 실행하자.

docker run -d -p 5005:5005 test_container

도커에 대해서 모르는 분들을 위해 잠깐 설명하자면, 이 명령은 test_container라고 만들어진 이미지를 실행한다. 이 때, 컨테이너의 5005번 포트를 호스트 머신의 5005번 포트로 포트포워딩(Port Forwarding) 해준다. 호스트 머신의 5005번 포트로 들어오는 요청들은 컨테이너의 5005번 포스토 전달된다.

docker run을 하면 도커파일에서 봤던 ENTRYPOINT 명령이 실행된다. 실행되는 명령을 다시 적어보면

java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005 Test

이런 명령어가 실행되는 것이다. 자바로 Test 프로그램을 실행시키되 5005번 포트로 디버거 연결을 기다리라는 옵션들이다. 자바 프로그램은 바로 실행되지 않고, 5005번 포트에 원격 디버거가 연결될 때까지 기다린다.

IntelliJ 원격 디버거 설정

IntelliJ에서 Test.java 파일을 포함한 프로젝트를 오픈한다. 프로젝트가 생성되고 [Run] -> [Edit Configurations] 메뉴로 들어간다. 

인텔리J 원격 디버깅 설정

왼쪽에 있는 '+' 버튼을 눌러서 Remote를 선택한다.

인텔리J 원격 디버깅 설정

원격 디버거 설정이다. Host Port에 디버깅할 JVM이 떠있는 주소를 입력한다. 도커를 이용해서 로컬에 컨테이너를 띄웠고, 5005번 포트로 연결해놨으므로 localhost5005 포트를 입력하면 된다.

'Command line arguments for remote JVM'에 아까 도커 이미지에서 사용했던 옵션을 넣어주면 된다. 마지막으로 OK 버튼을 눌러서 진행한다.

인텔리J 원격 디버깅 설정 - 소소코드 브레이크 포인트

로컬에서 디버깅하는 것처럼 브레이크 포인트를 걸어두고 실행할 수 있다.

이제 디버깅 버튼을 눌러서 디버깅을 진행하면 된다. 인텔리J에서 원격 디버거로 붙으면 로컬에서 실행하는 것처럼 소스코드를 보면서 디버깅할 수 있다. 원격에서 디버거의 접속을 기다리던 프로그램은 인텔리J에서 원격 디버거로 붙게 되면 실행을 시작한다.

Eclipse 원격 디버거

이클립스에서도 비슷하게 원격 디버깅 기능을 제공한다.

[Run] -> [Debug Configuration]으로 들어가서 [Remote Java Application] 항목에서 우클릭을 한다. "New Configuration"을 선택하면 새로운 리모트 디버깅 설정이 생긴다.

Host 항목에 localhost를 입력하고 Port 정보에 5005를 입력한 다음 "apply" 버튼을 클릭하고, 브레이크 포인트를 설정한 다음 로컬에서처럼 디버깅을 시작하면 된다.

댓글