การดีบักแบบรีโมตสำหรับแอ็พพลิเคชัน Java


254

ฉันมีจาวาแอปพลิเคชันที่ทำงานบนเครื่องลินุกซ์ ฉันรันแอปพลิเคชัน java โดยใช้สิ่งต่อไปนี้:

java myapp -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=4000, suspend=n

ฉันได้เปิดพอร์ต 4000 สำหรับ TCP บนเครื่อง Linux นี้ ฉันใช้ eclipse จากเครื่อง Windows XP และลองเชื่อมต่อกับแอปพลิเคชันนี้ ฉันได้เปิดพอร์ตใน windows ด้วย

เครื่องทั้งสองอยู่บน LAN แต่ฉันไม่สามารถเชื่อมต่อดีบักเกอร์กับแอปพลิเคชัน Java ได้ ผมทำอะไรผิดหรือเปล่า?




ไม่ซ้ำกันเลย ก่อนอื่นนี่เป็นคำถามที่เก่ากว่า ประการที่สองคำตอบสำหรับคำถามนี้ควรไม่เชื่อเรื่องสภาพแวดล้อมการดีบัก
Addison

คำตอบ:


476

แก้ไข:ฉันสังเกตเห็นว่าบางคนกำลังตัดและวางคำเชิญที่นี่ คำตอบที่ฉันให้ไว้มีความเกี่ยวข้องกับ OP เท่านั้น นี่คือรูปแบบการเรียกที่ทันสมัยยิ่งขึ้น (รวมถึงการใช้พอร์ตทั่วไปที่มากกว่า 8000):

java -agentlib:jdwp=transport=dt_socket,server=y,address=8000,suspend=n <other arguments>

คำตอบเดิมมีดังนี้


ลองสิ่งนี้:

java -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=4000,suspend=n myapp

สองจุดที่นี่:

  1. ไม่มีช่องว่างในrunjdwpตัวเลือก
  2. ตัวเลือกมาก่อนชื่อคลาส ข้อโต้แย้งใด ๆ ที่คุณมีหลังจากชื่อคลาสเป็นการขัดแย้งกับโปรแกรมของคุณ!


2
@DJGummikuh ดีมาก! ฉันได้อัปเดตโพสต์เพื่อใช้-agentlibตัวเลือกรูปแบบใหม่เพื่อความเพลิดเพลินในการตัดและวางของคุณ :-)
Chris Jester-Young

เราจำเป็นต้องมีซอร์สโค้ดสำหรับแอประยะไกลอยู่ในเครื่องที่เราทำการดีบักแบบรีโมทหรือไม่?
MasterJoe2

คุณต้องรู้รหัสที่มา ไม่ว่าคุณจะมีไฟล์. java หรือคุณมีไฟล์. jar / .class รวมกับตัวถอดรหัส IDE เช่น Eclipse สามารถมี decompiler เช่น JDecompiler ติดตั้งเพื่อให้คุณสามารถดีบักไฟล์. class ราวกับว่าเป็นไฟล์. java (ยกเว้นความคิดเห็น)
Iwan Satria

1
คุ้มค่าที่จะแสดงความคิดเห็นซ้ำจากstackoverflow.com/a/138518/500902นี้"ตั้งแต่ Java 9" address = 1044 "ไม่ได้ฟังบนทุกอินเตอร์เฟสเสมอ" address = *: 1044 "ทำให้ Java 9+ ทำงานเหมือน Java 8" ถึง อนุญาตให้ทำการดีบั๊กจากโฮสต์ที่แตกต่างกัน
Marvin

84

สำหรับ JDK 1.3 หรือเก่ากว่า:

-Xnoagent -Djava.compiler=NONE -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=6006

สำหรับ JDK 1.4

-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=6006

สำหรับ JDK ที่ใหม่กว่า:

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

โปรดเปลี่ยนหมายเลขพอร์ตตามความต้องการของคุณ

จากจาวาเทคโน

ตั้งแต่ 5.0 เป็นต้นไปจะใช้ตัวเลือก -agentlib: jdwp เพื่อโหลดและระบุตัวเลือกไปยังเอเจนต์ JDWP สำหรับรีลีสก่อนหน้า 5.0 จะใช้อ็อพชัน -Xdebug และ -Xrunjdwp (การนำไปใช้งาน 5.0 ยังสนับสนุนอ็อพชัน -Xdebug และ -Xrunjdwp แต่อ็อพชัน -agentlib: jdwp ที่ใหม่กว่านั้นดีกว่าเนื่องจากเอเจนต์ JDWP ใน 5.0 ใช้ JVM TI อินเตอร์เฟส VM มากกว่าอินเตอร์เฟส JVMDI ที่เก่ากว่า)

อีกสิ่งหนึ่งที่ควรทราบจากเอกสารคู่มือเครื่องมือ JVM :

