Java hadir di Linux dalam dua wujud yang sering tertukar: runtime untuk menjalankan program, dan kit pengembangan untuk membangunnya. Mesin latihan kita sengaja berada di kondisi yang mengajar: perintah java tersedia, tetapi compiler javac tidak terpasang — persis seperti server produksi yang hanya perlu menjalankan aplikasi Java tanpa membangunnya. Kondisi itu kita jadikan bahan bedah: memeriksa instalasi, menjalankan program satu file, memahami pergantian versi lewat update-alternatives, lalu menyusun proyek lewat pom.xml Maven. Setiap blok contoh pada Chapter ini dijalankan sungguhan di Debian 13, sehingga output yang tercetak sama dengan yang akan kita lihat di mesin masing-masing.

JDK versus JRE: Dua Wajah Java di Linux #

Distribusi Java dibagi berdasarkan pekerjaan yang perlu dilakukan. Java Runtime Environment (JRE) cukup untuk menjalankan aplikasi: berisi java — launcher yang memuat JVM (Java Virtual Machine) dan menjalankan bytecode. Java Development Kit (JDK) memuat seluruh isi JRE ditambah peralatan pengembangan: javac untuk mengompilasi, jar untuk mengemas, serta javadoc untuk dokumentasi. Di keluarga Debian, keduanya dikemas terpisah:

PackageIsi utamaKapan dipakai
openjdk-21-jre-headlessjava, tanpa pustaka GUIserver produksi yang hanya menjalankan aplikasi
openjdk-21-jdk-headlessJRE + javac, jar, javadocworkstation development
default-jdkmetapackage yang menunjuk JDK default rilispilihan aman saat mulai belajar

Akhiran -headless berarti komponen GUI AWT/Swing tidak disertakan — tepat untuk server tanpa layar, konsep yang sudah kita kenal saat membahas pilihan package di Chapter Compilers dan Build Tools . default-jdk bekerja seperti build-essential: bukan software sendirian, melainkan penunjuk — pada Debian 13 ia mengarah ke OpenJDK 21.

Memeriksa Instalasi: java Ada, javac Tidak #

Pemeriksaan instalasi Java sebaiknya dilakukan tiga lapis: versi runtime, keberadaan compiler, dan lokasi binary yang sesungguhnya:

bash
java --version
command -v javac || echo "javac tidak ditemukan"
readlink -f /usr/bin/java

Output yang Dihasilkan:

text
openjdk 21.0.12.1 2026-08-18
OpenJDK Runtime Environment (build 21.0.12.1+1-1-deb13u1-Debian)
OpenJDK 64-Bit Server VM (build 21.0.12.1+1-1-deb13u1-Debian, mixed mode, sharing)
javac tidak ditemukan
/usr/lib/jvm/java-21-openjdk-amd64/bin/java

Bedah ketiga barisnya:

  1. java --version: mencetak tiga baris — versi OpenJDK, lingkungan runtime, dan mesin virtual. Di mesin latihan ini terpasang OpenJDK 21, versi LTS yang menjadi default Debian 13.
  2. command -v javac || echo ...: command -v mencetak lokasi sebuah perintah atau gagal senyap. Operator || menjalankan echo hanya saat pemeriksaan gagal — pola pengganti which yang lebih dapat diandalkan. Hasilnya menegaskan: runtime ada, compiler tidak.
  3. readlink -f /usr/bin/java: mengikuti rantai symlink sampai file asli. Hasilnya bukan /usr/bin/java, melainkan di dalam /usr/lib/jvm/ — petunjuk penting untuk urusan versi berikutnya.

Menjalankan Program Java Tanpa javac #

Sejak Java 11, launcher java punya mode khusus untuk file tunggal: diberi berkas .java, launcher mengompilasi source di memori lalu langsung menjalankannya tanpa meninggalkan file .class di disk. Runtime di mesin ini membawa modul compiler yang dibutuhkan mode tersebut, sehingga kita bisa mencobanya sungguhan:

