Modularitas di Java 9: ​​Ditumpuk dengan Project Jigsaw, Penrose, dan OSGi

Artikel ini memberikan gambaran umum proposal, spesifikasi, dan platform yang bertujuan untuk membuat teknologi Java lebih modular di Java 9. Saya akan membahas faktor-faktor yang berkontribusi terhadap kebutuhan arsitektur Java yang lebih modular, menjelaskan secara singkat dan membandingkan solusi yang telah diusulkan, dan memperkenalkan tiga pembaruan modularitas yang direncanakan untuk Java 9, termasuk potensi dampaknya pada pengembangan Java.

Mengapa kita membutuhkan modularitas Java?

Modularitas adalah konsep umum. Dalam perangkat lunak, ini berlaku untuk menulis dan menerapkan program atau sistem komputasi sebagai sejumlah modul unik, bukan sebagai desain tunggal yang monolitik. Antarmuka standar kemudian digunakan untuk mengaktifkan modul untuk berkomunikasi. Mempartisi lingkungan konstruksi perangkat lunak menjadi modul yang berbeda membantu kami meminimalkan penggandengan, mengoptimalkan pengembangan aplikasi, dan mengurangi kompleksitas sistem.

Modularitas memungkinkan pemrogram untuk melakukan pengujian fungsionalitas secara terpisah dan terlibat dalam upaya pengembangan paralel selama sprint atau proyek tertentu. Ini meningkatkan efisiensi di seluruh siklus pengembangan perangkat lunak.

Beberapa atribut karakter dari modul asli adalah:

  • Unit penerapan otonom (kopling longgar)
  • Identitas yang konsisten dan unik (ID dan versi modul)
  • Persyaratan dan dependensi yang mudah diidentifikasi dan ditemukan (waktu kompilasi standar dan fasilitas penerapan dan informasi meta)
  • Antarmuka yang terbuka dan dapat dimengerti (kontrak komunikasi)
  • Detail implementasi tersembunyi (enkapsulasi)

Sistem yang dibangun untuk memproses modul secara efisien harus melakukan hal berikut:

  • Mendukung modularitas dan penemuan ketergantungan pada waktu kompilasi
  • Jalankan modul dalam lingkungan waktu proses yang mendukung penerapan dan penerapan ulang yang mudah tanpa waktu henti sistem
  • Terapkan siklus hidup eksekusi yang jelas dan kuat
  • Menyediakan fasilitas untuk memudahkan pendaftaran dan penemuan modul

Solusi berorientasi objek, berorientasi komponen, dan berorientasi layanan semuanya telah berusaha untuk mengaktifkan modularitas murni. Namun, setiap solusi memiliki seperangkat kebiasaannya sendiri yang mencegahnya mencapai kesempurnaan modular. Mari kita pertimbangkan secara singkat.

Kelas dan objek Java sebagai konstruksi modular

Bukankah sifat Java yang berorientasi objek memenuhi persyaratan modularitas? Bagaimanapun, pemrograman berorientasi objek dengan Java menekankan dan terkadang memaksakan keunikan, enkapsulasi data, dan kopling longgar. Meskipun poin-poin ini adalah permulaan yang baik, perhatikan persyaratan modularitas yang tidak dipenuhi oleh kerangka kerja berorientasi objek Java: identitas pada tingkat objek tidak dapat diandalkan; antarmuka tidak berversi: dan kelas tidak unik di tingkat penerapan. Kopling longgar adalah praktik terbaik, tetapi tentu saja tidak dipaksakan.

Menggunakan kembali kelas di Java sulit dilakukan jika dependensi pihak ketiga mudah disalahgunakan. Alat waktu kompilasi seperti Maven berusaha untuk mengatasi kekurangan ini. Konvensi dan konstruksi bahasa after-the-fact seperti injeksi dependensi dan inversi kontrol membantu pengembang dalam upaya kami untuk mengontrol lingkungan runtime, dan terkadang berhasil, terutama jika digunakan dengan disiplin yang ketat. Sayangnya, situasi ini meninggalkan tugas membuat lingkungan modular hingga konvensi dan konfigurasi kerangka kerja berpemilik.

Java juga menambahkan ruang nama paket dan visibilitas cakupan ke dalam campuran sebagai cara untuk membuat mekanisme waktu kompilasi dan waktu penerapan modular. Namun fitur bahasa ini mudah diabaikan, seperti yang akan saya jelaskan.

