من از راه سختش یاد گرفتم که نمیشه همه باگهای موجود در کد رو با دستورات println ردیابی کنم. وصل کردن یک دیباگر به کد در حال اجرا گاهی اوقات به طرز معجزه آسایی بهتون کمک میکنه تا متوجه بشین کجای کدتون اشکال داره.
از اولین نسخههای جاوا دیباگ از راه دور به عنوان یه امکان قرار داده شده، اما تعدادی از به روزرسانیهای اصلی با عنوان دیباگ با تمام سرعت در نسخه 1.4.0 جاوا معرفی شد و از اون زمان تا حالا تغییرات زیادی نداشته. شما میتونین مستندات جاوا 8 رو اینجا ببینین.
من اخیرا با برخی از قابلیتهای Intellij Idea در دیباگ از راه دور آشنا شدم و تصمیم گرفتم اونها رو تست کنم. در این مقاله میخوام بهتون نشون بدم چطور یه اپلیکیشن جاوای کوچک رو در یک کانتینر داکر و روی ماشین مجازی ابری اجرا و از طریق لپتاپم دیباگش کردم.
خب بیاین شروع کنیم.
گام اول
در قدم اول یه اپلیکیشن جاوا میسازیم که هر پنج ثانیه اعداد رو به صورت افزایشی و به مقدار نامحدود چاپ میکنه.
package com.kaysush;
public class App {
public static void main(String[] args) {
System.out.println("Starting the remote debugging application");
System.out.println("The application will be running inside a docker image");
int i = 0;
while(true){
System.out.println("Value of i is " + i);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
i++;
}
}
}
اپلیکیشن رو به صورت یک پکیج با پسوند jar ذخیره کنین. من برای این کار از maven استفاده میکنم، اما شما میتونین از نرمافزار مورد علاقه خودتون برای تهیه پکیج اپلیکیشن استفاده کنین. در مرحله بعد باید یه فایل داکر برای این اپلیکیشن ایجاد کنیم.
FROM openjdk:8
WORKDIR /app
ENV JAVA_TOOL_OPTIONS -agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n
COPY remote-debugging-1.0-SNAPSHOT.jar remote-debugging.jar
ENTRYPOINT ["java", "-cp", "remote-debugging.jar", "com.kaysush.App"]
نکته قابل توجه در این کد خط سومه که در اون متغیر محیطی JAVA_TOOL_OPTIONS رو تعریف کردم. این متغیر به جاوا میگه که باید بخش JPDA رو فعال کنه تا بتونیم با استفاده از Java Debug Wire Protocol یا JWDP اپلیکیشن رو از راه دور دیباگ کنیم.
خب حالا باید با استفاده از دستور زیر فایل داکر رو بسازیم. قبل از اون مطمئن بشین فایل jar و Dockerfile در یک دایرکتوری قرار دارن.
docker build -t remote-debugger:0.1 .
با دستور زیر اپلیکیشن رو اجرا کنین.
docker run -d -p 8000:8000 remote-debugger:0.1
با این دستور اپلیکیشن در حالت daemon اجرا میشه و پورت 8000 رو باز نگه میداره.
حالا شما باید یه لاگ مشابه شکل زیر ببینین.
اگه این لاگ رو نمیبینین لطفا متغیر محیطی رو دوباره بررسی کنین و مطمئن بشین که درست تعیین شده. برای نسخههای قبل از جاوا 8 این متغیر با عبارت JAVA_OPTS تعریف میشه.
من دارم اپلیکیشن رو روی یک ماشین مجازی ابری اجرا میکنم اما شما میتونین از هر سروری که خواستین استفاده کنین. فقط باید مطمئن باشین سرور اتصالهای ورودی رو دریافت میکنه و پورتی که توی متغیر محیطی تعریف کردین، روی سرور بازه.
در ضمن اپلیکیشن شما حتما نباید داخل یه کانتینر اجرا بشه. تمام این مراحل برای اجرای اپلیکیشن جاوا بدون کانتینر هم به همین صورت قابل اجراست.
تنظیم دیباگ از راه دور
حالا نوبت تنظیم دیباگ از راه دور در Intellij است.
مسیر زیر رو دنبال کنین:
روی علامت + کلیک و یه remote configuration اضافه کنین.
- در قسمت Debugger Mode گزینه Attach to remote JVM رو انتخاب کنین.
- آدرس IP میزبان راه دور و پورتی رو که تو متغیر محیطی تعریف کردین، وارد کنین.
- روی Apply کلیک کنین.
رای دیدن تنظیمات بیشتر میتونین اینجا رو ببینین.
یه نقطه توقف (break-point) آخر دستور پرینت اضافه کنین تا برنامه به این نقطه که رسید متوقف بشه.
به مسیر Run > Debug برین و تنظیماتی رو که در قسمت قبل ایجاد کردیم، انتخاب کنین. اگر همه چیز درست انجام شده باشه، الان دیباگر باید اجرا بشه و شما باید متن زیر رو ببینین.
حالا Intellij متغیرها رو بارگذاری و پشته رو فراخوانی میکنه.
شما میتونین در سمت راست مقادیر متغیرها رو ببینین. ما فقط یه متغیر i داریم که مقدار 134 رو نشون میده. برای این که مطمئن بشین دارین در حالت از راه دور اپلیکیشن رو دیباگ میکنین، به قسمت لاگ اپلیکیشن برین. اینجا میبینین که لاگ متوقف شده و منتظره تا برنامه به خط بعدی بره.
خب ما با موفقیت یه قسمت دیباگ از راه دور برای اپلیکیشن جاوای خودمون تنظیم کردیم.
از کدزنی لذت ببرین!
اگر دوست دارین بدونین چجوری میشه هر تغییری در برنامهتون رو در لحظه و بدون نیاز به ریاستارت کردن، بارگزاری کنین، پیشنهاد میکنیم این پست بلاگ سکو رو مطالعه کنین.