Maven2 membuatku gila selama fase pengembangan percobaan / mock-up cepat dan kotor.
Saya memiliki pom.xml
file yang mendefinisikan dependensi untuk kerangka kerja aplikasi web yang ingin saya gunakan, dan saya dapat dengan cepat menghasilkan proyek pemula dari file itu. Namun, kadang-kadang saya ingin menautkan ke perpustakaan pihak ke-3 yang belum memiliki pom.xml
file yang ditentukan, jadi daripada membuat pom.xml
file untuk lib pihak ke-3 dengan tangan dan menginstalnya, dan menambahkan ketergantungan pada saya pom.xml
, saya hanya ingin memberi tahu Maven: "Selain dependensi yang ditentukan, sertakan juga toples yang ada di /lib
dalamnya."
Sepertinya ini seharusnya sederhana, tetapi jika ya, saya kehilangan sesuatu.
Setiap petunjuk tentang cara melakukan ini sangat dihargai. Singkatnya, jika ada cara sederhana untuk mengarahkan maven ke /lib
direktori dan dengan mudah membuat pom.xml
dengan semua guci terlampir yang dipetakan ke satu dependensi yang kemudian bisa saya beri nama / instal dan tautkan ke dalam satu gerakan juga cukup.
Jawaban:
Masalah pendekatan populer
Sebagian besar jawaban yang akan Anda temukan di internet akan menyarankan Anda untuk menginstal dependensi ke repositori lokal Anda atau menentukan cakupan "sistem" di
pom
dan mendistribusikan dependensi dengan sumber proyek Anda. Tetapi kedua solusi ini sebenarnya cacat.Mengapa Anda tidak harus menerapkan pendekatan "Instal ke Repo Lokal"
Ketika Anda menginstal dependensi ke repositori lokal Anda, itu tetap ada. Artefak distribusi Anda akan baik-baik saja asalkan memiliki akses ke repositori ini. Masalahnya adalah dalam kebanyakan kasus repositori ini akan berada di komputer lokal Anda, jadi tidak akan ada cara untuk menyelesaikan ketergantungan ini pada mesin lain. Jelas membuat artefak Anda bergantung pada mesin tertentu bukanlah cara untuk menangani berbagai hal. Kalau tidak, ketergantungan ini harus dipasang secara lokal pada setiap mesin yang bekerja dengan proyek itu yang tidak lebih baik.
Mengapa Anda tidak harus menerapkan pendekatan "Cakupan Sistem"
Guci yang Anda andalkan dengan pendekatan "Lingkup Sistem" tidak bisa diinstal ke repositori apa pun atau dilampirkan ke paket target Anda. Itu sebabnya paket distribusi Anda tidak akan memiliki cara untuk mengatasi ketergantungan itu ketika digunakan. Yang saya percaya adalah alasan mengapa penggunaan ruang lingkup sistem bahkan menjadi usang. Pokoknya Anda tidak ingin bergantung pada fitur usang.
Solusi repositori statis dalam proyek
Setelah meletakkan ini di
pom
:untuk setiap artefak dengan id grup bentuk
x.y.z
Maven akan menyertakan lokasi berikut di dalam dir proyek Anda dalam pencariannya untuk artefak:Untuk menjelaskan lebih lanjut tentang ini, Anda dapat membaca posting blog ini .
Gunakan Maven untuk menginstal ke proyek repo
Alih-alih membuat struktur ini dengan tangan, saya sarankan untuk menggunakan plugin Maven untuk menginstal guci Anda sebagai artefak. Jadi, untuk menginstal artifact ke repositori dalam-proyek di dalam
repo
folder, jalankan:Jika Anda memilih pendekatan ini, Anda dapat menyederhanakan deklarasi repositori
pom
menjadi:Naskah pembantu
Karena mengeksekusi perintah instalasi untuk setiap lib agak menjengkelkan dan pasti rentan kesalahan, saya telah membuat skrip utilitas yang secara otomatis menginstal semua guci dari
lib
folder ke repositori proyek, sementara secara otomatis menyelesaikan semua metadata (groupId, artifactId, dll.) Dari nama file. Script juga mencetak dependensi xml untuk Anda salin-tempel dipom
.Sertakan dependensi dalam paket target Anda
Ketika repositori dalam-proyek Anda dibuat, Anda akan memecahkan masalah mendistribusikan dependensi proyek dengan sumbernya, tetapi sejak itu artefak target proyek Anda akan tergantung pada guci yang tidak dipublikasikan, jadi ketika Anda menginstal ke repositori ia akan memiliki dependensi yang tidak dapat dipecahkan.
Untuk mengatasi masalah ini, saya sarankan untuk memasukkan dependensi ini dalam paket target Anda. Ini dapat Anda lakukan dengan Plugin Majelis atau lebih baik dengan Plugin OneJar . Dokumentasi resmi tentang OneJar mudah dipahami.
sumber
Hanya untuk membuang kode
mengatur ruang lingkup == sistem dan hanya membuat groupId, artifactId, dan versi
Catatan: dependensi sistem tidak disalin ke dalam jar / perang yang dihasilkan
(lihat Cara memasukkan dependensi sistem dalam perang yang dibuat menggunakan pakar )
sumber
system
lingkup adalah praktik mengerikan yang sangat tidak dianjurkan . Lihat Ketergantungan + Cakupan .Anda dapat membuat repositori lokal di proyek Anda
Misalnya jika Anda memiliki
libs
folder dalam struktur proyekDalam
libs
folder Anda harus membuat struktur direktori seperti:/groupId/artifactId/version/artifactId-version.jar
Di pom.xml Anda, Anda harus mendaftarkan repositori
dan tambahkan ketergantungan seperti biasa
Itu semuanya.
Untuk informasi terperinci: Cara menambahkan perpustakaan eksternal di Maven
sumber
Catatan: Saat menggunakan lingkup Sistem ( seperti yang disebutkan di halaman ini ), Maven membutuhkan jalur absolut.
Jika toples Anda berada di bawah root proyek Anda, Anda akan ingin mengawali nilai systemPath Anda dengan $ {basedir}.
sumber
Ini adalah apa yang telah saya lakukan, ia juga bekerja di sekitar masalah paket dan berfungsi dengan memeriksa kode.
Saya membuat folder baru di proyek dalam kasus saya yang saya gunakan
repo
, tetapi merasa bebas untuk digunakansrc/repo
Dalam POM saya, saya memiliki ketergantungan yang tidak ada di repositori umum
Saya kemudian membuat direktori berikut
repo/com/dovetail/zoslog4j/1.0.1
dan menyalin file JAR ke folder itu.Saya membuat file POM berikut untuk mewakili file yang diunduh (langkah ini opsional, tetapi menghapus PERINGATAN) dan membantu orang berikutnya mencari tahu di mana saya mendapatkan file untuk memulai.
Dua file opsional yang saya buat adalah checksum SHA1 untuk POM dan JAR untuk menghapus peringatan checksum yang hilang.
Akhirnya saya menambahkan fragmen berikut ke pom.xml saya yang memungkinkan saya untuk merujuk ke repositori lokal
sumber
Anda benar-benar harus mendapatkan kerangka kerja melalui repositori dan mengidentifikasi dependensi Anda di muka. Menggunakan ruang lingkup sistem adalah kesalahan umum yang digunakan orang, karena mereka "tidak peduli dengan manajemen ketergantungan." Masalahnya adalah bahwa dengan melakukan ini, Anda akan berakhir dengan sosok pakar sesat yang tidak akan memperlihatkan pakar dalam kondisi normal. Anda akan lebih baik mengikuti pendekatan seperti ini .
sumber
Inilah cara kami menambahkan atau memasang toples lokal
saya memberikan beberapa groupId dan artifactId default karena mereka wajib :)
sumber
Plugin install Maven memiliki penggunaan baris perintah untuk menginstal toples ke repositori lokal, POM adalah opsional tetapi Anda harus menentukan GroupId, ArtifactId, Versi dan Kemasan (semua hal-hal POM).
sumber
Menggunakan
<scope>system</scope>
adalah ide yang buruk karena alasan yang dijelaskan oleh orang lain, menginstal file secara manual ke repositori lokal Anda membuat build tidak dapat diproduksi kembali, dan menggunakan<url>file://${project.basedir}/repo</url>
bukanlah ide yang baik karena (1) itu mungkin bukanfile
URL yang terbentuk dengan baik (misalnya jika proyek diperiksa dalam direktori dengan karakter yang tidak biasa), (2) hasilnya tidak dapat digunakan jika POM proyek ini digunakan sebagai ketergantungan proyek orang lain.Dengan asumsi Anda tidak mau mengunggah artefak ke repositori publik, saran Simeon tentang modul pembantu mengerjakan tugasnya. Tetapi ada cara yang lebih mudah sekarang ...
Rekomendasi
Gunakan non-maven-jar-maven-plugin . Melakukan persis apa yang Anda minta, tanpa ada kelemahan dari pendekatan lain.
sumber
Saya menemukan cara lain untuk melakukan ini, lihat di sini dari pos Heroku
Untuk meringkas (maaf tentang beberapa copy & paste)
repo
direktori di bawah folder root Anda:pom.xml
:sumber
Setelah berdiskusi sangat lama dengan para CloudBees tentang kemasan JAR yang benar, mereka membuat proposal yang bagus untuk solusi:
Pembuatan proyek Maven palsu yang melampirkan JAR yang sudah ada sebelumnya sebagai artefak utama, berjalan ke POM milik install: eksekusi-install file. Berikut ini adalah contoh Kinf dari POM tersebut:
Tetapi untuk mengimplementasikannya, struktur proyek yang ada harus diubah. Pertama, Anda harus ingat bahwa untuk setiap jenis JAR seperti itu harus dibuat proyek Maven palsu yang berbeda (modul). Dan harus ada dibuat proyek induk Maven termasuk semua sub-modul yaitu: semua pembungkus JAR dan proyek utama yang ada. Strukturnya bisa:
Saat induk berjalan melalui mvn: install atau mvn: pengemasan dipaksa dan sub-modul akan dieksekusi. Itu bisa dikhawatirkan sebagai minus di sini, karena struktur proyek harus diubah, tetapi menawarkan solusi non statis pada akhirnya
sumber
Yang tampaknya paling sederhana bagi saya adalah mengkonfigurasi maven-compiler-plugin Anda untuk memasukkan toples khusus Anda. Contoh ini akan memuat file jar apa pun di direktori lib.
sumber
says nothing to complile
!all classes are up to date
nothing to compile
karena tidak akan mencari*.java
lagi. Anda dapat menambahkannya kembali menggunakan<include>**/*.java</include>
. Namun tidak ada kesuksesan bagi saya untuk toplesMasalahnya
systemPath
adalah bahwa stoples dependensi tidak akan didistribusikan di sepanjang artefak Anda sebagai dependensi transitif. Coba apa yang saya posting di sini: Apakah yang terbaik untuk memangkas file tabung proyek Anda atau meletakkannya di WEB-INF / lib?Kemudian nyatakan dependensi seperti biasa.
Dan tolong baca catatan kaki.
sumber
Solusi aneh yang saya temukan:
menggunakan Eclipse
bersorak, Balint
sumber
Jika Anda menginginkan solusi cepat dan kotor, Anda dapat melakukan hal berikut (meskipun saya tidak merekomendasikan ini untuk apa pun kecuali proyek uji, pakar akan mengeluh panjang lebar bahwa ini tidak tepat).
Tambahkan entri ketergantungan untuk setiap file jar yang Anda butuhkan, lebih disukai dengan skrip perl atau sesuatu yang serupa dan salin / tempelkan itu ke file pom Anda.
sumber
Sebuah cepat & kotor solusi bets (berdasarkan jawaban Alex):
libs.bat
Jalankan seperti ini:
libs.bat > libs.txt
. Kemudian bukalibs.txt
dan salin isinya sebagai dependensi.Dalam kasus saya, saya hanya perlu perpustakaan untuk mengkompilasi kode saya, dan solusi ini adalah yang terbaik untuk tujuan itu.
sumber
Meskipun tidak persis sesuai dengan masalah Anda, saya akan menjatuhkan ini di sini. Persyaratan saya adalah:
Mari kita bicara tentang (3) pertama: Hanya memiliki guci dalam folder dan entah bagaimana menggabungkannya ke dalam guci terakhir tidak akan bekerja di sini, karena IDE tidak akan mengerti ini. Ini berarti semua perpustakaan harus diinstal dengan benar. Namun, saya tidak ingin semua orang menginstalnya menggunakan "mvn install-file".
Dalam proyek saya, saya membutuhkan metawidget. Kita mulai:
Setiap kali Anda memiliki perpustakaan baru, cukup tambahkan eksekusi baru dan beri tahu semua orang untuk membangun proyek lagi (Anda dapat meningkatkan proses ini dengan hierarki proyek).
sumber
Untuk menginstal toples pihak ke-3 yang tidak ada dalam repositori maven, gunakan maven-install-plugin.
Berikut langkah-langkahnya:
Di bawah ini adalah contoh yang saya gunakan untuk sim4ite log4j
Di pom.xml sertakan dependensi seperti di bawah ini
Jalankan perintah install mvn clean untuk membuat kemasan Anda
Di bawah ini adalah tautan referensi:
https://maven.apache.org/guides/mini/guide-3rd-party-jars-local.html
sumber
Bagi mereka yang tidak menemukan jawaban yang baik di sini, inilah yang kami lakukan untuk mendapatkan stoples dengan semua dependensi yang diperlukan di dalamnya. Jawaban ini ( https://stackoverflow.com/a/7623805/1084306 ) menyebutkan untuk menggunakan plugin Maven Assembly tetapi tidak benar-benar memberikan contoh dalam jawabannya. Dan jika Anda tidak membaca sampai akhir jawaban (itu cukup panjang), Anda mungkin melewatkannya. Menambahkan di bawah ini ke pom.xml Anda akan menghasilkan
target/${PROJECT_NAME}-${VERSION}-jar-with-dependencies.jar
sumber
Saya menyinggung beberapa kode python dalam komentar untuk jawaban dari @alex lehmann, jadi saya posting di sini.
sumber
Ini tidak menjawab bagaimana menambahkannya ke POM Anda, dan mungkin tidak punya otak, tetapi apakah hanya menambahkan lib dir ke pekerjaan classpath Anda? Saya tahu itulah yang saya lakukan ketika saya membutuhkan stoples eksternal yang tidak ingin saya tambahkan ke repo Maven saya.
Semoga ini membantu.
sumber
Apa yang berhasil dalam proyek kami adalah apa yang ditulis Archimedes Trajano, tapi kami punya di .m2 / settings.xml kami sesuatu seperti ini:
dan * harus diubah ke pusat. Jadi, jika jawabannya tidak bekerja untuk Anda, Anda harus memeriksa pengaturan Anda.xml
sumber
Saya hanya ingin solusi cepat dan kotor ... Saya tidak bisa menjalankan skrip dari Nikita Volkov: kesalahan sintaks + itu memerlukan format yang ketat untuk nama-nama toples.
Saya membuat skrip Perl ini yang berfungsi dengan format apa pun untuk nama file jar, dan menghasilkan dependensi dalam xml sehingga dapat disalin secara langsung di pom.
Jika Anda ingin menggunakannya, pastikan Anda memahami apa yang dilakukan skrip, Anda mungkin perlu mengubah
lib
folder dan nilai untukgroupId
atauartifactId
...sumber
Solusi untuk pendekatan scope = 'system' di Java:
sumber