এই পর্বে যা শিখবেন
- JDK, JRE আর JVM — কোনটি কী, আর আপনার কোনটি দরকার
- কোন JDK distribution আর কোন version বেছে নেবেন, কেন
- Windows, macOS আর Linux-এ ইনস্টল,
JAVA_HOMEআরPATHঠিক করা javac→.class→java— terminal-এ আসলে কী ঘটে, আর JShell দিয়ে দ্রুত পরীক্ষা- সবচেয়ে পরিচিত সেটআপ-error চিনে ঠিক করা, আর AI-এর পুরোনো পরামর্শ যাচাই করা
১ · Java চালাতে কী কী লাগে — JDK, JRE আর JVM
পর্ব ০১-এ দেখেছেন, Java-র মূল প্রতিশ্রুতি হলো “একবার লিখুন, যেকোনো জায়গায় চালান।” এই প্রতিশ্রুতি রাখতে Java মাঝখানে একটি স্তর রাখে। আপনার কোড সরাসরি CPU-র ভাষায় অনুবাদ হয় না; আগে অনুবাদ হয় bytecode-এ, তারপর সেটি চালায় একটি “ভার্চুয়াল কম্পিউটার”।
তাই নিজের কম্পিউটারে Java প্রোগ্রাম বানাতে আর চালাতে তিনটি জিনিস দরকার:
Compiler — javac
আপনার .java ফাইল পড়ে, ভুল থাকলে জানায়, আর না থাকলে .class ফাইলে bytecode লিখে দেয়।
JVM — java
.class ফাইল পড়ে আপনার কম্পিউটারের CPU-তে চালায়। Windows, Mac, Linux — প্রতিটির জন্য আলাদা JVM, কিন্তু bytecode একটাই।
Standard library
হাজার হাজার রেডিমেড class — String, List, ফাইল পড়া, নেটওয়ার্ক, তারিখ-সময়। System.out.println-ও এখান থেকেই আসে।
এই তিনটি একসাথে যে প্যাকেজে আসে, তার নাম JDK (Java Development Kit). নামের তিনটি শব্দ প্রায়ই গুলিয়ে যায়, তাই একবার পরিষ্কার করে নিই:
| নাম | ভেতরে কী আছে | কার জন্য |
|---|---|---|
| JVM (Java Virtual Machine) | bytecode চালানোর ইঞ্জিন — class লোড করা, যাচাই, চালানো, মেমরি সামলানো | সবার — এটি ছাড়া Java চলে না |
| JRE (Java Runtime Environment) | JVM + standard library | যিনি শুধু তৈরি প্রোগ্রাম চালাবেন |
| JDK (Java Development Kit) | JRE-এর সবকিছু + javac, jshell, jar, javap, jlink ইত্যাদি টুল | প্রোগ্রামার — অর্থাৎ আপনি |
একটি রেস্টুরেন্টের কথা ভাবুন। JVM হলো চুলা — রান্না আসলে এখানেই হয়। JRE হলো চুলা আর মসলার তাক মিলিয়ে একটি রান্নাঘর, যেখানে আগে থেকে তৈরি রেসিপি অনুযায়ী খাবার গরম করা যায়। আর JDK হলো পুরো রান্নাঘর সঙ্গে নতুন রেসিপি লেখার খাতা, মাপার চামচ আর পরীক্ষার টেবিল। আপনি যেহেতু নতুন রেসিপি লিখবেন, আপনার দরকার পুরো JDK.
আজকের দিনে আলাদা করে “JRE ডাউনলোড” করার প্রশ্নই প্রায় নেই। Java 11 থেকে Oracle আলাদা JRE দেওয়া বন্ধ করে দেয়; কোনো প্রোগ্রাম বিতরণ করতে হলে jlink দিয়ে শুধু দরকারি অংশ নিয়ে ছোট একটি runtime বানানো হয়। কয়েকটি distribution (যেমন Temurin) এখনো JRE প্যাকেজ দেয়, কিন্তু প্রোগ্রামার হিসেবে আপনার জন্য একটাই নিয়ম: JDK ইনস্টল করুন।
তাহলে IDE কী? IDE হলো কোড লেখার সুবিধাজনক জায়গা — রঙিন লেখা, ভুলের নিচে লাল দাগ, এক ক্লিকে চালানো। কিন্তু ভেতরে ভেতরে IDE ঠিক ওই JDK-র javac আর java-কেই ডাকে। আর terminal হলো সেই জায়গা, যেখানে এই ডাকাডাকি খালি চোখে দেখা যায়। এই পর্বে আমরা দুটোই শিখব — কারণ IDE-তে কিছু ভাঙলে terminal-ই বলে দেয় আসলে কী হয়েছে।
C/C++-এ gcc সরাসরি machine code বানায়, আর সেই .exe নির্দিষ্ট OS-এ চলে। Java-র javac বানায় bytecode, যা যেকোনো OS-এর JVM-এ চলে। Python-এও bytecode আছে, কিন্তু সেটি লুকিয়ে তৈরি হয়; Java-তে compile আর run দুটি আলাদা, চোখে দেখা ধাপ। তুলনার জন্য দেখুন C-এর toolchain আর Python-এর সেটআপ পর্ব।
২ · কোন JDK, কোন version — distribution আর LTS
প্রথমবার JDK খুঁজতে গেলে নতুনরা বিভ্রান্ত হন — Oracle, OpenJDK, Temurin, Corretto… এত নাম কেন? উত্তরটা সহজ। Java-র আসল সোর্স কোড একটিই — OpenJDK নামের একটি ওপেন-সোর্স প্রজেক্ট। বিভিন্ন প্রতিষ্ঠান সেই একই সোর্স থেকে JDK build করে, পরীক্ষা করে, আর নিজেদের নামে বিতরণ করে। একে বলে JDK distribution.
একই কারখানার ওষুধ বিভিন্ন ফার্মেসি নিজেদের প্যাকেটে বিক্রি করলে ভেতরের উপাদান একই থাকে; তফাত থাকে প্যাকেট, দাম আর ফেরত দেওয়ার নিয়মে। JDK distribution-ও তেমন — ভেতরের Java একই, তফাত লাইসেন্স, আপডেট কতদিন পাবেন আর কোন প্ল্যাটফর্মে কীভাবে ইনস্টল হয় তাতে।
| Distribution | কে বানায় | মন্তব্য |
|---|---|---|
| Eclipse Temurin | Eclipse Adoptium (আগের নাম AdoptOpenJDK) | বিনা মূল্যে, সব বড় OS-এ; শেখার জন্য নিরাপদ ডিফল্ট পছন্দ |
| Oracle JDK | Oracle | লাইসেন্সের শর্ত বিভিন্ন সময়ে বদলেছে; কোম্পানিতে ব্যবহারের আগে বর্তমান শর্ত পড়ে নিন। Oracle-এর GPL লাইসেন্সের OpenJDK build-ও আলাদাভাবে পাওয়া যায় (jdk.java.net) |
| Amazon Corretto | Amazon | বিনা মূল্যে, AWS-এ বেশি দেখা যায় |
| Microsoft Build of OpenJDK | Microsoft | বিনা মূল্যে, Azure ও Windows-কেন্দ্রিক দলে জনপ্রিয় |
এর বাইরেও Azul Zulu, Red Hat build of OpenJDK, Linux distribution-এর নিজস্ব প্যাকেজসহ আরও অনেক আছে। শেখার জন্য এদের যেকোনোটিই চলবে — আপনার লেখা Java কোড সবগুলোতে একইভাবে চলবে।
কোন version? — LTS বেছে নিন
২০১৮ সাল (Java 10) থেকে Java প্রতি ছয় মাসে একটি নতুন version প্রকাশ করে (প্রতি মার্চ আর সেপ্টেম্বরে)। কিন্তু প্রতিটিতে দীর্ঘদিন আপডেট আসে না। কয়েকটি version-কে বলা হয় LTS (Long-Term Support) — distribution-গুলো এগুলোতে বহু বছর নিরাপত্তা-আপডেট দেয়। কোম্পানিগুলো প্রায় সবসময় LTS-এই থাকে।
| LTS version | প্রকাশ | আজকের অবস্থা |
|---|---|---|
| Java 8 | ২০১৪ | পুরোনো প্রজেক্টে এখনো আছে; নতুন শেখার জন্য নয় |
| Java 11 | ২০১৮ | পুরোনো হয়ে আসছে |
| Java 17 | ২০২১ | অনেক কোম্পানিতে চলছে; Spring Boot 3-এর ন্যূনতম version |
| Java 21 | ২০২৩ | এই কোর্সের ভিত্তি — record, pattern matching, virtual thread সব আছে |
| Java 25 | ২০২৫ | সর্বশেষ LTS; এই কোর্সের সব কোড এতেও চলবে |
JDK 21 বা JDK 25, Eclipse Temurin থেকে — নতুন হলে এটুকুই মনে রাখুন। এই সাইটের অনলাইন runner Java 21-এ চলে, তাই JDK 21 নিলে পাতায় যা দেখবেন আর নিজের কম্পিউটারে যা দেখবেন, হুবহু মিলবে। পুরোনো কোনো প্রজেক্ট Java 8 বা 11 চাইলে পাশাপাশি সেটিও রাখা যায় — অংশ ৮-এ দেখবেন কীভাবে।
৩ · ইনস্টল — Windows, macOS আর Linux
ইনস্টলের আগে দুটি শব্দ বুঝে নিন, কারণ সেটআপের প্রায় সব সমস্যা এই দুটিকে ঘিরে।
- PATH: একটি environment variable, যেখানে কয়েকটি ফোল্ডারের তালিকা থাকে। terminal-এ
javacলিখলে কম্পিউটার এই তালিকার ফোল্ডারগুলোতে ক্রমানুসারেjavacনামের প্রোগ্রাম খোঁজে। যে ফোল্ডারে প্রথম পায়, সেটিই চালায়। কোথাও না পেলে — “not recognized”. - JAVA_HOME: আরেকটি environment variable, যার মান JDK-র মূল ফোল্ডার (যেমন
C:\Program Files\Eclipse Adoptium\jdk-21…)।javaআরjavacনিজেরা এটি পড়ে না; পড়ে Maven, Gradle, Tomcat আর অনেক IDE — “JDK কোথায় আছে” জানার জন্য।
- adoptium.net থেকে Temurin 21 (LTS)-এর Windows x64
.msiফাইল নামান। - installer-এ “Add to PATH” চালু আছে কি না দেখুন, আর “Set JAVA_HOME variable” অপশনটিও চালু করে দিন (ডিফল্টে এটি বন্ধ থাকতে পারে)।
- ইনস্টল শেষে নতুন Command Prompt খুলে যাচাই করুন। আগে খোলা জানালা পুরোনো PATH মনে রাখে।
যাঁরা কমান্ড পছন্দ করেন, Windows 10/11-এর winget দিয়েও একই কাজ হয়:
winget install EclipseAdoptium.Temurin.21.JDK
:: নতুন Command Prompt-এ যাচাই
where java
echo %JAVA_HOME%
java -version
javac -versionPowerShell-এ where একটি ভিন্ন কমান্ড, তাই সেখানে where.exe java লিখুন, আর JAVA_HOME দেখতে $env:JAVA_HOME.
দুটি সহজ পথ: adoptium.net থেকে .pkg installer নামিয়ে ডাবল-ক্লিক, অথবা Homebrew থাকলে একটি কমান্ড:
brew install --cask temurin@21
# কোন কোন JDK আছে আর কোনটি ডিফল্ট
/usr/libexec/java_home -V
# ~/.zshrc ফাইলে যোগ করুন, যাতে JAVA_HOME ঠিক থাকে
export JAVA_HOME=$(/usr/libexec/java_home -v 21)Apple Silicon (M1/M2/M3…) Mac-এ aarch64 build নিন; Homebrew নিজেই ঠিকটি বেছে নেয়।
Ubuntu (22.04 বা নতুন) আর Debian-এর নতুন সংস্করণে distribution-এর নিজস্ব OpenJDK প্যাকেজই যথেষ্ট। পুরোনো সংস্করণে openjdk-21-jdk প্যাকেজ না পেলে নিচের SDKMAN ব্যবহার করুন:
sudo apt update
sudo apt install openjdk-21-jdk
# একাধিক JDK থাকলে ডিফল্ট বদলানো
sudo update-alternatives --config java
sudo update-alternatives --config javacএকাধিক version নিয়ে কাজ করলে SDKMAN খুব কাজের — নিজের home ফোল্ডারে ইনস্টল করে, sudo লাগে না, আর এক কমান্ডে version বদলানো যায়:
curl -s "https://get.sdkman.io" | bash
sdk list java # কোন কোন build পাওয়া যায়
sdk install java 21.0.8-tem # তালিকায় যে নম্বর দেখবেন, সেটি লিখুন
sdk use java 21.0.8-temবাস্তব ঘটনা ১ — ল্যাবের কম্পিউটারে admin অধিকার নেই
রাজশাহীর একটি কম্পিউটার ল্যাবে সুমাইয়া Java অনুশীলন করতে চান, কিন্তু installer চালাতে গেলেই চায় administrator পাসওয়ার্ড। এখানে সমাধান হলো ZIP সংস্করণের JDK — ইনস্টল করতে হয় না, শুধু খুলে নিলেই চলে।
- adoptium.net-এ Windows-এর জন্য
.zipপ্যাকেজ নামান, তারপর এমন ফোল্ডারে খুলুন যেখানে লেখার অনুমতি আছে — যেমনD:\tools\jdk-21বা নিজের user ফোল্ডার। - শুধু এই terminal-জানালার জন্য PATH বদলান (জানালা বন্ধ করলে বদলটিও চলে যায়):
set "JAVA_HOME=D:\tools\jdk-21"
set "PATH=%JAVA_HOME%\bin;%PATH%"
java -versionস্থায়ীভাবে রাখতে চাইলে Windows-এর সার্চে “Edit environment variables for your account” খুলুন — এটি শুধু আপনার নিজের অ্যাকাউন্টের জন্য, তাই admin লাগে না। পেনড্রাইভে JDK-র ফোল্ডারটি রেখেও একই কাজ করা যায়। IntelliJ IDEA-ও নিজের ভেতর থেকে JDK নামিয়ে user ফোল্ডারে রাখতে পারে (অংশ ৭-এ দেখবেন)।
PATH কখনো পুরোটা মুছে নতুন করে লিখবেন না। অনেক পুরোনো টিউটোরিয়াল বলে setx PATH "%PATH%;..." চালাতে। এতে দুটি বিপদ: setx ১০২৪ অক্ষরের বেশি মান কেটে ফেলে, আর system ও user PATH মিশে যায়। ফলে অন্য সফটওয়্যার হঠাৎ কাজ করা বন্ধ করে দিতে পারে। Windows-এর Environment Variables জানালায় “New” চেপে একটি নতুন লাইন যোগ করাই নিরাপদ।
৪ · যাচাই — java -version আর javac -version কেন মিলতে হবে
ইনস্টল শেষ হলো কি না, তার আসল প্রমাণ দুটি কমান্ড। সব ঠিক থাকলে এমন কিছু দেখবেন (নম্বরের শেষ অংশ আপনার বেলায় আলাদা হতে পারে):
> java -version
openjdk version "21.0.5" 2024-10-15 LTS
OpenJDK Runtime Environment Temurin-21.0.5+11 (build 21.0.5+11-LTS)
OpenJDK 64-Bit Server VM Temurin-21.0.5+11 (build 21.0.5+11-LTS, mixed mode, sharing)
> javac -version
javac 21.0.5
প্রথমটি বলছে কোন JVM চলবে, দ্বিতীয়টি বলছে কোন compiler অনুবাদ করবে। দুটির প্রথম নম্বর (এখানে 21) একই হওয়া জরুরি। কেন, সেটি একটি বাস্তব ঘটনা দিয়ে বুঝি।
বাস্তব ঘটনা ২ — ল্যাপটপে লুকিয়ে থাকা JDK 8
তানভীর কয়েক বছর আগে একটি পুরোনো প্রজেক্টের জন্য Oracle-এর Java 8 ইনস্টল করেছিলেন। এখন তিনি JDK 21 ইনস্টল করে প্রথম প্রোগ্রাম লিখলেন। javac চলল, কিন্তু java Main লিখতেই এলো:
Exception in thread "main" java.lang.UnsupportedClassVersionError: Main has been compiled by a more recent version of the Java Runtime (class file version 65.0), this version of the Java Runtime only recognizes class file versions up to 52.0
দুটি version যাচাই করতেই রহস্য খুলে গেল:
> java -version
java version "1.8.0_202"
> javac -version
javac 21.0.5
> where java
C:\Program Files (x86)\Common Files\Oracle\Java\javapath\java.exe
C:\Program Files\Eclipse Adoptium\jdk-21.0.5.11-hotspot\bin\java.exe
Oracle-এর installer অনেক সময় নিজের একটি javapath ফোল্ডার PATH-এর একেবারে শুরুতে বসিয়ে দেয়। সেখানে java.exe আছে, কিন্তু javac.exe নেই। ফলে javac এলো নতুন JDK 21 থেকে, আর java এলো পুরোনো Java 8 থেকে। পুরোনো JVM নতুন compiler-এর লেখা ফাইল পড়তে পারে না। সমাধান: Java 8 দরকার না হলে আনইনস্টল করুন, অথবা PATH-এ JDK 21-এর bin ফোল্ডারটি javapath-এর ওপরে তুলে দিন। অংশ ৮-এ এই error-টি ধাপে ধাপে ভেঙে দেখব।
এবার ভেতর থেকে যাচাই করি — চলতে থাকা প্রোগ্রাম নিজেই বলে দিতে পারে সে কোন version-এর JVM-এ চলছে। নিচের কোডটি এই পাতার runner-এ চালান:
import java.nio.charset.Charset;
class Main {
public static void main(String[] args) {
int feature = Runtime.version().feature(); // যেমন 21
System.out.println("Java 17 বা নতুন? " + (feature >= 17));
System.out.println("Java 21 বা নতুন? " + (feature >= 21));
// class ফাইলের কোন version এই JVM সর্বোচ্চ বোঝে
System.out.println("class file version: " + System.getProperty("java.class.version"));
// Java 18 থেকে ডিফল্ট charset হলো UTF-8
System.out.println("UTF-8 ডিফল্ট? " + Charset.defaultCharset().name().equals("UTF-8"));
}
}আউটপুটে চারটি লাইন আসবে: Java 17 বা নতুন? true, Java 21 বা নতুন? true, class file version: 65.0 আর UTF-8 ডিফল্ট? true. Runtime.version().feature() দেয় version-এর প্রথম নম্বর। 65.0 হলো Java 21-এর class file version — তানভীরের error-এ ঠিক এই নম্বরটিই ছিল। নিজের কম্পিউটারে JDK 25 দিয়ে চালালে দেখবেন 69.0. আর একটা কথা: এখানে class-টির আগে public নেই — কেন নেই, অংশ ৭-এ বলছি।
৫ · javac Main.java আর java Main — terminal-এ আসলে যা ঘটে
IDE-তে সবুজ ▶ বোতাম চাপলে যা হয়, terminal-এ দুটি কমান্ডে সেটিই হয়। একটি ফোল্ডারে Main.java নামে একটি ফাইল রাখুন (ভেতরের কোডের প্রতিটি শব্দ পর্ব ০৪-এ বিস্তারিত দেখবেন), তারপর নিচের ডায়াগ্রামে ধাপগুলো দেখুন:
- PATH খোঁজা
javac.exe কোথায়?shell-এর কাজ - Compiler
javacভুল ধরে, অনুবাদ করে - Bytecode
Main.classযেকোনো OS-এ চলে - JVM
java Mainলোড, যাচাই, চালানো - Output
Hello, Dhaka!স্ক্রিনে ফল
> javac Main.java C:\Windows\system32\javac.exe ? → নেই C:\Windows\javac.exe ? → নেই C:\...\jdk-21.0.5.11-hotspot\bin\javac.exe → পাওয়া গেছে!
Main.java পড়া হলো ... class Main → ঠিক আছে main(String[]) → ঠিক আছে println("...") → System.out-এ আছে, ঠিক কোনো error নেই → কিছুই ছাপা হলো না
CA FE BA BE 00 00 00 41 ... ↑ magic number ↑ major version 0x41 = 65 = Java 21 এরপর bytecode: getstatic, ldc, invokevirtual ...
> java Main ← .class লিখবেন না! ১. classpath (এখানে বর্তমান ফোল্ডার)-এ Main.class খোঁজা ২. version 65 ≤ আমার সর্বোচ্চ 65? হ্যাঁ ৩. bytecode নিরাপদ কি না যাচাই ৪. public static void main(String[]) ডাকা
> java Main
Hello, Dhaka!
>
- Shell PATH-এ
javacখোঁজে। আপনিjavac Main.javaলিখে Enter চাপলেন। Windows (বা Mac/Linux-এর shell) PATH-এর ফোল্ডারগুলো একটার পর একটা দেখে। JDK-রbinফোল্ডারে পেয়ে সেটিই চালায়। এখানে না পেলে পরের ধাপে যাওয়াই হয় না — “'javac' is not recognized”. javacকোড যাচাই করে। javac পুরো ফাইল পড়ে ব্যাকরণ, টাইপ, নাম — সব মিলিয়ে দেখে। একটি;বাদ পড়লে বা নামের বানান ভুল হলে এখানেই error আসে, আর কোনো.classতৈরি হয় না। সব ঠিক থাকলেjavacচুপচাপ কাজ শেষ করে — কিছুই না ছাপা মানেই সফল।Main.classতৈরি হলো। এটি একটি class file — ভেতরে bytecode, CPU-র machine code নয়। প্রথম চার byte সবসময়CAFEBABE, তারপর version নম্বর। Java 21-এরjavacলেখে 65. এই ফাইলটি Windows-এ বানিয়ে Linux-এ নিয়ে গেলেও চলবে — Java-র মূল প্রতিশ্রুতি এখানেই।java MainJVM চালু করে। লক্ষ করুন, লিখতে হয় class-এর নাম (Main), ফাইলের নাম (Main.class) নয়।javalauncher JVM চালু করে; JVM-এর class loader classpath-এ (ডিফল্টে বর্তমান ফোল্ডার)Main.classখুঁজে নেয়, version মিলিয়ে দেখে, bytecode নিরাপদ কি না যাচাই করে, তারপরmainmethod ডাকে।- Output. JVM bytecode চালায় (প্রয়োজনে দ্রুত চালানোর জন্য machine code-এ অনুবাদও করে নেয় — পর্ব ০৫-এ JIT দেখবেন)। স্ক্রিনে আসে
Hello, Dhaka!. পরের বার শুধুjava Mainলিখলেই চলবে; কোড না বদলালে আবার compile করতে হয় না।
এক কমান্ডেই চালানো — java Main.java
Java 11 থেকে (JEP 330) একটি শর্টকাট আছে: java Main.java লিখলে java নিজেই ফাইলটি মেমরিতে compile করে সঙ্গে সঙ্গে চালায়। কোনো .class ফাইল ডিস্কে থাকে না। একে বলে source-file mode.
# পুরোনো ও পেশাদার পথ — দুই ধাপ
javac Main.java # Main.class তৈরি হয়
java Main # .class ছাড়া, শুধু class-এর নাম
# Java 11+ শর্টকাট — এক ধাপ, .class তৈরি হয় না
java Main.java| বিষয় | javac + java | java Main.java |
|---|---|---|
.class ফাইল | ডিস্কে থাকে, বারবার চালানো যায় | থাকে না, প্রতিবার নতুন করে compile |
| কোথায় কাজে লাগে | আসল প্রজেক্ট, অনেক ফাইল | শেখা, ছোট স্ক্রিপ্ট, দ্রুত পরীক্ষা |
| একাধিক ফাইল | হ্যাঁ | Java 11–21-এ একটিমাত্র ফাইল; Java 22 থেকে পাশের ফাইলও খুঁজে নিতে পারে |
৬ · JShell — Java-র সাথে সরাসরি কথা বলা
ধরুন আপনি শুধু জানতে চান 7 / 2 Java-তে কত হয়। এর জন্য একটি ফাইল খুলে class লিখে, main লিখে, compile করে চালানো — অনেক ঝামেলা। এই ঝামেলা কমাতে Java 9 (২০১৭) থেকে JDK-র সাথে আসে JShell — Java-র একটি REPL (Read–Eval–Print Loop): আপনি একটি লাইন লিখবেন, সে পড়বে, হিসাব করবে, ফল দেখাবে, তারপর আবার অপেক্ষা করবে।
JShell হলো মোবাইলের ক্যালকুলেটর, আর .java ফাইল হলো দোকানের হিসাবের খাতা। “১২০ টাকা কেজি দরে ৫ কেজি কত?” — ক্যালকুলেটরে দুই সেকেন্ড। কিন্তু মাসের হিসাব খাতায় লেখেন, যাতে কাল আবার দেখা যায়। JShell-এ যা লেখেন, বন্ধ করলেই হারিয়ে যায়।
terminal-এ শুধু jshell লিখে Enter চাপুন। নিচের ডায়াগ্রামে একটি ছোট সেশন ধাপে ধাপে দেখুন — ডান পাশে খেয়াল করুন JShell কোন নামে কোন মান মনে রাখছে:
1jshell> int price = 1202jshell> price * 53jshell> String city = "Dhaka"4jshell> Math.max(3, 7)5jshell> /vars6jshell> /exit
| price | |
| $2 | |
| city | |
| $4 |
- JShell খুলল। terminal-এ
jshellলিখতেই স্বাগত-বার্তা আরjshell>প্রম্পট এলো।jshellJDK-রbinফোল্ডারেই থাকে, তাই PATH ঠিক থাকলে আলাদা কিছু ইনস্টল করতে হয় না। - ভ্যারিয়েবল তৈরি।
int price = 120লিখলেন — শেষে;লাগেনি, JShell নিজেই বুঝে নেয়। উত্তরেprice ==> 120মানে “price নামে 120 রাখা হলো”। কোনো class বাmainলিখতে হয়নি। - নাম ছাড়া হিসাব।
price * 5লিখলেন, কোনো নাম দেননি। JShell নিজেই ফলটির নাম দিল$2— কারণ এটি সেশনের দ্বিতীয় লাইন। পরে$2 + 100লিখে এই মান আবার ব্যবহার করতে পারবেন। - String-ও চলে।
String city = "Dhaka". লক্ষ করুন উত্তরে মানটি উদ্ধৃতিচিহ্নসহ দেখায় — JShell বুঝিয়ে দিচ্ছে এটি String, সংখ্যা নয়। - Standard library সরাসরি।
Math.max(3, 7)— কোনো import ছাড়াইMathclass ব্যবহার করা গেল, ফল$4 ==> 7. কোনো method কী করে, তা দেখার এর চেয়ে দ্রুত উপায় নেই। /vars— কী কী মনে আছে।/দিয়ে শুরু হওয়া লাইন Java কোড নয়, JShell-এর নিজস্ব কমান্ড।/varsসব ভ্যারিয়েবল টাইপসহ দেখায়। আরও কাজের কমান্ড:/list(এ পর্যন্ত লেখা সব লাইন),/help. Tab চাপলে নাম পূরণ করে দেয়।/exit— বের হওয়া। “Goodbye” বলে JShell বন্ধ হলো, সাধারণ প্রম্পট ফিরে এলো। সেশনের সব মান হারিয়ে গেল — তাই যা রাখার, তা ফাইলে লিখতে হয়।
JShell-এ যা এক লাইনে হয়, ফাইলে সেটিই লিখতে হয় class আর main-এর ভেতরে, আর ফল দেখাতে নিজে System.out.println লিখতে হয়। একই হিসাব ফাইলে কেমন দেখায়, চালিয়ে দেখুন:
class Main {
public static void main(String[] args) {
var price = 120; // JShell-এ: int price = 120
var kg = 5;
var total = price * kg;
System.out.println("মোট: " + total);
System.out.println("7 / 2 = " + (7 / 2));
System.out.println("7 / 2.0 = " + (7 / 2.0));
System.out.println("Math.sqrt(144) = " + Math.sqrt(144));
}
}আউটপুট: মোট: 600, 7 / 2 = 3, 7 / 2.0 = 3.5 আর Math.sqrt(144) = 12.0. দুটি পূর্ণসংখ্যার ভাগে Java দশমিক অংশ ফেলে দেয় (3), একটি দশমিক সংখ্যা থাকলে পুরো ফল আসে (3.5). var মানে “টাইপটা ডান পাশ দেখে compiler নিজে ঠিক করুক” — এখানে int. এসব খুঁটিনাটি পর্ব ০৬ ও ০৭-এ বিস্তারিত দেখবেন। এমন ছোট প্রশ্নে আগে JShell-এ চেষ্টা করার অভ্যাস করুন।
৭ · IDE বাছাই, অনলাইন runner আর Maven/Gradle-এর এক ঝলক
IDE (Integrated Development Environment) এক জায়গায় দেয় editor, compile-run বোতাম, debugger আর ভুলের তাৎক্ষণিক ইঙ্গিত। Java-র জন্য চারটি পরিচিত নাম — সবগুলোই বিনা মূল্যে ব্যবহার করা যায়:
IntelliJ IDEA
JetBrains-এর তৈরি; পেশাদার Java জগতে সবচেয়ে বেশি ব্যবহৃত। ফ্রি সংস্করণটি (দীর্ঘদিন “Community Edition” নামে পরিচিত) Java শেখা ও সাধারণ প্রজেক্টের জন্য যথেষ্ট। Android Studio-ও এর ওপর তৈরি।
এই কোর্সের সুপারিশVS Code
হালকা editor; Microsoft-এর “Extension Pack for Java” যোগ করলে Java চালানো, debug আর Maven/Gradle সব চলে। আগে থেকে VS Code ব্যবহার করলে ভালো পছন্দ।
হালকা কম্পিউটারে ভালোEclipse
পুরোনো ও শক্তিশালী ওপেন-সোর্স IDE; অনেক বিশ্ববিদ্যালয়ের ল্যাব আর বড় কোম্পানিতে এখনো চলে।
ওপেন-সোর্সNetBeans
Apache-এর ওপেন-সোর্স IDE; সেটআপ সহজ, GUI (Swing) ডিজাইনের সুবিধা আছে, অনেক পুরোনো পাঠ্যবইয়ে এটিই ব্যবহার করা হয়েছে।
ওপেন-সোর্সIntelliJ-এ প্রথম প্রজেক্ট — পাঁচ ধাপ
- IntelliJ IDEA খুলে New Project চাপুন, বাঁ পাশ থেকে Java বেছে নিন।
- JDK ঘরে আপনার JDK 21 দেখাবে। না দেখালে ড্রপডাউন থেকে “Download JDK” চেপে Temurin 21 বেছে নিন — IntelliJ নিজেই নামিয়ে user ফোল্ডারে রাখবে (admin লাগে না)।
- Build system: শুরুতে “IntelliJ” রাখুন। Maven/Gradle পরে শিখবেন।
- “Add sample code” টিক দিয়ে Create চাপুন।
srcফোল্ডারে একটিMain.javaতৈরি হবে। main-এর পাশের সবুজ ▶ চিহ্নে ক্লিক করুন (বা Shift+F10). নিচে Run জানালায় আউটপুট আসবে — তার ঠিক ওপরে ধূসর লেখায় দেখবেন IntelliJ আসলে কোনjavaকমান্ড চালিয়েছে।
IDE-র নিজের JDK-সেটিং আর terminal-এর PATH আলাদা জিনিস। তাই এমন হতে পারে যে IntelliJ-এ সব চলছে, কিন্তু terminal-এ javac চিনছে না — বা উল্টোটা। IntelliJ-এ ব্যবহৃত JDK দেখতে: File → Project Structure → SDK.
এই সাইটের runner — কেন class Main, public class Main নয়
এই কোর্সের পাতায় “চালান” চাপলে কোড পাঠানো হয় Wandbox নামের একটি অনলাইন সার্ভিসে, যেখানে OpenJDK 21 চলে। সেখানে আপনার কোড prog.java নামের একটি ফাইলে রাখা হয়। Java-র নিয়ম হলো: কোনো class public হলে ফাইলের নাম হুবহু class-এর নামে হতে হবে। prog.java ফাইলে public class Main থাকলে compiler থেমে যায়:
prog.java:1: error: class Main is public, should be declared in a file named Main.java
public class Main {
^
1 error
তাই এই সাইটের runnable কোডে main class-এর আগে public থাকে না। নিজের প্রজেক্টে সাধারণত Main.java ফাইলে public class Main লেখা হয় — দুটিই বৈধ Java. বিকল্প অনলাইন জায়গা হিসেবে OnlineGDB বা Replit ব্যবহার করতে পারেন; সেখানে ফাইলের নাম সাধারণত Main.java, তাই public class Main-ই চলে। মোবাইল থেকে শেখার জন্য এগুলো ভালো, তবে আসল দক্ষতার জন্য নিজের কম্পিউটারে JDK রাখুন।
এক ঝলকে: Maven আর Gradle
একটি-দুটি ফাইলে javac যথেষ্ট। কিন্তু আসল প্রজেক্টে থাকে শত শত ফাইল আর বাইরের অনেক library (যেমন JSON পড়ার, ডেটাবেসে যোগ দেওয়ার)। কোন library-র কোন version লাগবে, কোথা থেকে নামাতে হবে, কোন ক্রমে compile হবে, টেস্ট কখন চলবে — এসব হাতে করা অসম্ভব। এই কাজ করে build tool: Maven (একটি pom.xml ফাইলে প্রজেক্টের বর্ণনা) আর Gradle (build.gradle বা build.gradle.kts ফাইলে)। Spring Boot বা Android-এর যেকোনো প্রজেক্ট এদের একটি দিয়েই চলে। দুটিই JAVA_HOME দেখে JDK খুঁজে নেয় — তাই আজই এটি ঠিক করে রাখা জরুরি। পুরো বিষয়টি পর্ব ৪৬-এ শিখবেন।
৮ · সাধারণ সেটআপ-সমস্যা — আসল মেসেজ, আসল সমাধান
সেটআপে আটকে যাওয়া লজ্জার কিছু নয়; অভিজ্ঞ ডেভেলপাররাও নতুন কম্পিউটারে এসব সমস্যায় পড়েন। পার্থক্য হলো তাঁরা মেসেজ পড়ে বুঝে নেন সমস্যাটি কোন ধাপের। সবচেয়ে পরিচিতটি দিয়ে শুরু:
'javac' is not recognized as an internal or external command,
operable program or batch file.
PowerShell-এ একই কথা আসে The term 'javac' is not recognized... রূপে, আর Mac/Linux-এ command not found: javac. নিচের ধাপগুলো ক্রম মেনে চেষ্টা করুন:
- নতুন terminal?
বন্ধ করে খুলুনসবচেয়ে সহজ কারণ - JDK আছে?
...\bin\javac.exeJRE নয় তো? - PATH দেখুন
echo %PATH%bin আছে কি? - PATH-এ যোগ
%JAVA_HOME%\binNew চেপে, ওপরে তুলে - যাচাই
where javacনতুন terminal-এ
ইনস্টলের আগে খোলা Command Prompt, PowerShell, VS Code → খোলার মুহূর্তের PATH-এর কপি নিয়ে বসে আছে সব বন্ধ করে আবার খুলুন, তারপর javac -version
C:\Program Files\Eclipse Adoptium\jdk-21.0.5.11-hotspot\bin\
javac.exe java.exe jshell.exe jar.exe ...
শুধু java.exe আছে, javac.exe নেই?
→ এটি JRE বা Oracle-এর javapath; JDK ইনস্টল করুন
> echo %JAVA_HOME%
C:\Program Files\Eclipse Adoptium\jdk-21.0.5.11-hotspot
> echo %PATH%
C:\Windows\system32;C:\Windows;...
← কোথাও ...\jdk-21...\bin নেই!
User variables: JAVA_HOME = C:\Program Files\Eclipse Adoptium\jdk-21.0.5.11-hotspot Path → Edit → New: %JAVA_HOME%\bin ← Move Up দিয়ে ওপরে [OK] [OK] [OK]
> where javac C:\Program Files\Eclipse Adoptium\jdk-21.0.5.11-hotspot\bin\javac.exe > javac -version javac 21.0.5 > java -version openjdk version "21.0.5" ... ← দুটোই 21
- আগে terminal নতুন করে খুলুন। environment variable বদলালে আগে থেকে খোলা জানালা সেটা জানতে পারে না। সব terminal আর IDE বন্ধ করে আবার খুলুন। অনেক সময় এতেই সমাধান হয়ে যায়।
- JDK আসলেই আছে কি না দেখুন। File Explorer-এ JDK-র
binফোল্ডার খুলুন, সেখানেjavac.exeআছে কি না দেখুন। শুধুjava.exeথাকলে আপনি JRE বা Oracle-এরjavapathফোল্ডার দেখছেন — compiler সেখানে থাকে না। তখন JDK ইনস্টল করুন। - PATH-এ
binআছে কি না দেখুন।echo %PATH%দীর্ঘ একটি লাইন দেখাবে। সেখানে JDK-রbinফোল্ডার না থাকলে shell কখনোjavacখুঁজে পাবে না। একটি সাধারণ ভুল: PATH-এ...\jdk-21যোগ করা হয়েছে, কিন্তু শেষে\binনেই। - PATH-এ যোগ করুন — নিরাপদ উপায়ে। Windows-এর সার্চে “environment variables” লিখে জানালাটি খুলুন।
JAVA_HOMEতৈরি করুন JDK-র মূল ফোল্ডার দিয়ে (শেষে\binছাড়া)। তারপর Path-এ “New” চেপে%JAVA_HOME%\binযোগ করুন, আর “Move Up” দিয়ে অন্য কোনো Java ফোল্ডারের ওপরে তুলুন। পুরো PATH মুছে নতুন করে লিখবেন না। - নতুন terminal-এ যাচাই করুন।
where javacএখন JDK-র পথ দেখাবে। শেষ পরীক্ষা হিসেবেjava -versionআরjavac -versionদুটোই চালান — দুটির নম্বর মিলতে হবে। Mac/Linux-এ একই যাচাইwhich javacআরecho $JAVA_HOMEদিয়ে।
UnsupportedClassVersionError — নম্বর পড়তে শিখুন
অংশ ৪-এ তানভীরের error দেখেছিলেন। মেসেজটি ভয়ের মনে হলেও আসলে খুব সৎ — দুটি নম্বরেই পুরো গল্প বলা আছে। ধাপে ধাপে দেখি:
- JDK 21-এ compile
javac Main.javaনতুন compiler - version ছাপ
major = 65class ফাইলের মাথায় - Java 8-এ run
সর্বোচ্চ 52পুরোনো JVM - সমাধান
দুটি একই JDKঅথবা --release
> javac -version javac 21.0.5 > javac Main.java (কিছু ছাপা হলো না — সফল)
minor version: 0 major version: 65 Java 8 → 52 · Java 11 → 55 · Java 17 → 61 Java 21 → 65 · Java 25 → 69 (version + 44)
> java Main
Exception in thread "main" java.lang.UnsupportedClassVersionError:
Main has been compiled by a more recent version of the Java Runtime
(class file version 65.0), this version of the Java Runtime only
recognizes class file versions up to 52.0
পথ ১: PATH ঠিক করে java-কেও JDK 21 থেকে আনুন > where java ← প্রথম লাইনে jdk-21 আসা চাই পথ ২: পুরোনো সার্ভারের জন্য পুরোনো version-এ compile > javac --release 17 Main.java ← Java 17-এ চলবে
- নতুন compiler দিয়ে compile.
javacPATH থেকে এলো JDK 21 থেকে। কোনো error নেই,Main.classতৈরি হলো। এ পর্যন্ত সব স্বাভাবিক। - class ফাইলের গায়ে version-এর ছাপ। প্রতিটি
.classফাইলের শুরুতে একটি “major version” নম্বর লেখা থাকে। Java 5 থেকে নিয়মটা সহজ: Java-র version + ৪৪. তাই Java 8 = 52, Java 17 = 61, Java 21 = 65. JDK-রjavap -vকমান্ড দিয়ে যেকোনো class ফাইলের এই নম্বর দেখা যায়। - পুরোনো JVM অচেনা version দেখে থেমে গেল।
javaএলো Java 8 থেকে, যে সর্বোচ্চ 52 পর্যন্ত চেনে। 65 দেখে সে বুঝল এই ফাইলে এমন কিছু থাকতে পারে যা সে জানে না — তাই চালানোর ঝুঁকি না নিয়ে থেমে গেল। মেসেজে দুটি নম্বরই আছে: ফাইলটি 65 (Java 21), JVM বোঝে 52 (Java 8) পর্যন্ত। উল্টোটা কিন্তু চলে — Java 8-এ বানানো class ফাইল Java 21-এ নিশ্চিন্তে চলে। - সমাধান — পরিস্থিতি বুঝে। নিজের কম্পিউটারে হলে PATH ঠিক করুন, যাতে
javaআরjavacএকই JDK থেকে আসে। আর যদি প্রোগ্রামটি এমন সার্ভারে চালাতে হয় যেখানে পুরোনো Java আছে, তবেjavac --release 17দিয়ে compile করুন — compiler তখন Java 17-এর নিয়ম ও library মেনে ফাইল বানায়, version নম্বরও হয় 61.
আরও কয়েকটি পরিচিত সমস্যা
| যা দেখছেন | আসল কারণ | সমাধান |
|---|---|---|
class Main is public, should be declared in a file named Main.java | ফাইলের নাম আর public class-এর নাম আলাদা (যেমন hello.java বা Main (1).java). বড়-ছোট হাতের অক্ষরও মিলতে হবে | ফাইলের নাম বদলে Main.java করুন |
Error: Could not find or load main class Main.class | java Main.class লিখেছেন | শুধু java Main লিখুন |
Error: Could not find or load main class Main | ভুল ফোল্ডারে আছেন, অথবা javac চালানোই হয়নি | dir (Mac/Linux-এ ls) দিয়ে দেখুন Main.class আছে কি না |
Maven/Gradle বলছে JAVA_HOME is not defined correctly বা ভুল version নিচ্ছে | JAVA_HOME নেই, ভুল ফোল্ডার দেখাচ্ছে, অথবা শেষে \bin যোগ করা হয়েছে | JAVA_HOME = JDK-র মূল ফোল্ডার, \bin ছাড়া |
java -version আর javac -version ভিন্ন নম্বর দেখায় | দুটি JDK ইনস্টল আছে, PATH-এ ভুলটি আগে | where java দেখে PATH-এর ক্রম ঠিক করুন, অথবা অপ্রয়োজনীয়টি আনইনস্টল করুন |
বাংলা লেখা — source ফাইল আর Windows console
আপনার কোডে "মোট: "-এর মতো বাংলা লেখা থাকলে দুটি আলাদা প্রশ্ন আসে। প্রথম প্রশ্ন: compiler কি ফাইলটি ঠিকভাবে পড়ছে? Java 18 থেকে (JEP 400) ডিফল্ট UTF-8, তাই UTF-8-এ সেভ করা ফাইল javac ঠিকঠাক পড়ে। Java 17 বা তার আগের JDK-তে Windows-এ ডিফল্ট ছিল অন্য encoding, তখন javac -encoding UTF-8 Main.java লিখতে হতো। (IntelliJ ও VS Code ডিফল্টে ফাইল UTF-8-এ সেভ করে।)
দ্বিতীয় প্রশ্ন: console কি বাংলা দেখাতে পারছে? পুরোনো Windows Command Prompt প্রায়ই অন্য code page-এ চলে। তখন বাংলার জায়গায় ??? বা ভাঙা অক্ষর আসে — যদিও প্রোগ্রাম ঠিকই আছে। এ ক্ষেত্রে সাধারণত এটুকু কাজে দেয়:
chcp 65001
java -Dstdout.encoding=UTF-8 Main.javachcp 65001 console-কে UTF-8-এ নেয়, আর -Dstdout.encoding=UTF-8 (Java 19 থেকে আছে) JVM-কে বলে আউটপুট UTF-8-এ পাঠাতে। এরপরও অক্ষর ভাঙলে সমস্যা ফন্টে — Windows Terminal ব্যবহার করুন, যার ফন্ট বাংলা দেখাতে পারে। মনে রাখবেন, এটি শুধু দেখানোর সমস্যা; IDE-র Run জানালা আর এই সাইটের runner-এ বাংলা আউটপুট সাধারণত কোনো ঝামেলা ছাড়াই আসে।
৯ · AI-এর যুগে সেটআপ — সহকারী আছে, যাচাই আপনার
সেটআপে আটকে গেলে AI-কে জিজ্ঞেস করা স্বাভাবিক। সমস্যা হলো, AI শিখেছে ইন্টারনেটের বহু বছরের লেখা থেকে — আর Java-র সেটআপ নিয়ে সবচেয়ে বেশি লেখা হয়েছে Java 8-এর যুগে। তাই AI প্রায়ই আত্মবিশ্বাসের সাথে পুরোনো পরামর্শ দেয়। কয়েকটি চেনা উদাহরণ:
| AI যা বলতে পারে | সমস্যা কোথায় | আজকের ঠিক পথ |
|---|---|---|
| “java.com থেকে Java ডাউনলোড করুন” | ওটি সাধারণ ব্যবহারকারীর জন্য পুরোনো runtime; সেখানে javac নেই | JDK নিন — Temurin বা অন্য OpenJDK build |
| “Java 8 ইনস্টল করুন, এটাই সবচেয়ে স্থিতিশীল” | record, var, switch expression, text block কিছুই নেই | Java 21 বা 25 (LTS) |
| শুধু Oracle-এর ডাউনলোড লিংক | লাইসেন্সের শর্ত না জেনে কোম্পানিতে ব্যবহার করলে ঝামেলা হতে পারে | বিকল্পগুলো জানুন; শর্ত নিজে পড়ুন |
“setx PATH "%PATH%;C:\...\bin" চালান” | ১০২৪ অক্ষরের বেশি PATH কেটে যায়, system ও user PATH মিশে যায় | Environment Variables জানালায় New চেপে যোগ |
“CLASSPATH environment variable সেট করুন” | অপ্রয়োজনীয়; ভুল মান দিলে Could not find or load main class আসে | সাধারণত CLASSPATH সেট করার দরকারই নেই |
| “JAVA_HOME = ...\jdk-21\bin” | শেষে \bin ভুল — Maven/Gradle JDK খুঁজে পাবে না | JAVA_HOME = JDK-র মূল ফোল্ডার; PATH-এ %JAVA_HOME%\bin |
AI-কে কাজে লাগানোর কৌশল হলো তাকে আপনার যন্ত্রের পুরো ছবি দেওয়া, আর আধুনিক উত্তর দাবি করা। নিচের কাঠামোয় প্রশ্ন করুন — বন্ধনীর জায়গায় নিজের তথ্য বসান:
AI-এর সেটআপ-পরামর্শ মানার আগে — চেকলিস্ট
- JDK, JRE আর JVM-এর পার্থক্য কী? — JVM bytecode চালায়; JRE = JVM + library; JDK = JRE +
javac-সহ ডেভেলপমেন্ট টুল। - Java platform-independent, কিন্তু JVM কি platform-independent? — না; bytecode সব জায়গায় এক, কিন্তু প্রতিটি OS-এর জন্য আলাদা JVM লাগে।
javacকী তৈরি করে? — প্রতিটি class-এর জন্য একটি.classফাইল, যার ভেতরে bytecode.- PATH আর JAVA_HOME-এর কাজ কী? — PATH দিয়ে shell
java/javacখুঁজে পায়; JAVA_HOME দিয়ে Maven, Gradle ও অন্যান্য টুল JDK খুঁজে পায়। UnsupportedClassVersionErrorকেন হয়? — নতুন JDK-তে compile করা class পুরোনো JVM-এ চালালে।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিয়ে নিজে কিছুক্ষণ ভাবুন — তারপর “→ উত্তর” চাপুন। এখানে সেটআপের পেছনের ইতিহাস আর নকশার যুক্তি আছে।
প্র ০১Java-র জন্য কেন JAVA_HOME আর PATH দুটোই লাগে? এই ব্যবস্থা কোথা থেকে এলো, আর আধুনিক টুল একে কীভাবে সহজ করছে?
PATH Java-র আবিষ্কার নয়। এটি Unix আর MS-DOS-এর যুগ থেকে আসা একটি সাধারণ ব্যবস্থা: shell-কে বলে দেওয়া, কোন কোন ফোল্ডারে প্রোগ্রাম খুঁজতে হবে। প্রতিটি কমান্ডের পূর্ণ ঠিকানা লেখার বদলে আপনি শুধু নাম লেখেন, shell তালিকা ধরে খোঁজে, প্রথম মিলটিই চালায়। “প্রথম মিল” নিয়মটাই দুটি JDK থাকলে বিভ্রান্তির উৎস — যার ফোল্ডার আগে, সে জেতে।
JAVA_HOME এসেছে টুলের প্রয়োজনে। ১৯৯০-এর দশকের শেষ আর ২০০০-এর দশকের শুরুতে Ant, Tomcat আর পরে Maven-এর মতো টুলগুলো শুধু java চালিয়েই খুশি ছিল না। তাদের দরকার ছিল JDK-র পুরো ফোল্ডার — compiler-এর library (তখন tools.jar), header ফাইল, অন্যান্য টুল। PATH থেকে উল্টো দিকে JDK-র মূল ফোল্ডার বের করা ঝামেলার আর ভঙ্গুর, তাই প্রচলিত হলো একটি রীতি: “JDK-র মূল ফোল্ডার JAVA_HOME-এ রাখো।” এটি Java ভাষার কোনো নিয়ম নয়, সম্প্রদায়ের একটি চুক্তি — এজন্যই java নিজে JAVA_HOME পড়ে না, কিন্তু Maven না পেলে অভিযোগ করে।
এই ব্যবস্থার দুর্বলতা হলো দুটি আলাদা জায়গায় একই তথ্য রাখা। PATH এক JDK দেখায়, JAVA_HOME আরেকটি — এমন অমিল খুবই সাধারণ, আর তখন terminal-এ এক version আর Maven-এ আরেক version চলে।
আধুনিক সমাধানগুলো এই হাতের কাজ কমাচ্ছে। SDKMAN (Mac/Linux) আর Linux-এর update-alternatives একসাথে দুটোই বদলায়। IntelliJ প্রতিটি প্রজেক্টের জন্য আলাদা JDK মনে রাখে, এমনকি নিজেই নামিয়ে দেয়। Gradle-এর “toolchain” আর Maven-এর “toolchains” সুবিধায় প্রজেক্টের ফাইলেই লেখা থাকে “আমার Java 21 লাগবে”, আর টুল নিজে খুঁজে নেয় — Gradle দরকার হলে নামিয়েও আনতে পারে। ফলে একই কম্পিউটারে Java 8-এর পুরোনো প্রজেক্ট আর Java 21-এর নতুন প্রজেক্ট পাশাপাশি চলে।
মূল উপলব্ধি: “কোন প্রোগ্রাম চলবে” — এই সিদ্ধান্ত OS নেয় একটি সাধারণ তালিকা দেখে। তালিকাটি পড়তে জানলে সেটআপের বেশিরভাগ রহস্য মিলিয়ে যায়। আর পেশাদার পথ হলো version-এর সিদ্ধান্ত গ্লোবাল সেটিং থেকে সরিয়ে প্রজেক্টের ভেতরে লিখে রাখা।
প্র ০২একটাই Java, তবু এত JDK distribution কেন? ২০১৯ সালের লাইসেন্স-পরিবর্তন আর Adoptium-এর উত্থানের গল্পটা কী?
শুরুটা ওপেন-সোর্স দিয়ে। ২০০৬–২০০৭ সালে Sun Microsystems Java-কে ওপেন-সোর্স করে, প্রজেক্টের নাম হয় OpenJDK, লাইসেন্স GPL (সাথে “Classpath Exception”, যাতে আপনার নিজের প্রোগ্রামকে GPL হতে না হয়)। ২০১০ সালে Oracle Sun-কে কিনে নেয়। এরপর বহু বছর মানুষ অভ্যস্ত ছিল একটি জিনিসে: Oracle-এর ওয়েবসাইট থেকে JDK নামাও, বিনা মূল্যে যেকোনো কাজে ব্যবহার করো।
বদলের সূচনা ২০১৭–২০১৯। Java 9-এর পর Oracle ছয় মাস পরপর নতুন version প্রকাশের নিয়ম চালু করে। সাথে Oracle দুটি আলাদা build দিতে শুরু করে — GPL লাইসেন্সের OpenJDK build (প্রতিটি version-এ মাত্র ছয় মাস আপডেট) আর বাণিজ্যিক শর্তের Oracle JDK. ২০১৯ সালের শুরু থেকে Java 8-এর নতুন আপডেট বাণিজ্যিক ব্যবহারে বিনা মূল্যে পাওয়া বন্ধ হয়। বহু কোম্পানির জন্য এটি ছিল ধাক্কা — তাদের লাখো সার্ভারে Java 8 চলছিল।
সম্প্রদায়ের জবাব। যেহেতু সোর্স কোড GPL-এ খোলা, যে কেউ build করে বিতরণ করতে পারে। ২০১৭ সালে শুরু হওয়া AdoptOpenJDK প্রজেক্ট বিনা মূল্যের, পরীক্ষিত build দিতে থাকে; পরে এটি Eclipse Foundation-এ গিয়ে Eclipse Adoptium নাম নেয়, আর build-এর নাম হয় Temurin. Amazon আনে Corretto, Microsoft আনে নিজের build, Azul, Red Hat, SAP-সহ আরও অনেকে দীর্ঘমেয়াদি আপডেট দিতে থাকে। কয়েকটি বড় প্রতিষ্ঠান মিলে পুরোনো LTS version-এর নিরাপত্তা-সংশোধনও OpenJDK-তে জমা দেয়।
এরপর থেকে Oracle-এর শর্ত আরও কয়েকবার বদলেছে — কিছু সময়ের জন্য Oracle JDK আবার বিনা মূল্যে ব্যবহারের শর্তে দেওয়া হয়েছে, সাবস্ক্রিপশনের হিসাবের নিয়মও বদলেছে। বিস্তারিত সময়ের সাথে বদলায়, তাই কোম্পানিতে ব্যবহারের আগে সবসময় বর্তমান শর্ত পড়ে নেওয়াই নিয়ম।
প্রযুক্তিগতভাবে তফাত কতটা? খুব সামান্য। প্রায় সব distribution একই OpenJDK সোর্স থেকে আসে, আর Java-র সামঞ্জস্য-পরীক্ষা (TCK) পাস করে। তফাত থাকে কতদিন আপডেট আসবে, কোন প্ল্যাটফর্মে প্যাকেজ আছে, আর কেউ টাকা নিয়ে সাপোর্ট দেয় কি না তাতে।
মূল উপলব্ধি: ওপেন-সোর্স লাইসেন্স একটি প্রযুক্তিকে কোনো একক কোম্পানির সিদ্ধান্ত থেকে রক্ষা করতে পারে। Java-র ক্ষেত্রে তা-ই হয়েছে — এক কোম্পানি নিয়ম বদলালেও ভাষাটি সবার জন্য খোলা থেকে গেছে।
প্র ০৩Lisp-এ ১৯৬০-এর দশকেই REPL ছিল, Python-এ শুরু থেকে। তাহলে Java-তে অফিসিয়াল REPL (JShell) আসতে প্রায় ২০ বছর লাগল কেন?
Java-র নকশাই ছিল “ফাইল আর class”-কেন্দ্রিক। Java-তে প্রতিটি কোড কোনো না কোনো class-এর ভেতরে থাকতে হয়, প্রোগ্রাম শুরু হয় public static void main থেকে, আর চালানোর আগে পুরো ফাইল compile হয়। “একটি লাইন লিখে সঙ্গে সঙ্গে চালাও” — এই ধারণা সেই কাঠামোয় সহজে বসে না। একটি লাইন কোন class-এ থাকবে? আগের লাইনের ভ্যারিয়েবল পরের লাইন কীভাবে দেখবে?
সংস্কৃতিও ভূমিকা রেখেছে। ১৯৯৫ সালে Java এসেছিল বড় সফটওয়্যার, কঠোর টাইপ-যাচাই আর IDE-নির্ভর কাজের জন্য। Eclipse-এর “scrapbook page” বা BeanShell-এর মতো তৃতীয় পক্ষের কিছু ব্যবস্থা ছিল, কিন্তু JDK-র অংশ হিসেবে অফিসিয়াল কিছু ছিল না।
চাপ এসেছিল শিক্ষা থেকে। শিক্ষকেরা বহু বছর অভিযোগ করেছেন — “Hello World” লিখতেই নতুনদের class, public, static, void, String[] সব একসাথে দেখতে হয়, যার কোনোটিই তখন বোঝানো যায় না। এই সময়ে Python, Scala, Clojure-এর মতো REPL-সমৃদ্ধ ভাষা জনপ্রিয় হচ্ছিল, আর অনেক বিশ্ববিদ্যালয় প্রথম ভাষা হিসেবে Java থেকে Python-এ সরে যাচ্ছিল।
JEP 222 আর JShell (Java 9, ২০১৭)। সমাধানটি চতুর: JShell প্রতিটি লাইনকে (snippet) ভেতরে ভেতরে একটি লুকানো class-এ মুড়ে দেয়, আসল javac দিয়ে compile করে, আর চলমান JVM-এ লোড করে। তাই JShell-এর টাইপ-যাচাই হুবহু আসল Java-র মতো — এটি “Java-সদৃশ” কিছু নয়, খাঁটি Java. শেষের ; ঐচ্ছিক, আর কোনো method আগে ব্যবহার করে পরে সংজ্ঞায়িত করলেও JShell মেনে নেয়।
একই চিন্তার ধারাবাহিকতা দেখা যায় পরের বছরগুলোতে: Java 11-এ এক ফাইল সরাসরি চালানো (JEP 330), আর Java 21-এ preview হিসেবে শুরু হয়ে Java 25-এ স্থায়ী হওয়া ছোট আকারের main (class ছাড়াই void main() লেখা যায়)। লক্ষ্য একটাই — শুরুর বাধা কমানো, অথচ বড় প্রজেক্টের কঠোরতা না হারানো।
মূল উপলব্ধি: একটি ভাষার নকশার সিদ্ধান্ত (সবকিছু class-এ) সুবিধা দেয় বড় সফটওয়্যারে, কিন্তু দাম দিতে হয় শুরুর সহজতায়। পরিণত ভাষা মূল নীতি না ভেঙে সেই দাম কমানোর পথ খোঁজে — JShell তার ভালো উদাহরণ।
প্র ০৪class file-এর version নম্বর (52, 61, 65…) কেন আছে? পুরোনো class নতুন JVM-এ চলে, কিন্তু উল্টোটা চলে না কেন — আর --release কোন সমস্যার সমাধান করে?
version নম্বর হলো একটি প্রতিশ্রুতির লেবেল। প্রতিটি .class ফাইল শুরু হয় চার byte-এর “magic number” CAFEBABE দিয়ে, তারপর minor ও major version. JVM ফাইল খুলেই আগে এই নম্বর দেখে। Java 1.0 ও 1.1 ছিল 45, তারপর প্রতি version-এ এক করে বেড়েছে — Java 8 = 52, 11 = 55, 17 = 61, 21 = 65, 25 = 69.
কেন নতুন ফাইল পুরোনো JVM-এ চলে না? প্রতিটি নতুন version-এ class ফাইলে নতুন জিনিস যোগ হতে পারে — নতুন bytecode নির্দেশ (যেমন Java 7-এর invokedynamic, যার ওপর Java 8-এর lambda দাঁড়িয়ে), নতুন attribute (record, sealed class, nest-এর তথ্য)। পুরোনো JVM এগুলো চেনে না। আন্দাজে চালালে ভুল আচরণ বা নিরাপত্তা-ঝুঁকি হতে পারত। তাই সে সৎভাবে প্রথমেই থেমে যায় — UnsupportedClassVersionError.
উল্টো দিকে Java-র প্রতিশ্রুতি খুব শক্ত। Java ভাষার নিয়মে “binary compatibility”-র একটি পুরো অধ্যায় আছে। নতুন JVM পুরোনো সব version-এর class ফাইল চালাতে বাধ্য। এজন্যই ২০ বছর আগের কোনো .jar আজকের JVM-এ প্রায়ই কোনো বদল ছাড়াই চলে — ব্যাংক, সরকারি সিস্টেম আর বড় কোম্পানি Java-কে বিশ্বাস করে মূলত এই কারণে। (ব্যতিক্রমও আছে: যেসব অভ্যন্তরীণ API কখনো প্রকাশ্য ছিল না, বা যা বহু বছর সতর্কবার্তার পর সরানো হয়েছে।)
-target-এর একটি গোপন ফাঁদ। আগে পুরোনো JVM-এর জন্য compile করতে লেখা হতো -source 8 -target 8. এতে version নম্বর 52 হতো ঠিকই, কিন্তু compiler যাচাই করত নতুন JDK-র library দিয়ে। ফলে কোডে Java 11-এর কোনো নতুন method থাকলে compile সফল হতো, অথচ Java 8-এ চালানোর সময় NoSuchMethodError. Java 9-এ আসা --release (JEP 247) এই ফাঁদ বন্ধ করে — compiler সেই version-এর ভাষার নিয়ম আর সেই version-এর library-র তালিকা, দুটিই মেনে চলে।
বাড়তি একটি তথ্য: preview feature ব্যবহার করে compile করলে class ফাইলের minor version হয় 65535 — তখন সেটি শুধু ঠিক সেই JDK-তে --enable-preview দিয়েই চলে, যাতে অস্থায়ী feature ভুল করে production-এ না ঢোকে।
মূল উপলব্ধি: সামঞ্জস্য এক দিকে সহজ, দুই দিকে অসম্ভব। ভালো সিস্টেম নিজের সীমা স্পষ্ট লেবেলে লিখে রাখে আর অচেনা কিছু দেখলে চুপচাপ ভুল না করে স্পষ্টভাবে থেমে যায়।
প্র ০৫java Main.java (JEP 330, Java 11) কীভাবে কাজ করে? Java 22-এর multi-file launch (JEP 458) কী যোগ করল — আর এগুলো কি Maven/Gradle-এর বিকল্প?
JEP 330-এর উদ্দেশ্য ছিল দুটি: নতুনদের জন্য প্রথম ধাপ সহজ করা, আর ছোট স্ক্রিপ্ট লেখাকে স্বাভাবিক করা। Java 11-এর আগে সবচেয়ে ছোট প্রোগ্রাম চালাতেও দুটি কমান্ড লাগত, আর ফোল্ডারে .class ফাইল জমত।
ভেতরে কী হয়? java launcher দেখে আর্গুমেন্টটি .java-তে শেষ হয়েছে। তখন সে JDK-র ভেতরের compiler (javac-এর একই ইঞ্জিন) দিয়ে ফাইলটি মেমরিতে compile করে, তৈরি class-গুলো সরাসরি নিজের মেমরিতে লোড করে, আর ফাইলের প্রথম top-level class-এর main চালায়। ডিস্কে কিছুই লেখা হয় না। এই মোডে ফাইলের নাম আর public class-এর নাম মেলানোর বাধ্যবাধকতাও কঠোরভাবে প্রয়োগ হয় না। Mac/Linux-এ ফাইলের প্রথম লাইনে “shebang” (#!) দিয়ে Java ফাইলকে সরাসরি স্ক্রিপ্টের মতো চালানোও যায় (তখন ফাইলের নামে .java থাকে না, আর --source option লাগে)।
সীমাবদ্ধতা: Java 11 থেকে 21 পর্যন্ত এই মোড শুধু একটি ফাইল compile করত। Main.java যদি পাশের Helper.java-র class ব্যবহার করত, error আসত।
JEP 458 (Java 22) এই সীমা তুলে দেয়: launch করা ফাইলটি অন্য কোনো class-এর উল্লেখ করলে launcher সেই ফোল্ডার-কাঠামোর মধ্যে মিলমতো .java ফাইল খুঁজে নিয়ে দরকার অনুযায়ী compile করে। ফলে একটি ছোট প্রজেক্ট কয়েকটি ফাইলে ভাগ করেও কোনো build tool ছাড়া চালানো যায়, আর --class-path দিয়ে তৈরি .jar library-ও যোগ করা যায়। এর সাথে Java 25-এ স্থায়ী হওয়া ছোট আকারের main মিলিয়ে শুরুর অভিজ্ঞতা এখন অনেক হালকা।
তাহলে কি Maven/Gradle লাগবে না? লাগবে। source-file mode বাইরের library ইন্টারনেট থেকে নামায় না, version-এর হিসাব রাখে না, টেস্ট চালায় না, প্রকাশযোগ্য .jar বানায় না, আর প্রতিবার নতুন করে compile করে — বড় প্রজেক্টে যা ধীর। JEP-গুলোর নিজস্ব ভাষ্যও এমন: এটি ছোট প্রোগ্রাম থেকে বড় প্রজেক্টে যাওয়ার “মসৃণ সিঁড়ি”, build tool-এর প্রতিস্থাপন নয়।
মূল উপলব্ধি: ভালো টুল-নকশা শুরুটা সহজ রাখে, কিন্তু বড় হওয়ার পথ বন্ধ করে না। আজ java Main.java দিয়ে শুরু করুন; প্রজেক্ট বড় হলে পর্ব ৪৬-এর Maven/Gradle-এ যাওয়া স্বাভাবিক পরের ধাপ।
অনুশীলন
বেশিরভাগ কাজে কোড লিখতে হবে না — নিজের কম্পিউটারে চালিয়ে দেখা আর ব্যাখ্যা করাই আসল কাজ।
-
নিজের যন্ত্রের রিপোর্ট: নতুন terminal-এ চারটি কমান্ড চালান —
where java(Mac/Linux-এwhich java),java -version,javac -version,echo %JAVA_HOME%. প্রতিটির আউটপুট দেখে লিখুন: কয়টি Java আছে, কোনটি চলছে, আর সব ঠিক আছে কি না।সব ঠিক থাকলে:
where java-এর প্রথম লাইন JDK 21 (বা 25)-এরbinফোল্ডার,java -versionওjavac -versionদুটোতেই একই প্রথম নম্বর, আর JAVA_HOME সেই একই JDK-র মূল ফোল্ডার (শেষে\binছাড়া)।where javaএকাধিক লাইন দেখালে কম্পিউটারে একাধিক Java আছে — সমস্যা নয়, যদি প্রথম লাইনটি আপনার চাওয়া JDK হয়।javapathবা পুরোনো version প্রথমে থাকলে অংশ ৮-এর ধাপগুলো অনুসরণ করুন।echo %JAVA_HOME%যদি হুবহু%JAVA_HOME%ছাপে, তার মানে variable-টি সেট করাই হয়নি। -
JShell-এ অনুমান আর যাচাই: JShell খুলে লেখার আগে খাতায় অনুমান লিখুন, তারপর চালান:
int x = 7,x / 2,x / 2.0,x % 2,"Java " + x, তারপর/varsআর/list.x ==> 7,$2 ==> 3(দুটি int-এর ভাগে দশমিক বাদ),$3 ==> 3.5,$4 ==> 1(ভাগশেষ),$5 ==> "Java 7"(String-এর সাথে+মানে জোড়া লাগানো)।/varsদেখাবেint x = 7,int $2 = 3,double $3 = 3.5,int $4 = 1,String $5 = "Java 7"— লক্ষ করুন JShell প্রতিটির টাইপ নিজেই ঠিক করেছে।/listলেখা লাইনগুলো ক্রমিক নম্বরসহ দেখাবে। কোন অনুমান ভুল হলো, সেটিই আপনার শেখার জায়গা। -
Error শিকারি: প্রতিটি মেসেজের কারণ আর সমাধান বলুন — (ক)
'javac' is not recognized as an internal or external command(খ)error: class Calculator is public, should be declared in a file named Calculator.java(গ)Error: Could not find or load main class Main.class(ঘ)class file version 61.0 ... only recognizes class file versions up to 55.0(ক) shell PATH-এ
javacপায়নি — JDK নেই, শুধু JRE আছে, অথবা JDK-রbinPATH-এ নেই। নতুন terminal, তারপর PATH ঠিক করুন।(খ)
public class Calculatorএমন ফাইলে আছে যার নামCalculator.javaনয়। ফাইলের নাম বদলান।(গ)
java-কে ফাইলের নাম দেওয়া হয়েছে; শুধু class-এর নাম লিখুন —java Main.(ঘ) 61 = Java 17-এ compile, 55 = Java 11-এর JVM-এ চালানো হয়েছে। হয় Java 17 বা নতুন JVM ব্যবহার করুন, নয়তো
javac --release 11দিয়ে compile করুন। -
class ফাইলের ভেতরে উঁকি: একটি
Main.javaলিখেjavac Main.javaচালান, তারপরjavap -v Main.classচালিয়ে “major version” লাইনটি খুঁজুন (Windows-এjavap -v Main.class | findstr major, Mac/Linux-এ| grep major). এবারjavac --release 17 Main.javaদিয়ে আবার compile করে একই কাজ করুন। কী বদলাল, কেন?JDK 21 দিয়ে স্বাভাবিক compile-এ দেখবেন
major version: 65(JDK 25 হলে 69).--release 17দিলে হবেmajor version: 61. compiler এখন Java 17-এর নিয়মে ফাইল বানিয়েছে, তাই এটি Java 17-এর JVM-এও চলবে। কোডে Java 17-এর পরে আসা কোনো method বা ভাষার feature থাকলে--release 17-এ compile-ই হবে না — এটাই--release-এর সুরক্ষা।javapJDK-র আরেকটি টুল, যা class ফাইল খুলে পড়ে দেখায়; পর্ব ০৫-এ bytecode দেখতেও এটি কাজে লাগবে।
নিজেকে যাচাই করুন
ভুল হলে কারণসহ ব্যাখ্যা পাবেন, আবার চেষ্টাও করতে পারবেন।
ক্রমterminal-এ একটি Java প্রোগ্রাম চালানোর ধাপগুলো সঠিক ক্রমে সাজান (▲▼ চেপে সরান)
- ✍️
Main.javaফাইলে কোড লেখা - 🔎
javac Main.java— shell PATH-এ compiler খুঁজে পায় - 📦
Main.classতৈরি — ভেতরে bytecode - ⚙️
java Main— JVM class লোড ও যাচাই করে - 🖥️
mainmethod চলে, স্ক্রিনে আউটপুট আসে
Java প্রোগ্রাম লিখে compile করতে চাইলে কম্পিউটারে ন্যূনতম কোনটি থাকতে হবে?
- শুধু JVM
- JRE
- JDK
- শুধু একটি IDE
UnsupportedClassVersionError: ... (class file version 65.0), this version of the Java Runtime only recognizes class file versions up to 52.0 — এর অর্থ কী?
- Java 8-এ compile করে Java 21-এ চালানো হয়েছে
- Java 21-এ compile করে Java 8-এর JVM-এ চালানো হয়েছে
- কোডে syntax-এর ভুল আছে
- Main.class ফাইলটি খুঁজে পাওয়া যায়নি
Windows-এ 'javac' is not recognized as an internal or external command আসার সবচেয়ে সম্ভাব্য কারণ কোনটি?
- Main.java ফাইলে syntax ভুল
- Java 21 খুব নতুন version
- JAVA_HOME-এর শেষে \bin নেই
- PATH-এ JDK-র bin ফোল্ডার নেই, অথবা JDK-ই ইনস্টল হয়নি
Hello.java নামের ফাইলের ভেতরে লেখা আছে public class Main { ... }. javac Hello.java চালালে কী হবে?
- error: class Main is public, should be declared in a file named Main.java
- Hello.class তৈরি হবে
- compile হবে, কিন্তু চালানোর সময় error
- নতুন JDK-তে কোনো সমস্যা হবে না, পুরোনোতে হবে
JShell সম্পর্কে কোন কথাটি সঠিক?
- এটি আলাদা ইনস্টল করতে হয়
- প্রতিটি লাইন একটি class-এর ভেতরে লিখতে হয়
- এটি Java 9 থেকে JDK-র অংশ, আর /exit লিখে বের হওয়া যায়
- JShell-এ লেখা কোড নিজে থেকে .java ফাইলে সেভ হয়
Java 11 বা নতুন JDK-তে java Main.java লিখলে কী হয়?
- error — java শুধু .class ফাইল চালায়
- ফাইলটি মেমরিতে compile হয়ে সঙ্গে সঙ্গে চলে, .class ফাইল তৈরি হয় না
- Main.class তৈরি হয়, কিন্তু চলে না
- Maven প্রজেক্ট তৈরি হয়
শব্দকোষ
লেখার মধ্যে ডটেড দাগ দেওয়া শব্দে মাউস রাখুন বা চাপুন — অর্থ দেখাবে। এই পর্বের সব নতুন শব্দ এখানে একসাথে:
মনে রাখুন
- প্রোগ্রামারের দরকার JDK = JVM + standard library +
javac,jshell-এর মতো টুল। আলাদা JRE আর লাগে না। - যেকোনো ভালো OpenJDK distribution (যেমন Temurin) থেকে একটি LTS version নিন — 21 বা 25.
- PATH দিয়ে shell
java/javacখোঁজে; JAVA_HOME দিয়ে Maven, Gradle ও IDE JDK খোঁজে।java -versionআরjavac -versionমিলতে হবে। javac Main.java→Main.class(bytecode) →java Main; ছোট পরীক্ষায়java Main.javaবা JShell.- error মেসেজ পড়ুন: “not recognized” মানে PATH, “should be declared in a file named” মানে ফাইলের নাম, “class file version” মানে দুটি JDK-র লড়াই।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- পর্ব ০৪ · প্রথম প্রোগ্রাম — class, main আর printlnপরবর্তী পর্বপ্রথম Java প্রোগ্রামের প্রতিটি লাইনের অর্থ ও উদ্দেশ্য।
- Java প্রোগ্রামিং · কোর্স হোম৫৯টি পর্বপুরো কোর্সের রোডম্যাপ — কোন পর্ব কখন।
- Python প্রোগ্রামিং · সেটআপ পর্বপাশের ট্র্যাকPython-এর interpreter, REPL আর PATH — Java-র সেটআপের সাথে তুলনা করুন।
- C প্রোগ্রামিং · টুলচেইনগভীরে যানmachine code-এ compile হওয়া ভাষার চার ধাপ — bytecode-এর সাথে পার্থক্য বুঝতে।