Perbedaan antara kompilasi lingkup maven dan disediakan untuk kemasan JAR

260

Apa perbedaan antara ruang lingkup pakar compiledan providedketika artefak dibangun sebagai JAR? Jika itu PERANG, saya akan mengerti - artefak akan dimasukkan atau tidak dalam WEB-INF / lib. Tetapi dalam kasus JAR tidak masalah - dependensi tidak termasuk. Mereka harus berada di classpath ketika ruang lingkup mereka compileatau provided. Saya tahu bahwa provideddependensi tidak transitif - tetapi apakah hanya satu perbedaan?

emstol
sumber

Jawaban:

289

Dari Maven Doc :

  • menyusun

    Ini adalah ruang lingkup standar, digunakan jika tidak ada yang ditentukan. Kompilasi dependensi tersedia di semua jalan setapak proyek. Selain itu, dependensi tersebut disebarkan ke proyek dependen.

  • disediakan

    Ini mirip kompilasi, tetapi menunjukkan Anda mengharapkan JDK atau wadah untuk memberikan dependensi saat runtime. Misalnya, saat membuat aplikasi web untuk Java Enterprise Edition, Anda akan mengatur ketergantungan pada Servlet API dan Java EE API terkait ke ruang lingkup yang disediakan karena wadah web menyediakan kelas-kelas tersebut. Cakupan ini hanya tersedia pada kompilasi dan test classpath, dan tidak transitif.

Rekap:

  • dependensi tidak transitif (seperti yang Anda sebutkan)
  • ruang lingkup yang disediakan hanya tersedia pada kompilasi dan test classpath, sedangkan ruang lingkup kompilasi tersedia di semua classpath.
  • asalkan dependensi tidak dikemas
Yakub
sumber
5
Ya saya tahu. Tetapi saya merenungkan perbedaan dalam lingkup dalam JAR packagingkonteks. Maven doc tidak menyebutkan tentang itu. Saya menggunakan Maven untuk sementara waktu, tetapi saya baru saja bertanya pada diri sendiri tentang hal itu :) Jadi sepertinya dalam JAR packagingkonteksnya, tidak ada perbedaan antara compiledan provided(kecuali transisi ketergantungan). Apakah saya benar?
emstol
3
@ Jacob apa yang dimaksud dengan "sedangkan kompilasi cakupan tersedia di semua classpath ."
Geek
1
Saya pikir "BUKAN Transitif" adalah tangkapan besar di sini. Karena neraka ketergantungan adalah sesuatu yang sering dihadapi pengembang dan lingkup yang disediakan mencegahnya mengacaukan versi lain sangat penting.
Seetharamani Tmr
2
Saya pikir perbedaannya ada pada fase pengemasan. Dengan kompilasi, itu akan termasuk jar dalam perang terakhir atau jar (seperti jar boot yang dapat dieksekusi), dan asalkan hasilnya mungkin tidak. Karena tabung yang disediakan dapat disediakan oleh wadah web (seperti dimasukkan ke dalam folder ext lib), itu tidak dalam paket perang jika tidak bergantung pada cakupan lain, kompilasi, runtime.
Addo Zhang
1
@emstol Kembali ke pertanyaan awal Anda, Anda benar bahwa dalam kasus JAR, dependensi tidak dikemas di dalam JAR itu sendiri. Tetapi dalam maven, kemasan JAR berarti Anda ingin itu digunakan sebagai perpustakaan. Segera setelah Anda mengimpornya di beberapa proyek pakar lain, dependensi transitif akan dibawa jika cakupannya adalah compiledan tidak akan jika lingkupnya provided.
LeoLuz
291

Kompilasi berarti Anda membutuhkan JAR untuk mengkompilasi dan menjalankan aplikasi. Untuk aplikasi web, sebagai contoh, JAR akan ditempatkan di direktori WEB-INF / lib.

