Gradle: Apa perbedaan antara classpath dan dependensi kompilasi?

92

Saat menambahkan dependensi ke proyek saya, saya tidak pernah yakin awalan apa yang harus saya berikan kepada mereka, misalnya "classpath"atau"compile".

Misalnya, haruskah dependensi saya di bawah ini berupa waktu kompilasi atau classpath?

Juga, haruskah ini ada di aplikasi saya build.gradle atau di modul build.gradle khusus?

Build.gradle saat ini (di level aplikasi):

apply plugin: 'java'

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.hibernate:hibernate-core:5.0.5.Final'
    compile 'mysql:mysql-connector-java:5.1.38'
} 
java123999
sumber
1
Saya tidak yakin saya mengerti. classpathbukan cakupan ketergantungan yang valid.
Tunaki
Mungkin saya bingung, apa saja cakupan dependensi yang valid?
java123999
Lihatlah dokumen ini: docs.gradle.org/current/userguide/…
Tunaki
Satu hal yang saya perhatikan adalah bahwa compileOnlydependensi mengarah ke project.configurations.compileClasspathtetapi tidak ke project.configurations.compile, seperti yang disebutkan di sini github.com/iboyko/gradle-plugins/issues/5
Vytenis Bivainis

Jawaban:

47

Saya akan menebak bahwa Anda mereferensikan compiledan classpathdi dalam dependencies {}blok. Jika demikian, itu adalah Konfigurasi ketergantungan .

Konfigurasi hanyalah sekumpulan dependensi bernama.

The compilekonfigurasi dibuat oleh plugin Java. The classpathkonfigurasi sering terlihat di buildSrc {}blok mana salah satu kebutuhan untuk menyatakan dependensi untuk build.gradle, itu sendiri (untuk plugin, mungkin).

Eric Wendelin
sumber
Terima kasih, jadi untuk build.gradle utama saya, saya tidak perlu menggunakan classpath?
java123999
@ java123999 Tidak, kecuali Anda menggunakan plugin yang ditulis khusus
Eric Wendelin
@EricWendelin Di mana Anda mengatakan "dalam blok {} dependensi" yang Anda maksud "di dalam blok {dependencies {}} buildscript"? (Saya tidak yakin, hanya bertanya.)
Paulo Merson
2
Sebuah dependencies {}blok dapat dideklarasikan baik di dalam maupun di buildscript {}luarnya. Saat berada di dalam, Anda menggunakan classpathkonfigurasi untuk dependensi yang diperlukan untuk mengompilasi skrip build itu sendiri.
Eric Wendelin
55

Jika buildscript itu sendiri membutuhkan sesuatu untuk dijalankan, gunakan classpath .

Jika proyek Anda membutuhkan sesuatu untuk dijalankan, gunakan kompilasi .

The buildscript{}blok untuk build.gradle itu sendiri.

Untuk pembangunan multi-proyek, file build tingkat atas adalah untuk proyek root, file build spesifik untuk sub-proyek (modul).

File build level atas tempat Anda dapat menambahkan opsi konfigurasi yang umum untuk semua subproyek / modul.

Jangan tempatkan dependensi aplikasi Anda dalam file build level atas, dependensi tersebut termasuk dalam file build.gradle modul individual

q ...
sumber
Untuk mengonfirmasi: apakah itu berarti proandroiddev.com/… harus menggunakan a compiledan bukan classpath?
WillC
1
Tetapi mengapa tidak menempatkan dependensi aplikasi di file level atas itu sendiri jika proyek tersebut hanya memiliki satu modul, seperti aplikasi android pada umumnya?
Harsha
18

Jika saya mengerti dengan benar, Anda mengacaukan Project.dependenciesblok skrip dengan Project.buildscript.dependenciesblok skrip (seperti yang saya lakukan ketika saya mencapai pertanyaan ini).

Saya akan mencoba menjawab ini dengan apa yang saya temukan.

Saya pikir Anda seharusnya sudah terbiasa dengan Project.dependenciesblok skrip. Di blok ini, kami mendeklarasikan dependensi yang diperlukan oleh kode sumber kami. Ada beberapa cara untuk mendeklarasikan ketergantungan yang kita perlukan untuk proyek tersebut. Lihat Tutorial Gradle: Jenis Ketergantungan . Saya hanya akan menyebutkan bagian yang paling relevan dengan masalah ini:

compile 'org.hibernate:hibernate-core:5.0.5.Final'adalah deklarasi ketergantungan modul. Konfigurasi kompilasi (yang sekarang sudah tidak digunakan lagi oleh konfigurasi implementasi.) Hanyalah sebuah kata kunci untuk Implementation only dependencies.Ini bukan kata kunci yang menjelaskan jenis ketergantungannya (menurut jenis di sini saya mengikuti tiga jenis yang ditentukan dalam tutorial, yaitu modul, file, dan proyek.)

Dalam Gradle Tutorial: Organizing Build Logic dikatakan:

Jika skrip build Anda perlu menggunakan pustaka eksternal, Anda dapat menambahkannya ke classpath skrip dalam skrip build itu sendiri. Anda melakukan ini menggunakan metode buildscript (), meneruskan closure yang mendeklarasikan classpath skrip build.

Ini adalah cara yang sama Anda mendeklarasikan, misalnya, classpath kompilasi Java. Anda dapat menggunakan salah satu tipe dependensi yang dijelaskan dalam Tipe Ketergantungan, kecuali ketergantungan proyek.

Setelah mendeklarasikan classpath skrip build, Anda dapat menggunakan kelas dalam skrip build seperti yang Anda lakukan pada kelas lain di classpath.

Saya harap semuanya menjadi jelas bagi Anda sekarang.

Dengan classpath "com.android.tools.build:gradle:${Versions.android_gradle_plugin}"kami menyetel classpathmetode com.android.tools.build:gradle:${Versions.android_gradle_plugin}yang merupakan dependensi modul yang digunakan oleh skrip build itu sendiri, bukan sumber dalam proyek Anda.

Di sisi lain, dengan compile 'org.hibernate:hibernate-core:5.0.5.Final'kami mendeklarasikan ketergantungan modul yang diperlukan untuk proyek Anda dengan konfigurasi kompilasi .

tl; dr: The classpath,, compiledan implementationadalah semua kata kunci yang dapat digunakan melawan dependensi dalam keadaan yang berbeda. Yang pertama digunakan saat Anda ingin meneruskan dependensi ke skrip build, dan yang terakhir adalah salah satu konfigurasi yang mungkin ingin Anda deklarasikan.

Teng-pao Yu
sumber
1
Jawaban yang bagus. Saya harus menambahkan, bahwa kita tidak hanya harus melihat kata kunci itu sendiri seperti yang dijelaskan dengan baik di atas, tetapi selain itu kita juga harus mempertimbangkan artefak yang diminta karena kata kunci saja tidak menentukan konteks secara lengkap. Misalnya, 'org.projectlombok:lombok:1.18.4'tidak memiliki classpathpengaitan karena ini adalah jar yang hanya diperlukan selama javacwaktu kompilasi tetapi tidak diperlukan pada waktu proses java. Oleh karena itu, penggunaan yang benar merupakan interaksi antara kata kunci dan artefak yang ditentukan. Artinya, seseorang membutuhkan pengetahuan apriori.
eigenfield