|
Components Debugger Interfaces / |--------------| / | VM | debuggee -----( |--------------| <---- JVMTI - Java VM Tool Interface \ | back-end | \ |--------------| / | comm channel --( | <------------ JDWP - Java Debug Wire Protocol \ | / |--------------| / | front-end | debugger -----( |--------------| <---- JDI - Java Debug Interface \ | UI | \ |--------------| |
따라서 JPDA를 기반으로 한 써드파티 도구와 VM이 함께 문제 없이 작동해야 한다. 이런 클라이언트-서버 아키텍처를 통해 플랫폼을 운영하는 로컬 워크스테이션에서 Java 프로그램을 디버그하거나 네트워크 상의 원격 컴퓨터에서 디버그할 수도 있다.
디버그 시나리오에 대해 설명하기 전에, JPDA 스펙에서 사용되는 커넥터와 전송이라는 두 가지 용어를 소개하겠다. 커넥터는 디버거 애플리케이션과 대상 VM 사이에 연결을 설정하는 데 사용되는 JDI 추상화이다. 전송은 애플리케이션이 데이터에 액세스하여 프론트 엔드와 백엔드 사이에서 전송하는 방식을 정의한다. 커넥터는 연결의 모드와 사용 가능한 전송 유형에 "맵핑"된다. Sun의 JPDA 참조 구현에서는 Microsoft? Windows?에서 소켓 전송과 공유 메모리 전송이라는 두 가지 전송 메커니즘이 제공된다. 사용 가능한 커넥터는 다음과 같다.
디버거 애플리케이션과 대상 VM 간에 연결을 설정할 때, 한쪽은 서버로 작동하면서 연결을 수신 대기한다. 나중에, 다른 쪽이 리스너에 연결하여 연결을 설정한다. 이런 연결을 통해 디버거 애플리케이션 또는 대상 VM이 서버 역할을 할 수 있다. 한 머신이나 다른 머신에서 프로세스 간의 통신이 작동 중일 수 있다.
Java 프로그램을 원격으로 디버깅할 때의 문제점이 디버거 프론트 엔드에는 없지만 원격 Java 백엔드에는 있다. 불행히도, Eclipse 도움말 시스템에는 이에 대한 정보가 그다지 많지 않다. 사실, JDI와 JVMTI는 각각 Eclipse와 Java 런타임 환경에 의해 구현된다. 우리가 관심을 갖는 유일한 것은 JDWP로서, 여기에는 JVMTI 및 JDI와 통신하기 위한 정보가 포함된다. JDWP에는 원격 Java 애플리케이션용 애플리케이션을 호출하기 위해 추가된 많은 인수가 있다. 다음은 이 기사에서 사용하는 몇 가지 인수다.
Java V5부터는 -Xdebug와 -Xrunjdwp 대신 -agentlib:jdwp 옵션을 사용할 수 있다. 그러나 V5 이전의 VM에 연결해야 하는 경우에는 -Xdebug와 -Xrunjdwp만 선택할 수 있다. 다음은 -Xrunjdwp 하위 옵션에 대한 간략한 설명이다.
각 디버그 설정에 대한 자세한 설명은 JPDA 문서를 참조한다(참고자료 참조).
목록 2는 디버그 모드에서 VM을 시작하고 포트 8765에서 소켓 연결을 수신 대기하는 방법의 예를 나타낸 것이다.
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=8765 |
목록 3은 포트 8000에서 호스트 127.0.0.1의 소켓을 사용하여 실행 중인 디버거 애플리케이션에 연결하는 방법을 나타낸 것이다.
-Xdebug -Xrunjdwp:transport=dt_socket,address=127.0.0.1:8000 |
Eclipse는 그래픽 Java 디버거 프론트 엔드이다. JDI는 org.eclipse.jdt.debug 번들로 구현된다. 이 기사에서는 JDI 구현에 대해 자세히 논하지 않는다. Eclipse JDT 및 Java JDI 기술에 관한 정보는 참고자료를 참조한다.
우리가 가장 먼저 알고 싶은 것은 사용할 Eclipse 커넥터가 어떤 것이냐 하는 점이다. Eclipse에서 제공하는 원격 연결 유형을 알아보려면 Eclipse 메뉴로 이동하여 Run > Debug Configurations...를 선택한 후 드롭다운 목록에서 커넥터를 선택하여 Remote Java Application
에서 시작 구성을 추가하면 된다. Ganymede에서는 다음 두 커넥터가 제공된다.
소켓 수신 대기 커넥터의 경우, Eclipse VM이 원격 Java 애플리케이션에서 연결할 호스트가 된다. 소켓 접속 커넥터의 경우, 대상 VM이 호스트가 된다. 두 커넥터 사이에 애플리케이션 디버깅의 차이는 없으므로, 사용자가 선택할 수 있다. 경험 법칙에 따르면, 필요한 전산 자원 때문에 더 빠르고 강력한 컴퓨터를 VM 디버그 호스트로 사용하는 것이 좋다.
Java 애플리케이션을 디버그하기 전에 원격 애플리케이션에 대해 디버그 옵션이 모두 사용되는지 확인할 필요가 있다. 그 정보를 알 수 없는 경우 "Debug information is not available(디버그 정보를 제공할 수 없음)" 또는 "Unable to install breakpoint due to missing line number(행 번호가 없어 중단점을 설치할 수 없음)"와 같은 오류 메시지가 표시된다. Window > Preferences > Java > Compiler에서 설정한 것을 변경하여 Eclipse 메뉴에서 설정을 수정할 수 있다.
애플리케이션 원격 디버깅을 시작할 준비가 되었다. 단계별로 진행해보자.
package com.ibm.developerWorks.debugtest; public class test { public static void main(String[] args) { System.out.println("This is a test."); } } |
System.out.println("This is a test.");
행에 중단점을 설정한다.java -jar test.jar |
다음은 원격 측에서 Java 애플리케이션을 호출하고 디버그 서버로 작동하고 포트 8000에서 소켓 연결을 수신 대기하는 예제이다. 디버거가 연결할 때까지 대상 VM이 일시중단된다.
목록 6. Eclipse에서 소켓 접속 모드에 대한 VM 호출 샘플
java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address="8000" -jar test.jar |
원격 시작 구성을 사용하여 Eclipse를 시작하고 원격 애플리케이션의 대상 VM 주소를 지정한다. 이 작업을 수행하려면 Eclipse 메뉴에서 Run > Debug Configurations를 클릭하고 Remote Java Application을 두 번 클릭한다. 새로 작성된 시작 구성에서 대상 애플리케이션에 대한 IP와 포트를 지정한다. 동일한 머신에서 원격 애플리케이션을 실행하려면 간단히 호스트 IP 또는 로컬 호스트 또는 127.0.0.1을 지정한다.
Allow termination of remote VM 옵션을 선택하여 애플리케이션 디버깅 중에 연결하는 VM을 종료한다.
두 번째 예제에서는 디버그 클라이언트로 작동하는 간단한 Java 애플리케이션을 사용하며, 디버거 프론트 엔드가 디버그 서버로 작동한다. Eclipse에서는 소켓 수신 대기 모드 연결 유형을 사용하여 수신 대기한다. 특정 포트에서 수신 대기하려면 우선 디버그 프론트 엔드부터 시작해야 한다. 그림 6은 수신 대기를 설정하기 위한 샘플 구성을 나타낸 것이다.
Eclipse Debug 단추를 클릭하면 상태 표시줄에 "waiting for vm to connect at port 8000..." 메시지가 표시된다. 이 메시지가 보이면 원격 애플리케이션을 시작한다. 목록 7은 Java 애플리케이션을 디버그 클라이언트로 호출하고 포트 8000에서 호스트 127.0.0.1의 소켓을 사용하여 실행 중인 디버거 애플리케이션에 이를 연결하는 방법을 나타낸 것이다.
목록 7. Eclipse에서 소켓 수신 대기 연결을 위한 VM 호출 샘플
java -Xdebug -Xrunjdwp:transport=dt_socket,address=127.0.0.1:8000,suspend=y -jar test.jar |
모든 것이 원활하게 진행되면 애플리케이션 디버깅을 지원하기 위한 디버그 퍼스펙티브가 표시되고 원격 Java 애플리케이션의 실행이 정상적으로 중지된다. 이는 로컬 디버깅에서 수행한 3단계와 유사하다(그림 3 참조). 이때 중단점과 값, 단계 실행 등과 같은 표준 디버깅 기능을 사용할 수 있다.
이 기사에서는 Eclipse에 내장된 원격 Java 애플리케이션 구성 유형을 사용하여 애플리케이션 디버깅을 원격으로 수행하는 방법을 설명했다. 그리고 원격 디버깅을 호출하도록 Java 애플리케이션을 설정하는 방법을 소개하고 Eclipse에서 제공하는 커넥터에 대한 정보를 제공했다. 마지막으로, 프로젝트에 이 기술을 적용하는 방법을 학습해보았다.
|