Saya menemukan plugin maven-shade-plugin digunakan di pom.xml seseorang. Saya belum pernah menggunakan maven-shade-plugin sebelumnya (dan saya seorang Maven n00b) jadi saya mencoba memahami alasan untuk menggunakan ini dan apa fungsinya.
Saya melihat dokumen Maven , namun saya tidak dapat memahami pernyataan ini:
"Plugin ini menyediakan kemampuan untuk mengemas artefak dalam tabung-uber, termasuk dependensinya dan untuk menaungi - yaitu mengganti nama - paket-paket dari beberapa dependensi."
Dokumentasi pada halaman tersebut sepertinya tidak ramah bagi pemula.
Apa itu "toples uber?" Mengapa seseorang ingin membuatnya? Apa gunanya mengganti nama paket dependensi? Saya mencoba membaca contoh-contoh di halaman apache maven-shade-plugin seperti "Memilih konten untuk Uber Jar," tetapi saya masih tidak mengerti apa yang sedang dilakukan dengan "shading."
Petunjuk apa pun untuk contoh-contoh / kasus penggunaan ilustratif (dengan penjelasan mengapa naungan diperlukan dalam kasus ini - masalah apa yang dipecahkannya) akan dihargai. Terakhir, kapan saya harus menggunakan maven-shade-plugin?
sumber
s/reallocation/relocation/
dalam komentar di atas.Jawaban:
Uber JAR, singkatnya, adalah JAR yang berisi segalanya.
Biasanya di Maven, kami mengandalkan manajemen ketergantungan. Artefak hanya berisi kelas / sumber daya itu sendiri. Maven akan bertanggung jawab untuk mengetahui semua artefak (JAR, dll) yang tergantung pada proyek saat proyek dibangun.
Uber-jar adalah sesuatu yang mengambil semua dependensi, dan mengekstrak konten dependensi dan menempatkannya dengan kelas / sumber daya dari proyek itu sendiri, dalam satu JAR besar. Dengan memiliki uber-jar seperti itu, mudah untuk dieksekusi, karena Anda hanya perlu satu JAR besar, bukan ton JAR kecil untuk menjalankan aplikasi Anda. Ini juga memudahkan distribusi dalam beberapa kasus.
Hanya catatan tambahan. Hindari menggunakan uber-jar sebagai ketergantungan Maven, karena merusak fitur resolusi ketergantungan Maven. Biasanya kami membuat tabung-uber hanya untuk artefak akhir untuk penyebaran aktual atau untuk distribusi manual, tetapi tidak untuk menempatkan ke repositori Maven.
Pembaruan: Saya baru saja menemukan bahwa saya belum menjawab satu bagian dari pertanyaan: "Apa gunanya mengubah nama paket dependensi?". Berikut adalah beberapa pembaruan singkat dan mudah-mudahan akan membantu orang yang memiliki pertanyaan serupa.
Membuat uber-jar untuk kemudahan penempatan adalah salah satu contoh penggunaan plugin teduh. Ada juga kasus penggunaan umum lainnya yang melibatkan penggantian nama paket.
Sebagai contoh, saya sedang mengembangkan
Foo
perpustakaan, yang tergantung pada versi tertentu (mis. 1.0)Bar
perpustakaan. Dengan asumsi saya tidak dapat menggunakan versiBar
lib lainnya (karena perubahan API, atau masalah teknis lainnya, dll). Jika saya hanya menyatakanBar:1.0
sebagaiFoo
dependensi dalam Maven, adalah mungkin untuk jatuh ke dalam masalah: SebuahQux
proyek tergantung padaFoo
, dan jugaBar:2.0
(dan itu tidak dapat digunakanBar:1.0
karenaQux
perlu menggunakan fitur baru diBar:2.0
). Inilah dilema: harusQux
digunakanBar:1.0
(Qux
kode mana yang tidak akan berfungsi) atauBar:2.0
(Foo
kode mana yang tidak akan berfungsi)?Untuk mengatasi masalah ini, pengembang
Foo
dapat memilih untuk menggunakan plugin teduh untuk mengubah nama penggunaannyaBar
, sehingga semua kelas diBar:1.0
jar disematkan dalamFoo
jar, dan paketBar
kelas tertanam diubah daricom.bar
menjadicom.foo.bar
. Dengan demikian,Qux
dapat dengan aman bergantung padaBar:2.0
karena sekarangFoo
tidak lagi tergantung padaBar
, dan menggunakan salinan "diubah" sendiri yangBar
terletak di paket lain.sumber
jar-with-dependency
deskriptor bawaan. Untuk masalah ketergantungan roslution menggunakan uber-jar, saya telah menyebutkan dalam jawaban saya: Jangan menggunakan uber-jar sebagai ketergantungan, titik. Sedikit lebih detail: sebelum Anda membuat uber-jar, Anda harus memiliki proyek normal dengan ketergantungan normal. Artefak asli itu adalah yang harus Anda gunakan sebagai ketergantungan (alih-alih tabung-uber)Class.forName
bekerja?Saya bertanya-tanya pada diri sendiri baru-baru ini mengapa elasticsearch menaungi dan memindahkan beberapa (tetapi tidak semua) dari ketergantungannya. Berikut penjelasan dari pengelola proyek, @kimchy :
- https://github.com/elasticsearch/elasticsearch/issues/2091#issuecomment-7156766
Dan satu lagi di sini dari drewr :
- https://github.com/elasticsearch/elasticsearch/pull/3244#issuecomment-20125452
Jadi, itu satu kasus penggunaan. Adapun contoh ilustratif, di bawah ini adalah bagaimana maven-shade-plugin digunakan dalam pom.xml elasticsearch (v0.90.5). Itu
artifactSet::include
garis menginstruksikan itu dependensi apa yang menarik ke dalam JAR uber (pada dasarnya, mereka membuka ritsleting dan dan re-dikemas bersama kelas elasticsearch sendiri ketika jar sasaran elasticsearch diproduksi. (Dalam kasus Anda tidak tahu ini sudah, file JAR adalah hanya file ZIP yang berisi kelas program, sumber daya, dll, dan beberapa metadata. Anda dapat mengekstrak satu untuk melihat bagaimana itu disatukan.)The
relocations::relocation
garis mirip, kecuali bahwa dalam setiap kasus mereka juga menerapkan substitusi ditentukan untuk kelas ketergantungan ini - dalam hal ini, membawa mereka di bawahorg.elasticsearch.common
.Akhirnya
filters
bagian mengecualikan beberapa hal dari target JAR yang seharusnya tidak ada di sana - seperti metadata JAR, file membangun semut, file teks, dll. Yang dikemas dengan beberapa dependensi, tetapi yang tidak termasuk dalam JAR uber.sumber
Peringatan kecil
Meskipun itu tidak menjelaskan mengapa seseorang ingin menggunakan maven-shade-plugin (karena jawaban yang dipilih menggambarkannya dengan cukup baik), saya ingin mencatat bahwa saya memiliki masalah dengannya. Itu mengubah JAR (sejak itu apa yang dilakukannya) dan itu menyebabkan regresi dalam perangkat lunak saya.
Jadi, daripada menggunakan ini (atau maven-jarjar-plugin), saya telah menggunakan binari JarJar yang tampaknya berfungsi tanpa masalah.
Saya memposting di sini solusi saya karena butuh beberapa waktu untuk menemukan solusi yang layak.
File JAR Downlaod JarJar
Anda dapat mengunduh toples dari sini: https://code.google.com/p/jarjar/ Di menu sebelah kiri Anda punya tautan untuk mengunduhnya.
Cara menggunakan JarJar untuk memindahkan kelas JAR dari satu paket ke paket lainnya
Dalam contoh ini kita akan mengubah paket dari "com.fasterxml.jackson" menjadi "io.kuku.dependencies.com.fasterxml.jackson". - Sumber JAR disebut "jackson-databind-2.6.4.jar" dan JAR yang baru dimodifikasi disebut "kuku-jackson-databind-2.6.4.jar". - File JAR "jarjar" dalam versi 1.4
Buat file "rules.txt". Isi file harus (perhatikan periode sebelum karakter '@'): rule com.fasterxml.jackson. ** io.kuku.dependencies.com.fasterxml.jackson. @ 1
Jalankan perintah berikut: java -jar jarjar-1.4.jar proses rules.txt jackson-databind-2.6.4.jar kuku-jackson-databind-2.6.4.jar
Menginstal JAR yang dimodifikasi ke repositori lokal
Dalam hal ini saya menginstal 3 file yang terletak di folder "c: \ my-jars \".
mvn install: install-file -Dfile = C: \ my-jars \ kuku-jackson-annotations-2.6.4.jar -DgroupId = io.kuku.dependencies -DartifactId = kuku-jackson-annotations -Dversion = 2.6.4 - Dpackaging = toples
mvn install: install-file -Dfile = C: \ my-jars \ kuku-jackson-core-2.6.4.jar -DgroupId = io.kuku.dependencies -DartifactId = kuku-jackson-core -Dversion = 2.6.4 - Dpackaging = toples
mvn install: install-file -Dfile = C: \ my-jars \ kuku-jackson-databind-2.6.4.jar -DgroupId = io.kuku.dependencies -DartifactId = kuku-jackson-annotations -Dversion = 2.6.4 - Dpackaging = toples
Menggunakan JAR yang dimodifikasi di pom proyek
Dalam contoh ini, ini adalah elemen "dependensi" dalam proyek pom:
sumber
Saya pikir salah satu contoh perlunya toples "berbayang" adalah fungsi AWS Lambda. Mereka tampaknya hanya memungkinkan Anda mengunggah 1 jar, bukan seluruh koleksi .jar seperti yang Anda temukan dalam file .war yang khas. Jadi, membuat .jar tunggal dengan semua dependensi proyek memungkinkan Anda melakukan ini.
sumber