bash
cat > Halo.java << 'AKHIR'
public class Halo {
    public static void main(String[] args) {
        System.out.println("Halo dari Java!");
    }
}
AKHIR
java Halo.java

Output yang Dihasilkan:

text
Halo dari Java!

Mari kita telaah isi program dan perintahnya:

  1. Baris 1 (public class Halo): nama class wajib sama dengan nama berkas — Halo.java — aturan keras compiler Java; melanggarnya berarti error kompilasi.
  2. Baris 2 (public static void main(String[] args)): titik masuk program. JVM mencari method dengan bentuk persis ini sebagai tempat eksekusi dimulai.
  3. Baris 3 (System.out.println(...)): mencetak satu baris teks ke stdout, lalu pindah baris.
  4. java Halo.java: mode source-file — kompilasi di memori, jalankan, selesai.

Untuk proyek sungguhan, jalur resminya tetap dua langkah: javac menghasilkan bytecode .class, lalu java menjalankannya:

bash
javac Halo.java   # menghasilkan Halo.class
java Halo          # menjalankan bytecode tanpa akhiran .class

Kedua perintah itu baru bisa dijalankan setelah package openjdk-21-jdk-headless (atau default-jdk) terpasang — sudo apt install default-jdk dari Chapter apt dan dpkg sudah cukup.

Memasang JDK dan Berganti Versi #

Beberapa JDK boleh terpasang berdampingan dalam satu sistem: satu aplikasi lama butuh Java 17, proyek baru berjalan di Java 21. Yang menyelesaikan perebutan nama perintah java adalah mekanisme update-alternatives dari dpkg — tabel symlink yang menunjuk satu pemenang:

bash
update-alternatives --list java
ls /usr/lib/jvm

Output yang Dihasilkan:

text
/usr/lib/jvm/java-21-openjdk-amd64/bin/java
default-java
java-1.21.0-openjdk-amd64
java-21-openjdk-amd64

Bedah hasilnya:

  1. update-alternatives --list java: mencetak semua kandidat yang terdaftar untuk perintah java. Di mesin ini satu-satunya kandidat adalah binary OpenJDK 21.
  2. ls /usr/lib/jvm: memperlihatkan tiga nama. default-java adalah symlink penunjuk, java-21-openjdk-amd64 adalah instalasi sungguhan, dan java-1.21.0-openjdk-amd64 adalah nama alias yang dipakai package lain untuk menyatakan kompatibilitas versi.

Perintah sudo update-alternatives --config java membuka menu interaktif untuk memilih kandidat secara manual, sementara mode bawaan (auto) selalu mengikuti kandidat dengan prioritas tertinggi. Instalasi JDK tambahan lewat apt install openjdk-17-jdk-headless otomatis mendaftarkan diri ke tabel ini — inilah cara Debian mengelola banyak versi Java tanpa saling menimpa.

JAVA_HOME: Alamat Instalasi untuk Tool Lain #

Sebagian besar tool ekosistem Java — Maven, Gradle, beberapa IDE dan skrip build — tidak mencari java lewat PATH, melainkan membaca variabel lingkungan JAVA_HOME yang berisi alamat folder instalasi JDK. Folder itu bisa ditemukan dengan pola dua level ke atas dari binary java — dari .../bin/java naik dua tingkat ke folder instalasi, hasil readlink yang kita dapatkan di blok pertama:

bash
export JAVA_HOME="/usr/lib/jvm/java-21-openjdk-amd64"
export PATH="$JAVA_HOME/bin:$PATH"

Baris pertama menetapkan alamatnya; baris kedua menempatkan bin milik JDK di depan PATH sehingga tool di dalamnya menang atas versi lain. Dua baris ini layak ditaruh di ~/.bashrc agar aktif di setiap sesi — mekanisme file startup shell yang kita bedah di Chapter Environment Variables . Di Debian, java sudah tersedia lewat /usr/bin, jadi baris kedua lebih relevan saat Anda mengelola beberapa JDK sekaligus.

Maven: Build Terdelegasi lewat pom.xml #