Asalkan berarti Anda memerlukan JAR untuk dikompilasi, tetapi pada saat run sudah ada JAR yang disediakan oleh lingkungan sehingga Anda tidak perlu itu JAR dikemas dengan aplikasi Anda. Untuk aplikasi web, ini berarti bahwa file JAR tidak akan ditempatkan ke direktori WEB-INF / lib.

Untuk aplikasi web, jika server aplikasi sudah menyediakan JAR (atau fungsinya), maka gunakan "asalkan" jika tidak gunakan "kompilasi".

Ini rujukannya.

Owen Cao
sumber
11
Anda tidak menjawab pertanyaan OP? ' Apa bedanya menggunakan kompilasi lingkup pakar dan diberikan ketika artefak dibangun sebagai JAR ? 'Perhatikan bahwa penulis secara eksplisit menyatakan bahwa mereka tahu bedanya saat mengemas sebagai perang.
Alberto
dapatkah saya menggunakan asalkan saya mereferensikan JAR lain yang digunakan pada server aplikasi yang sama ??
Samy Omar
1
Jadi untuk menjadi jelas, dependensi yang disediakan tidak ditambahkan ke classpath ketika mvn exec:javadijalankan, tetapi dependensi yang dikompilasi adalah.
Jamie
Saya mengajukan pertanyaan ini - stackoverflow.com/questions/37360132/... Masalahnya diselesaikan dengan mengubah ruang lingkup dari yang disediakan ke kompilasi. Tapi saya tidak melihat perbedaan antara jar yang dikompilasi dengan lingkup "yang disediakan" dan jar yang dikompilasi dengan ruang lingkup "kompilasi". Bisakah Anda menjelaskan mengapa?
Pavel_K
22

Jika Anda berencana untuk membuat file JAR tunggal dengan semua dependensinya (tipikal xxxx-all.jar), maka berikan ruang lingkup yang penting, karena kelas-kelas di dalam lingkup ini tidak akan menjadi paket dalam JAR yang dihasilkan.

Lihat maven-assembly-plugin untuk informasi lebih lanjut

jfcorugedo
sumber
7
asalkan dependensi ==> dependensi TIDAK akan dikemas.
Gab 是 好人
3
Kebingungan OP jelas terselesaikan saat Anda mengemas maven-assembly-plugin, menarik bahwa jawaban yang paling banyak dipilih tidak menyebutkannya.
Henrique G. Abreu
Saya tidak mengerti jawaban ini. Itu lebih mirip komentar.
reinierpost
11
  • menyusun

Jadikan tersedia ke jalur kelas, jangan tambahkan ketergantungan ini ke jar final jika itu adalah jar normal; tetapi tambahkan toples ini ke toples jika toples terakhir adalah toples tunggal (misalnya, toples yang dapat dieksekusi)

  • disediakan

Ketergantungan akan tersedia di lingkungan run time jadi jangan tambahkan ketergantungan ini dalam hal apa pun; bahkan tidak dalam satu toples (yaitu toples yang dapat dieksekusi dll)

Vijay
sumber
3

Untuk file jar, perbedaannya ada pada classpath yang tercantum dalam file MANIFEST.MF yang termasuk dalam jar jika addClassPath disetel ke true dalam konfigurasi maven-jar-plugin. dependensi 'kompilasi' akan muncul dalam manifes, dependensi 'yang disediakan' tidak akan.

Salah satu kesal saya adalah bahwa kedua kata ini harus memiliki bentuk yang sama. Baik disusun dan disediakan, atau kompilasi dan berikan.

Rick
sumber
0

Ketika Anda menetapkan lingkup maven sebagai provided, itu berarti bahwa ketika plugin berjalan, versi dependensi aktual yang digunakan akan tergantung pada versi Apache Maven yang telah Anda instal.

Vishwa Ratna
sumber
0

Jika file jar seperti file jar boot spring yang dapat dieksekusi, maka cakupan semua dependensi harus compilemencakup semua file jar.

Tetapi jika file jar digunakan dalam paket atau aplikasi lain maka itu tidak perlu menyertakan semua dependensi dalam file jar karena paket atau aplikasi ini dapat menyediakan dependensi lain sendiri.

Ali
sumber