Saya ingin mengimplementasikan aplikasi java (aplikasi server) yang dapat mendownload versi baru (file .jar) dari url tertentu, dan kemudian mengupdate dirinya sendiri saat runtime.
Apa cara terbaik untuk melakukan ini dan apakah mungkin?
Saya kira aplikasi tersebut dapat mengunduh file .jar baru dan memulainya. Tetapi bagaimana saya harus melakukan serah terima, misalnya mengetahui kapan aplikasi baru dimulai dan kemudian keluar. Atau apakah ada cara yang lebih baik untuk melakukan ini?
Jawaban:
Struktur dasar solusi adalah sebagai berikut:
Ada loop utama yang bertanggung jawab untuk berulang kali memuat versi terbaru aplikasi (jika diperlukan) dan meluncurkannya.
Aplikasi melakukan tugasnya, tetapi secara berkala memeriksa URL unduhan. Jika mendeteksi versi baru, itu keluar kembali ke peluncur.
Ada beberapa cara untuk menerapkan ini. Sebagai contoh:
Peluncur bisa berupa skrip pembungkus atau aplikasi biner yang memulai JVM baru untuk menjalankan aplikasi dari file JAR yang diganti.
Peluncur dapat berupa aplikasi Java yang membuat classloader untuk JAR baru, memuat kelas entrypoint dan memanggil beberapa metode di atasnya. Jika Anda melakukannya dengan cara ini, Anda harus memperhatikan kebocoran penyimpanan classloader, tetapi itu tidak sulit. (Anda hanya perlu memastikan bahwa tidak ada objek dengan kelas yang dimuat dari JAR yang dapat dijangkau setelah Anda meluncurkan ulang.)
Keuntungan dari pendekatan pembungkus eksternal adalah:
Pendekatan kedua membutuhkan dua JAR, tetapi memiliki keuntungan sebagai berikut:
Cara "terbaik" tergantung pada kebutuhan spesifik Anda.
Perlu juga diperhatikan bahwa:
Ada risiko keamanan dengan pembaruan otomatis. Secara umum, jika server yang menyediakan pembaruan terganggu, atau jika mekanisme untuk menyediakan pembaruan rentan terhadap serangan, maka pembaruan otomatis dapat menyebabkan gangguan pada klien.
Mendorong pembaruan ke klien yang menyebabkan kerusakan pada klien dapat memiliki risiko hukum, dan risiko reputasi bisnis Anda.
Jika Anda dapat menemukan cara untuk menghindari penemuan kembali roda, itu bagus. Lihat jawaban lain untuk saran.
sumber
Saat ini saya sedang mengembangkan JAVA Linux Daemon dan juga perlu menerapkan mekanisme pembaruan otomatis. Saya ingin membatasi aplikasi saya ke satu file jar, dan menghasilkan solusi sederhana:
Kemas aplikasi pembaru dalam pembaruan itu sendiri.
Aplikasi : Saat aplikasi mendeteksi versi yang lebih baru, ia melakukan hal berikut:
ApplicationUpdater : Saat pembaru menjalankannya, ia melakukan hal berikut:
Semoga bisa membantu seseorang.
sumber
Ini adalah masalah yang diketahui dan saya sarankan untuk tidak menciptakan kembali roda - jangan menulis retasan Anda sendiri, cukup gunakan apa yang telah dilakukan orang lain.
Dua situasi yang perlu Anda pertimbangkan:
Aplikasi harus dapat diperbarui sendiri dan terus berjalan bahkan selama pembaruan (aplikasi server, aplikasi tersemat). Gunakan OSGi: Bundles atau Equinox p2 .
Aplikasi adalah aplikasi desktop dan memiliki penginstal. Ada banyak penginstal dengan opsi pembaruan. Periksa daftar pemasang .
sumber
Saya baru saja membuat update4j yang sepenuhnya kompatibel dengan sistem modul Java 9.
Ini akan memulai versi baru dengan mulus tanpa restart.
sumber
Saya telah menulis aplikasi Java yang dapat memuat plugin saat runtime dan segera mulai menggunakannya, terinspirasi oleh mekanisme serupa di jEdit. jEdit adalah open source sehingga Anda memiliki opsi untuk melihat cara kerjanya.
Solusinya menggunakan ClassLoader kustom untuk memuat file dari jar. Setelah dimuat, Anda dapat menjalankan beberapa metode dari toples baru yang akan bertindak sebagai
main
metodenya. Kemudian bagian yang sulit adalah memastikan Anda menyingkirkan semua referensi ke kode lama sehingga bisa dikumpulkan sampahnya. Saya bukan ahli dalam hal itu, saya telah membuatnya berhasil tetapi itu tidak mudah.sumber
NetworkClassLoader
di JavaDocsumber
Ini belum tentu yang terbaik cara , tetapi mungkin berhasil untuk Anda.
Anda dapat menulis aplikasi bootstrap (ala peluncur World of Warcraft, jika Anda telah memainkan WoW). Bootstrap itu bertanggung jawab untuk memeriksa pembaruan.
Dengan cara ini Anda tidak perlu khawatir tentang memaksa keluar dari aplikasi Anda.
Jika aplikasi Anda berbasis web, dan jika penting bahwa mereka memiliki klien terbaru, maka Anda juga dapat melakukan pemeriksaan versi saat aplikasi berjalan. Anda dapat melakukannya dalam interval, saat melakukan komunikasi normal dengan server (beberapa atau semua panggilan), atau keduanya.
Untuk produk yang baru-baru ini saya kerjakan, kami melakukan pemeriksaan versi saat peluncuran (tanpa aplikasi boot strapper, tetapi sebelum jendela utama muncul), dan selama panggilan ke server. Jika klien sudah tidak berlaku lagi, kami mengandalkan pengguna untuk keluar secara manual, tetapi melarang tindakan apa pun terhadap server.
Harap perhatikan bahwa saya tidak tahu apakah Java dapat memanggil kode UI sebelum Anda membuka jendela utama. Kami menggunakan C # / WPF.
sumber
Jika Anda membangun aplikasi Anda menggunakan plugin Equinox , Anda dapat menggunakan Sistem Penyediaan P2 untuk mendapatkan solusi siap pakai untuk masalah ini. Ini akan mengharuskan server untuk memulai ulang sendiri setelah pembaruan.
sumber
Saya melihat masalah keamanan saat mengunduh jar baru (dll.), Misalnya, seorang pria di tengah serangan. Anda selalu harus menandatangani pembaruan yang dapat diunduh.
Pada JAX2015, Adam Bien bercerita tentang penggunaan JGit untuk memperbarui binari. Sayangnya saya tidak dapat menemukan tutorial apapun.
Sumber dalam bahasa Jerman.
Adam Bien menciptakan pembaru, lihat di sini
Saya bercabang di sini dengan beberapa frontend javaFX. Saya juga sedang mengerjakan penandatanganan otomatis.
sumber