Segera setelah proyek Java tumbuh — banyak class, pustaka pihak ketiga, pengujian — kompilasi manual menjadi tidak praktis. Maven menyembunyikan seluruh kerumitan itu di balik satu file deklarasi bernama pom.xml: Project Object Model. Kita tulis versi ringkasnya dan periksa isinya:

bash
cat > pom.xml << 'AKHIR'
<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example.kasir</groupId>
  <artifactId>aplikasi-kasir</artifactId>
  <version>1.0.0</version>
  <dependencies>
    <dependency>
      <groupId>com.google.code.gson</groupId>
      <artifactId>gson</artifactId>
      <version>2.13.1</version>
    </dependency>
  </dependencies>
</project>
AKHIR
cat pom.xml

Output yang Dihasilkan:

text
<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example.kasir</groupId>
  <artifactId>aplikasi-kasir</artifactId>
  <version>1.0.0</version>
  <dependencies>
    <dependency>
      <groupId>com.google.code.gson</groupId>
      <artifactId>gson</artifactId>
      <version>2.13.1</version>
    </dependency>
  </dependencies>
</project>

Bedah bagian-bagian utamanya:

  1. modelVersion (4.0.0): versi format file POM yang dipakai — angka ini wajib ada dan 4.0.0 adalah satu-satunya nilai yang dikenal Maven 3.
  2. Trio groupId, artifactId, version: koordinat identitas proyek, biasa disingkat GAV. com.example.kasir adalah namespace organisasi, aplikasi-kasir nama artefak, 1.0.0 versinya — koordinat inilah yang dipakai Maven saat proyek kita sendiri dijadikan dependensi proyek lain.
  3. Blok <dependencies>: daftar pustaka yang dibutuhkan. Saat pertama kali build, Maven mengunduh gson dari repositori pusat Maven Central, menyimpannya di cache lokal ~/.m2/repository, lalu menyertakannya di classpath kompilasi.

Satu perintah mvn package kemudian menjalankan rangkaian fase — validate, compile, test, package — dan berhenti dengan berkas JAR di folder target/. Sebagai contoh tampilan, akhiran output mvn package pada proyek kecil berbentuk seperti ini:

text
[INFO] --- jar:3.4.2:jar (default-jar) @ aplikasi-kasir ---
[INFO] Building jar: /home/budi/proyek/target/aplikasi-kasir-1.0.0.jar
[INFO] BUILD SUCCESS
[INFO] Total time:  4.219 s

Baris BUILD SUCCESS adalah penanda seluruh fase lulus; target/ adalah folder kerja berisi hasil build yang aman dihapus kapan saja dengan mvn clean. Rincian perintah dan siklus hidupnya terdokumentasi rapi di halaman Java wiki Debian dan manual java(1) .

Gradle: Alternatif dengan Skrip Singkat #

Maven bukan satu-satunya pengatur build di dunia Java. Gradle menawarkan pendekatan berbeda: alih-alih XML, konfigurasi ditulis sebagai skrip — umumnya Kotlin — sehingga logika build bisa memakai if dan fungsi:

kotlin
plugins {
    java
}

dependencies {
    implementation("com.google.code.gson:gson:2.13.1")
}

Blok plugins mengaktifkan dukungan build Java bawaan, dan koordinat dependensi ditulis satu baris dalam format grup:artefak:versi — isi yang sama dengan pom.xml di atas, hanya lebih ringkas. Gradle unggul di kecepatan build bertahap berkat cache dan daemon, dan menyertakan gradlew — wrapper yang mengunduh versi Gradle yang tepat sehingga seluruh tim dan server CI memakai versi sama tanpa instalasi manual. Maven membalas dengan kematangan dan konvensi yang baku; keduanya membaca JAVA_HOME, jadi fondasi yang kita pasang berlaku untuk keduanya.

Toolchain Java kini lengkap: runtime diperiksa, identitas versi jelas, dan build didelegasikan ke Maven. Bahasa berikutnya mengambil jalur yang berbeda — interpreter yang menyatu dengan web server — kita bahas di Chapter PHP Development .