Mode Tanpa Kepala Java

1. Ikhtisar

Terkadang, kita perlu bekerja dengan aplikasi berbasis grafik di Java tanpa tampilan, keyboard, atau mouse yang sebenarnya , katakanlah, di server atau container.

Dalam tutorial singkat ini, kita akan belajar tentang mode headless Java untuk mengatasi skenario ini. Kami juga akan melihat apa yang dapat kami lakukan dalam mode tanpa kepala dan apa yang tidak dapat kami lakukan.

2. Menyiapkan Mode Tanpa Kepala

Ada banyak cara untuk menyiapkan mode headless di Java secara eksplisit:

  • Secara terprogram menyetel properti sistem java.awt.headless ke true
  • Menggunakan argumen baris perintah: java -Djava.awt.headless = true
  • Menambahkan -Djava.awt.headless = true ke variabel lingkungan JAVA_OPTS di skrip startup server

Jika lingkungan sebenarnya tidak memiliki head, JVM akan menyadarinya secara implisit. Namun, akan ada perbedaan halus dalam beberapa skenario. Kami akan segera melihatnya.

3. Contoh Komponen UI dalam Mode Tanpa Kepala

Kasus penggunaan umum komponen UI yang berjalan di lingkungan tanpa head bisa menjadi aplikasi pengonversi gambar. Meskipun membutuhkan data grafik untuk pemrosesan gambar, tampilan tidak terlalu diperlukan. Aplikasi dapat dijalankan di server dan file yang dikonversi disimpan atau dikirim melalui jaringan ke komputer lain untuk ditampilkan.

Mari kita lihat ini beraksi.

Pertama, kita akan mengaktifkan mode headless secara terprogram dalam kelas JUnit :

@Before public void setUpHeadlessMode() { System.setProperty("java.awt.headless", "true"); } 

Untuk memastikannya sudah diatur dengan benar, kita bisa menggunakan java.awt.GraphicsEnvironment # isHeadless :

@Test public void whenSetUpSuccessful_thenHeadlessIsTrue() { assertThat(GraphicsEnvironment.isHeadless()).isTrue(); } 

Kita harus ingat bahwa pengujian di atas akan berhasil dalam lingkungan tanpa head meskipun mode tidak diaktifkan secara eksplisit.

Sekarang mari kita lihat pengubah gambar sederhana kami:

@Test public void whenHeadlessMode_thenImagesWork() { boolean result = false; try (InputStream inStream = HeadlessModeUnitTest.class.getResourceAsStream(IN_FILE); FileOutputStream outStream = new FileOutputStream(OUT_FILE)) { BufferedImage inputImage = ImageIO.read(inStream); result = ImageIO.write(inputImage, FORMAT, outStream); } assertThat(result).isTrue(); }

Dalam contoh berikut ini, kita dapat melihat bahwa informasi dari semua font, termasuk metrik font, juga tersedia untuk kita:

@Test public void whenHeadless_thenFontsWork() { GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); String fonts[] = ge.getAvailableFontFamilyNames(); assertThat(fonts).isNotEmpty(); Font font = new Font(fonts[0], Font.BOLD, 14); FontMetrics fm = (new Canvas()).getFontMetrics(font); assertThat(fm.getHeight()).isGreaterThan(0); assertThat(fm.getAscent()).isGreaterThan(0); assertThat(fm.getDescent()).isGreaterThan(0); }

4. HeadlessException

Ada komponen yang membutuhkan perangkat periferal dan tidak akan berfungsi dalam mode tanpa kepala. Mereka melempar HeadlessException saat digunakan di lingkungan non-interaktif:

Exception in thread "main" java.awt.HeadlessException at java.awt.GraphicsEnvironment.checkHeadless(GraphicsEnvironment.java:204) at java.awt.Window.(Window.java:536) at java.awt.Frame.(Frame.java:420)

Tes ini menegaskan bahwa menggunakan Frame dalam mode headless memang akan memunculkan HeadlessException :

@Test public void whenHeadlessmode_thenFrameThrowsHeadlessException() { assertThatExceptionOfType(HeadlessException.class).isThrownBy(() -> { Frame frame = new Frame(); frame.setVisible(true); frame.setSize(120, 120); }); } 

Sebagai aturan praktis, ingatlah bahwa komponen tingkat atas seperti Frame dan Tombol selalu membutuhkan lingkungan interaktif dan akan mengeluarkan pengecualian ini. Namun, ini akan ditampilkan sebagai Error yang tidak dapat dipulihkan jika mode headless tidak disetel secara eksplisit .

5. Melewati Komponen Kelas Berat dalam Mode Tanpa Kepala

Pada titik ini, kita mungkin mengajukan pertanyaan kepada diri kita sendiri - tetapi bagaimana jika kita memiliki kode dengan komponen GUI untuk dijalankan pada kedua jenis lingkungan - mesin produksi yang dipimpin dan server analisis kode sumber tanpa kepala?

Dalam contoh di atas, kita telah melihat bahwa komponen kelas berat tidak akan berfungsi di server dan akan mengeluarkan pengecualian.

Jadi, kita bisa menggunakan pendekatan bersyarat:

public void FlexibleApp() { if (GraphicsEnvironment.isHeadless()) { System.out.println("Hello World"); } else { JOptionPane.showMessageDialog(null, "Hello World"); } }

Dengan menggunakan pola ini, kita dapat membuat aplikasi fleksibel yang menyesuaikan perilakunya sesuai lingkungan.

6. Kesimpulan

Dengan contoh kode yang berbeda, kami melihat bagaimana dan mengapa mode headless di java. Artikel teknis ini memberikan daftar lengkap dari semua yang dapat dilakukan saat beroperasi dalam mode tanpa kepala.

Seperti biasa, kode sumber untuk contoh di atas tersedia di GitHub.