Paket sebagai solusi modular

Paket mencoba menambahkan level abstraksi ke lanskap pemrograman Java. Mereka menyediakan fasilitas untuk ruang nama pengkodean yang unik dan konteks konfigurasi. Sayangnya, bagaimanapun, konvensi paket mudah dielakkan, seringkali mengarah ke lingkungan penghubung waktu kompilasi yang berbahaya.

Keadaan modularitas di Java saat ini (selain OSGi, yang akan saya bahas sebentar lagi) paling sering dicapai dengan menggunakan ruang nama paket, konvensi JavaBeans, dan konfigurasi kerangka kerja berpemilik seperti yang ditemukan di Spring.

Bukankah file JAR cukup modular?

File JAR dan lingkungan penerapan tempat mereka beroperasi sangat meningkatkan banyak konvensi penerapan lama yang tersedia. Tetapi file JAR tidak memiliki keunikan intrinsik, selain dari nomor versi yang jarang digunakan, yang disembunyikan dalam manifes .jar. File JAR dan manifes opsional tidak digunakan sebagai konvensi modularitas dalam lingkungan runtime Java. Jadi, nama paket kelas dalam file dan partisipasinya di classpath adalah satu-satunya bagian dari struktur JAR yang memberikan modularitas ke lingkungan runtime.

Singkatnya, JAR adalah upaya yang baik untuk modularisasi, tetapi JAR tidak memenuhi semua persyaratan untuk lingkungan yang benar-benar modular. Kerangka kerja dan platform seperti Spring dan OSGi menggunakan pola dan peningkatan spesifikasi JAR untuk menyediakan lingkungan untuk membangun sistem yang sangat mampu dan modular. Seiring waktu, bagaimanapun, bahkan alat ini akan menyerah pada efek samping yang sangat disayangkan dari spesifikasi JAR JAR neraka!

Classpath / JAR neraka

Ketika lingkungan runtime Java memungkinkan mekanisme pemuatan JAR yang rumit secara sewenang-wenang, pengembang tahu bahwa mereka berada di classpath hell atau JAR hell . Sejumlah konfigurasi dapat menyebabkan kondisi ini.

Pertama, pertimbangkan situasi di mana pengembang aplikasi Java menyediakan versi aplikasi yang diperbarui dan telah mengemasnya dalam file JAR dengan nama yang sama persis dengan versi lama. Lingkungan runtime Java tidak menyediakan fasilitas validasi untuk menentukan file JAR yang benar. Lingkungan runtime hanya akan memuat kelas dari file JAR yang ditemukannya pertama kali atau yang memenuhi salah satu dari banyak aturan jalur kelas. Ini mengarah pada perilaku yang tidak terduga.

Contoh lain dari JAR hell muncul di mana dua atau lebih aplikasi atau proses bergantung pada versi berbeda dari pustaka pihak ketiga. Menggunakan fasilitas pemuatan kelas standar, hanya satu versi pustaka pihak ketiga yang akan tersedia pada waktu proses, yang menyebabkan kesalahan setidaknya dalam satu aplikasi atau proses.

Sistem modul Java dengan fitur lengkap dan efisien harus memfasilitasi pemisahan kode menjadi modul yang berbeda, mudah dipahami, dan digabungkan secara longgar. Ketergantungan harus ditentukan dengan jelas dan ditegakkan dengan ketat. Fasilitas harus tersedia yang memungkinkan modul untuk ditingkatkan tanpa berdampak negatif pada modul lain. Lingkungan runtime modular harus mengaktifkan konfigurasi yang khusus untuk domain tertentu atau pasar vertikal, sehingga mengurangi waktu startup dan jejak lingkungan sistem.

Solusi modularitas untuk Java

Seiring dengan fitur modularitas yang disebutkan sejauh ini, upaya terbaru menambahkan beberapa lagi. Fitur berikut dimaksudkan untuk mengoptimalkan kinerja dan memungkinkan perluasan lingkungan runtime:

  • Kode sumber tersegmentasi : Kode sumber dipisahkan menjadi segmen cache yang berbeda, yang masing-masing berisi jenis kode terkompilasi tertentu. Sasarannya termasuk melewatkan kode non-metode selama pembersihan sampah, build tambahan, dan manajemen memori yang lebih baik.
  • Penerapan waktu build : Konstruksi bahasa untuk menerapkan namespace, pembuatan versi, dependensi, dan lainnya.
  • Fasilitas penyebaran : Dukungan untuk menerapkan lingkungan runtime yang diskalakan sesuai dengan kebutuhan spesifik, seperti yang ada di lingkungan perangkat seluler.

