Topik ini menelusuri perjalanan sebuah program Java dari berkas teks sampai keluaran muncul di layar. Perjalanannya melewati dua aktor utama, yaitu kompiler javac yang menerjemahkan kode sumber menjadi bytecode, dan mesin virtual Java (Java Virtual Machine, JVM) yang mengeksekusinya. Setelah selesai membaca, dua perintah klasik javac dan java tidak lagi tertukar, dan tombol run di IDE terasa sebagai singkatan dari langkah-langkah yang sudah dipahami.
Dari kode sumber ke bytecode#
Kode yang ditulis pengembang adalah teks yang nyaman dibaca manusia, sedangkan JVM hanya mengerti satu bahasa, yaitu bytecode. Kompilator javac menjembatani keduanya. Kompilator ini membaca berkas .java, memeriksa sintaks dan kecocokan tipe, lalu menghasilkan berkas .class yang berisi bytecode, yakni rangkaian instruksi untuk mesin virtual dan bukan untuk prosesor tertentu.
Alur lengkapnya digambarkan berikut ini.
Desain dua lapis inilah alasan slogan write once, run anywhere bisa bekerja. Kompilasi menghasilkan bytecode yang sama untuk semua platform, sedangkan setiap sistem operasi punya JVM miliknya yang menerjemahkan bytecode tersebut ke mesin masing-masing. Konsekuensinya, berkas .class hasil kompilasi di Linux dapat dijalankan di Windows tanpa kompilasi ulang, asalkan di sana terpasang JVM.
Dua langkah klasik dengan javac#
Cara tradisional menjalankan Java terdiri atas dua perintah. Perintah pertama mengompilasi, dan perintah kedua menjalankan hasilnya.
# tidak-dijalankan
# langkah 1, mengompilasi Halo.java menjadi Halo.class
javac Halo.java
# langkah 2, menjalankan kelas Halo di atas JVM
java HaloPerhatikan perbedaan argumennya. Perintah javac menerima nama berkas lengkap dengan ekstensi .java, sedangkan perintah java menerima nama kelas tanpa ekstensi apa pun. Jika kompilasi berhasil, berkas Halo.class muncul di folder yang sama. Bila kompilasi gagal, javac menampilkan daftar error dengan nomor barisnya, dan tidak ada berkas .class yang dihasilkan sampai kesalahan diperbaiki.
Setelah .class ada, perintah java Halo memuat kelas itu, mencari metode main, lalu mengeksekusinya. Berkas .class inilah yang dibagikan ke pengguna aplikasi, karena berkas sumber .java tidak diperlukan lagi pada saat program dijalankan.
Satu langkah dengan mode single-file#
Sejak Java 11, launcher java dapat menjalankan berkas sumber secara langsung dalam satu perintah, tanpa javac dan tanpa berkas .class yang tertinggal. Mode ini disebut mode single-file source, dan perintahnya berbentuk java Nama.java dengan nama berkas sebagai argumennya.
# mode single-file, langsung dari berkas sumber
java Sapa.javaKompilasi selesai, saatnya dieksekusi
Bytecode dijalankan oleh JVM
Program berakhir dengan normalDi balik layar, launcher tetap mengompilasi berkas tersebut, tetapi hasilnya disimpan di memori dan tidak pernah ditulis ke disk. Untuk program kecil dan untuk tahap belajar, mode ini memangkas satu langkah sekaligus menghilangkan risiko menjalankan .class yang lama. Untuk proyek berukuran besar, alat bantu seperti Maven atau Gradle tetap menjadi pilihan karena keduanya mengatur ketergantungan dan kompilasi banyak berkas sekaligus.
Apa yang terjadi di dalam JVM#
JVM bukan penerjemah buta yang membaca bytecode baris demi baris dari awal sampai akhir. Sebelum program berjalan, JVM melakukan beberapa tahap. Kelas yang dibutuhkan dimuat (loading) dari berkas .class, lalu bytecode diverifikasi agar tidak merusak memori, dan setelah itu eksekusi dimulai.
Selama eksekusi, JVM mengamati bagian kode yang paling sering dijalankan dan mengompilasinya menjadi instruksi mesin asli melalui teknik just-in-time (JIT). Hasilnya, program yang berjalan lama semakin cepat karena jalur panasnya sudah berupa kode mesin, bukan bytecode yang ditafsirkan berulang. JVM juga mengelola memori otomatis, termasuk membebaskan objek yang tidak lagi dirujuk melalui proses garbage collection. Bagian-bagian ini memang jauh dari mata, tetapi mengetahui keberadaannya menjelaskan mengapa keluaran program tidak bergantung pada prosesor apa yang dipakai.
Tombol run di IDE#
Tombol run di IntelliJ IDEA, VS Code, atau NetBeans membungkus seluruh alur di atas menjadi satu klik. Di belakangnya, IDE memanggil kompiler untuk semua berkas yang berubah, melaporkan error sebelum program dijalankan, lalu memanggil JVM untuk kelas yang memuat main. Folder hasil kompilasi biasanya bernama out, bin, atau target tergantung alat bantunya.
Keunggulan tambahan IDE terjadi jauh sebelum tombol run ditekan. Editor IDE menandai kesalahan tipe dan sintaks saat kode sedang diketik, melengkapi nama metode secara otomatis, dan menawarkan perbaikan cepat. Dengan begitu banyak error kompilasi terselesaikan sebelum sempat menjadi perintah yang gagal. Terminal tetap bernilai karena perilakunya transparan, sedangkan IDE bernilai karena kecepatan umpan baliknya, dan keduanya memakai mekanisme kompilasi yang sama.
Kesalahan umum#
- Menjalankan
java Sapa.class. JVM mencari kelas bernamaSapa.classdan menampilkanError: Could not find or load main class Sapa.class. Perbaikannya menulis nama kelas tanpa ekstensi, yaitujava Sapa, ataujava Sapa.javauntuk mode single-file. - Mengedit kode lalu lupa menyimpan berkas sebelum menjalankan. Program tetap berperilaku seperti versi lama karena JVM mengeksekusi versi terakhir yang tersimpan. Kebiasaan menyimpan, atau pengaturan simpan otomatis, menghilangkan kebingungan ini.
javactidak dikenali dengan pesancommand not found. Penyebabnya umumnya JDK belum terpasang atau folder biner JDK belum masuk ke PATH. Instalasi JDK dan pemeriksaanjavac -versionmenyelesaikannya.- Mengira
.classharus dibuat dahulu sebelum mode single-file bisa dipakai. Kedua jalur itu berdiri sendiri, karenajava Sapa.javamengompilasi di memori tanpa menyentuh berkas.classmana pun.
Ringkasan#
- Kompilator
javacmenerjemahkan berkas.javamenjadi berkas.classberisi bytecode, dan JVM mengeksekusi bytecode tersebut di platform mana pun yang punya JVM. - Jalur klasik terdiri atas
javac Nama.javalalujava Nama, dengan perbedaan penting bahwajavamenerima nama kelas tanpa ekstensi. - Mode single-file
java Nama.javamengompilasi di memori dan langsung menjalankan program, sehingga cocok untuk program kecil dan tahap belajar. - JVM memuat dan memverifikasi kelas, mengeksekusi bytecode, mengompilasi jalur panas dengan JIT, dan mengelola memori lewat garbage collection.
Referensi#
- JEP 330: Launch Single-File Source-Code Programs — OpenJDK — Spesifikasi resmi mode single-file beserta batasan-batasannya.
- The “Hello World!” Application — Oracle — Langkah kompilasi dan eksekusi pertama pada Windows, macOS, dan Linux.
- Introduction to the Java Virtual Machine, JVM Specification SE 21 — Oracle — Gambaran resmi tugas JVM dalam memuat dan mengeksekusi bytecode.