JVM TI เปิดตัวที่ JDK 5.0 JVM TI แทนที่ Java Virtual Machine Profiler Interface (JVMPI) และ Java Virtual Machine Debug Interface (JVMDI) ซึ่งในตอนนี้ของ JDK 6 ไม่มีให้บริการอีกต่อไป


ต่อไปนี้ใช้งานได้กับการตั้งค่าเริ่มต้นของ Eclipse: -agentlib: jdwp = transport = dt_socket, เซิร์ฟเวอร์ = y, ที่อยู่ = 8000
Sundae

29

ขั้นตอน:

  1. เริ่มต้นแอ็พพลิเคชัน java รีโมตของคุณด้วยอ็อพชันการดีบักดังกล่าวในโพสต์ด้านบน
  2. กำหนดค่า Eclipse สำหรับการดีบักแบบรีโมตโดยการระบุโฮสต์และพอร์ต
  3. เริ่มต้นการดีบักแบบรีโมตใน Eclipse และรอให้การเชื่อมต่อสำเร็จ
  4. ตั้งค่าเบรกพอยต์และดีบัก
  5. หากคุณต้องการแก้ปัญหาตั้งแต่เริ่มต้นของแอปพลิเคชันใช้ suspend = y สิ่งนี้จะทำให้แอปพลิเคชันระยะไกลถูกระงับจนกว่าคุณจะเชื่อมต่อจาก eclipse

ดูคำแนะนำทีละขั้นตอนเกี่ยวกับการดีบักแบบรีโมทของ Javaสำหรับรายละเอียดแบบเต็ม


16

คำตอบที่ครอบคลุม Java> = 9:

สำหรับ Java 9+ ตัวเลือก JVM ต้องการการเปลี่ยนแปลงเล็กน้อยโดยใส่คำนำหน้าที่อยู่ด้วยที่อยู่ IP ของเครื่องที่โฮสต์ JVM หรือเพียงแค่*:

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

เพราะนี่คือการเปลี่ยนแปลงที่ระบุไว้ในhttps://www.oracle.com/technetwork/java/javase/9-notes-3745703.html#JDK-8041435

สำหรับ Java <9 หมายเลขพอร์ตก็เพียงพอที่จะเชื่อมต่อได้


8

ผมอยากจะเน้นว่าคำสั่งของการขัดแย้งเป็นสิ่งที่สำคัญ

สำหรับผม java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000 -jar app.jarคำสั่งเปิดพอร์ตดีบัก ,

แต่java -jar app.jar -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000คำสั่งไม่ได้


3
ฉันเดาว่าเป็นเพราะในตัวอย่างที่สองของคุณทุกอย่างหลังจาก "app.jar" ถูกส่งผ่านเป็นอาร์กิวเมนต์ในวิธีการหลักของคุณ
xoX Zeus Xox

@xoXZeusXox ฮ่าฮ่า ใช่มันผ่านเป็นข้อโต้แย้ง ขอบคุณที่พูดถึง
MrBlack

1

นี่คือวิธีที่คุณควรตั้งค่า Eclipse Debugger สำหรับการดีบักแบบรีโมท:

การตั้งค่า Eclipse:

1. คลิกที่ปุ่ม Run
2. เลือก Debug Configuration
3. เลือก“ Remote Java Application”
4. กำหนดค่าใหม่

  • ชื่อ: GatewayPortalProject
  • โครงการ: GatewayPortal-portlet
  • ประเภทการเชื่อมต่อ: ซ็อกเก็ตที่แนบมา
  • คุณสมบัติการเชื่อมต่อ: i) localhost ii) 8787

สำหรับ JBoss:

1. เปลี่ยน/path/toJboss/jboss-eap-6.1/bin/standalone.confใน vm ของคุณดังนี้: ยกเลิกหมายเหตุบรรทัดต่อไปนี้โดยลบ #:

JAVA_OPTS="$JAVA_OPTS -agentlib:jdwp=transport=dt_socket,address=8787,server=y,suspend=n"

สำหรับ Tomcat:

ในไฟล์catalina.bat :

ขั้นตอนที่ 1:

CATALINA_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n"

ขั้นตอนที่ 2:

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

ขั้นตอนที่ 3: เรียกใช้ Tomcat จากพรอมต์คำสั่งด้านล่าง:

catalina.sh jpda start

จากนั้นคุณต้องตั้งค่าเบรกพอยต์ในคลาส Java ที่คุณต้องการดีบัก


ใน Java 8 JDK สนับสนุนตัวแปรสภาพแวดล้อมJAVA_TOOL_OPTIONSเพื่อเปิดใช้งานดีบักเกอร์สำหรับแอปพลิเคชัน Java ใด ๆ ที่คุณต้องใช้: JAVA_TOOL_OPTIONS=-agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n ps ขออภัยสำหรับการแก้ไขต่อสู้กับฟอร์แมตเตอร์
Nathan Niesen
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.