Sejumlah spesifikasi dan kerangka kerja modularitas telah berusaha untuk memfasilitasi fitur-fitur ini, dan beberapa baru-baru ini naik ke posisi teratas dalam proposal untuk Java 9. Ikhtisar proposal modularitas Java ada di bawah.

JSR (Permintaan Spesifikasi Java) 277

Saat ini tidak aktif adalah Java Specification Request (JSR) 277, Java Module System; diperkenalkan oleh Sun pada bulan Juni 2005. Spesifikasi ini mencakup sebagian besar area yang sama dengan OSGi. Seperti OSGi, JSR 277 juga mendefinisikan penemuan, pemuatan, dan konsistensi modul, dengan dukungan renggang untuk modifikasi runtime dan / atau pemeriksaan integritas.

Kekurangan JSR 277 meliputi:

  • Tidak ada pemuatan dan pembongkaran modul / bundel yang dinamis
  • Tidak ada pemeriksaan runtime untuk keunikan ruang kelas

OSGi (Open Service Gateway Initiative)

Diperkenalkan oleh OSGI Alliance pada November 1998, platform OSGI adalah jawaban modularitas yang paling banyak digunakan untuk pertanyaan standar formal untuk Java. Saat ini pada rilis 6, spesifikasi OSGi diterima dan digunakan secara luas, terutama akhir-akhir ini.

Intinya, OSGi adalah sistem modular dan platform layanan untuk bahasa pemrograman Java yang mengimplementasikan model komponen yang lengkap dan dinamis dalam bentuk modul, layanan, bundel yang dapat diterapkan, dan sebagainya.

Lapisan utama arsitektur OSGI adalah sebagai berikut:

  • Lingkungan eksekusi : Lingkungan Java (misalnya, Java EE atau Java SE) tempat bundel akan dijalankan.
  • Module : Di mana kerangka OSGi memproses aspek modular dari sebuah bundel. Metadata paket diproses di sini.
  • Siklus hidup : Memulai, memulai, dan menghentikan bundel terjadi di sini.
  • Registri layanan : Tempat kumpulan mencantumkan layanan mereka untuk ditemukan oleh bundel lain.

Salah satu kelemahan terbesar OSGi adalah kurangnya mekanisme formal untuk instalasi paket asli.

JSR 291

JSR 291 adalah kerangka kerja komponen dinamis untuk Java SE yang didasarkan pada OSGi, saat ini sedang dalam tahap akhir pengembangan. Upaya ini berfokus untuk membawa OSGi ke dalam Java mainstream, seperti yang dilakukan untuk lingkungan seluler Java oleh JSR 232.

JSR 294

JSR 294 mendefinisikan sistem meta-modul dan mendelegasikan perwujudan aktual modul pluggable (versi, dependensi, batasan, dll.) Ke penyedia eksternal. Spesifikasi ini memperkenalkan ekstensi bahasa, seperti "superpackages" dan modul yang terkait secara hierarki, untuk memfasilitasi modularitas. Enkapsulasi yang ketat dan unit kompilasi yang berbeda juga merupakan bagian dari fokus spesifikasi. JSR 294 saat ini tidak aktif.

Proyek Jigsaw

Project Jigsaw adalah kandidat yang paling mungkin untuk modularitas di Java 9. Jigsaw berusaha menggunakan konstruksi bahasa dan konfigurasi lingkungan untuk menentukan sistem modul yang dapat diskalakan untuk Java SE. Tujuan utama Jigsaw meliputi:

  • Sangat mudah untuk menskalakan runtime Java SE dan JDK ke perangkat kecil.
  • Meningkatkan keamanan Java SE dan JDK dengan melarang akses ke API JDK internal serta dengan menegakkan dan meningkatkan SecurityManager.checkPackageAccessmetode.
  • Meningkatkan kinerja aplikasi melalui pengoptimalan kode yang ada dan memfasilitasi teknik pengoptimalan program di masa depan.
  • Menyederhanakan pengembangan aplikasi dalam Java SE dengan mengaktifkan perpustakaan dan aplikasi yang akan dibangun dari modul kontribusi pengembang dan dari JDK modular
  • Mewajibkan dan menerapkan serangkaian batasan versi yang terbatas

JEP (Java Enhancement Proposal) 200

Java Enhancement Proposal 200 yang dibuat pada Juli 2014, berupaya untuk menentukan struktur modular untuk JDK. JEP 200 dibangun di atas kerangka kerja Jigsaw untuk memfasilitasi segmentasi JDK, menurut Profil Ringkas Java 8, menjadi sekumpulan modul yang dapat digabungkan pada waktu kompilasi, waktu pembuatan, dan waktu penerapan. Kombinasi modul ini kemudian dapat diterapkan sebagai lingkungan runtime yang diperkecil yang terdiri dari modul yang sesuai dengan Jigsaw.

JEP 201

JEP 201 berusaha membangun Jigsaw untuk mengatur ulang kode sumber JDK menjadi modul. Modul ini kemudian dapat dikompilasi sebagai unit berbeda oleh sistem build yang ditingkatkan yang menerapkan batasan modul. JEP 201 mengusulkan skema restrukturisasi kode sumber di seluruh JDK yang menekankan batas-batas modul di tingkat atas pohon kode sumber.

Penrose

Penrose akan mengatur interoperabilitas antara Jigsaw dan OSGi. Secara khusus, ini akan memfasilitasi kemampuan untuk memodifikasi mikro-kernel OSGi agar bundel yang berjalan di kernel yang dimodifikasi untuk menggunakan modul Jigsaw. Ini bergantung pada penggunaan JSON untuk mendeskripsikan modul.

Rencana untuk Java 9

Java 9 adalah rilis besar yang unik untuk Java. Yang membuatnya unik adalah pengenalan komponen dan segmen modular di seluruh JDK . Fitur utama yang mendukung modularisasi adalah:

  • Kode sumber modular : Di Java 9, JRE dan JDK akan diatur ulang menjadi modul yang dapat dioperasikan. Ini akan memungkinkan pembuatan runtime yang dapat diskalakan yang dapat dijalankan pada perangkat kecil.
  • Cache kode tersegmentasi : Meskipun bukan hanya fasilitas modular, cache kode tersegmentasi baru dari Java 9 akan mengikuti semangat modularisasi dan menikmati beberapa manfaat yang sama. Cache kode baru akan membuat keputusan cerdas untuk mengompilasi segmen kode yang sering diakses ke kode asli dan menyimpannya untuk pencarian yang dioptimalkan dan eksekusi di masa mendatang. Heap juga akan dibagi menjadi 3 unit berbeda: kode non-metode yang akan disimpan secara permanen di cache; kode yang berpotensi memiliki siklus hidup panjang (dikenal sebagai "kode non-profil"); dan kode yang bersifat sementara (dikenal sebagai "kode profil").
  • Penerapan waktu build: Sistem build akan ditingkatkan, melalui JEP 201, untuk menyusun dan menerapkan batasan modul.
  • Fasilitas penyebaran : Alat akan disediakan dalam proyek Jigsaw yang akan mendukung batasan modul, batasan, dan ketergantungan pada waktu penerapan.

Rilis akses awal Java 9

Meskipun tanggal rilis pasti Java 9 masih menjadi misteri, Anda dapat mendownload rilis akses awal di Java.net.

Kesimpulannya

Artikel ini telah mengulas tentang modularitas dalam platform Java, termasuk prospek untuk modularitas di Java 9. Saya menjelaskan bagaimana masalah lama seperti classpath hell berkontribusi pada kebutuhan arsitektur Java yang lebih modular dan membahas beberapa modularitas baru terbaru fitur yang diusulkan untuk Java. Saya kemudian menjelaskan dan mengontekstualisasikan setiap proposal atau platform modularitas Java, termasuk OSGi dan Project Jigsaw.

Kebutuhan akan arsitektur Java yang lebih modular jelas. Upaya saat ini gagal, meskipun OSGi sangat dekat. Untuk rilis Java 9 Project Jigsaw dan OSGi akan menjadi pemain utama di ruang modular untuk Java, dengan Penrose mungkin menyediakan perekat di antara mereka.

Artikel ini, "Modularitas di Java 9: ​​Bertumpuk dengan Project Jigsaw, Penrose, dan OSGi" awalnya diterbitkan oleh JavaWorld.