Gradle kildesæt

1. Oversigt

Kildesæt giver os en effektiv måde at strukturere kildekoden på i vores Gradle-projekter.

I denne hurtige vejledning skal vi se, hvordan du bruger dem.

2. Standard kildesæt

Før vi springer ind i standardindstillingerne, lad os først forklare, hvad kildesæt er. Som navnet antyder, kildesæt repræsenterer en logisk gruppering af kildefiler.

Vi dækker konfigurationen af ​​Java-projekter, men begreberne gælder også for andre Gradle-projekttyper.

2.1. Standard projektlayout

Lad os starte med en simpel projektstruktur:

source-sets ├── src │ └── main │ ├── java │ │ ├── SourceSetsMain.java │ │ └── SourceSetsObject.java │ └── test │ └── SourceSetsTest.java └── build. gradle 

Lad os nu se på build.gradle:

anvend plugin: "java" description = "Kilde Sætter eksempel" test {testLogging {events "bestået", "sprunget over", "mislykkedes"}} afhængigheder {implementering ('org.apache.httpcomponents: httpclient: 4.5.12') testImplementation ('junit: junit: 4.12')}

Java-pluginet antager src / main / java og src / test / java som standardkildekataloger.

Lad os lave en simpel værktøjsopgave:

opgave printSourceSetInformation () {doLast {sourceSets.each {srcSet -> println "[" + srcSet.name + "]" print "-> Kildekataloger:" + srcSet.allJava.srcDirs + "\ n" print "-> Output kataloger: "+ srcSet.output.classesDirs.files +" \ n "println" "}}

Vi udskriver nogle få kildesætegenskaber her. Vi kan altid kontrollere hele JavaDoc for at få flere oplysninger.

Lad os køre det og se, hvad vi får:

$ ./gradlew printSourceSetInformation> Opgave: kildesæt: printSourceSetInformation [main] -> Kildekataloger: [... / source-sets / src / main / java] -> Outputkataloger: [... / source- sæt / build / klasser / java / main] [test] -> Kildekataloger: [... / kildesæt / src / test / java] -> Outputkataloger: [... / kildesæt / build / klasser / java / test] 

Varsel vi har to standard kildesæt: vigtigste og prøve.

2.2. Standardkonfigurationer

Java-pluginet opretter også automatisk nogle standard Gradle-konfigurationer for os.

De følger en særlig navngivningskonvention: .

Vi bruger dem til at erklære afhængighederne i build.gradle:

afhængigheder {implementering ('org.apache.httpcomponents: httpclient: 4.5.12') testImplementation ('junit: junit: 4.12')}

Bemærk, at vi specificerer implementering i stedet for mainImplementation. Dette er en undtagelse fra navngivningskonventionen.

Som standard, testImplementering konfigurationen udvides implementering og arver alle dens afhængigheder og output.

Lad os forbedre vores hjælperopgave og se, hvad det handler om:

opgave printSourceSetInformation () {doLast {sourceSets.each {srcSet -> println "[" + srcSet.name + "]" print "-> Kildekataloger:" + srcSet.allJava.srcDirs + "\ n" print "-> Output mapper: "+ srcSet.output.classesDirs.files +" \ n "print" -> Kompilér klassebane: \ n "srcSet.compileClasspath.files.each {print" "+ it.path +" \ n "} println" "} }}

Lad os se på output:

[main] // samme output som før -> Kompilér klassebane: ... / httpclient-4.5.12.jar ... / httpcore-4.4.13.jar ... / commons-logging-1.2.jar .. ./commons-codec-1.11.jar [test] // samme output som før -> Kompilér klassebane: ... / kildesæt / build / klasser / java / main ... / kildesæt / build / ressourcer / main ... / httpclient-4.5.12.jar ... / junit-4.12.jar ... / httpcore-4.4.13.jar ... / commons-logging-1.2.jar ... / commons- codec-1.11.jar ... / hamcrest-core-1.3.jar

Det prøve kildesæt indeholder output fra vigtigste i sin kompilér klassesti og inkluderer også dens afhængigheder.

Lad os derefter oprette vores enhedstest:

offentlig klasse SourceSetsTest {@Test offentlig ugyldig når Run_ThenSuccess () {SourceSetsObject underTest = ny SourceSetsObject ("lorem", "ipsum"); assertThat (underTest.getUser (), er ("lorem")); assertThat (underTest.getPassword (), er ("ipsum")); }}

Her tester vi en simpel POJO, der gemmer to værdier. Vi kan bruge det direkte fordi det vigtigste output er i vores prøve klassesti.

Lad os derefter køre dette fra Gradle:

./gradlew clean test> Task: source-sets: test com.baeldung.test.SourceSetsTest> whenRunThenSuccess PASSED 

3. Brugerdefinerede kildesæt

Indtil videre har vi set nogle fornuftige standardindstillinger. I praksis har vi dog ofte brug for tilpassede kildesæt, især til integrationstests.

Det skyldes, at vi måske kun vil have specifikke testbiblioteker på klassestien til integrationstest. Vi vil muligvis også udføre dem uafhængigt af enhedstest.

3.1. Definition af brugerdefinerede kildesæt

Lad os lave en separat kildekatalog til vores integrationstest:

kildesæt ├── src │ └── hoved │ ├── java │ │ ├── SourceSetsMain.java │ │ └── SourceSetsObject.java │ ├── test │ │ └── SourceSetsTest.java │ └── itest │ └── SourceSetsITest.java └── build.gradle 

Lad os derefter konfigurer det i vores build.gradle bruger sourceSets konstruere:

sourceSets {itest {java {}}} afhængigheder {implementering ('org.apache.httpcomponents: httpclient: 4.5.12') testImplementation ('junit: junit: 4.12')} // andre erklæringer udeladt 

Bemærk, at vi ikke angav nogen brugerdefineret mappe. Det er fordi vores mappe matcher navnet på det nye kildesæt (itest).

Vi kan tilpasse, hvilke mapper der er inkluderet i srcDirs ejendom:

sourceSets {itest {java {srcDirs ("src / itest")}}}

Husk vores hjælperopgave fra starten? Lad os køre det igen og se, hvad det udskriver:

$ ./gradlew printSourceSetInformation> Opgave: kildesæt: printSourceSetInformation [itest] -> Kildekataloger: [... / kildesæt / src / itest / java] -> Outputkataloger: [... / kilde- sæt / build / klasser / java / itest] -> Kompilér klassebane: ... / kildesæt / build / klasser / java / main ... / source-sets / build / resources / main [main] // same output som før [test] // samme output som før

3.2. Tildeling af kildesætsspecifikke afhængigheder

Husker du standardkonfigurationer? Vi får nu nogle konfigurationer til itest kildesæt også.

Lad os bruge itestImplementation for at tildele en ny afhængighed:

afhængigheder {implementering ('org.apache.httpcomponents: httpclient: 4.5.12') testImplementation ('junit: junit: 4.12') itestImplementation ('com.google.guava: guava: 29.0-jre')}

Denne gælder kun for integrationstest.

Lad os ændre vores tidligere test og tilføje den som en integrationstest:

offentlig klasse SourceSetsItest {@Test offentlig ugyldighed givenImmutableList_whenRun_ThenSuccess () {SourceSetsObject underTest = ny SourceSetsObject ("lorem", "ipsum"); Liste over someStrings = ImmutableList.of ("Baeldung", "is", "cool"); assertThat (underTest.getUser (), er ("lorem")); assertThat (underTest.getPassword (), er ("ipsum")); assertThat (someStrings.size (), er (3)); }}

At kunne at køre det, vi er nødt til definere en brugerdefineret testopgave, der bruger de kompilerede output:

// kilde sætter erklæringer // afhængighedserklæringer opgave itest (type: test) {beskrivelse = "Kør integrationstest" gruppe = "verifikation" testClassesDirs = sourceSets.itest.output.classesDirs classpath = sourceSets.itest.runtimeClasspath}

Disse erklæringer evalueres i konfigurationsfasen. Som resultat, deres rækkefølge er vigtig.

For eksempel kan vi ikke henvise til itest kilde, der er angivet i opgaveorganet, før dette erklæres.

Lad os se, hvad der sker, hvis vi kører testen:

$ ./gradlew clean itest // nogle kompileringsproblemer FAILURE: Build mislykkedes med en undtagelse. * Hvad gik galt: Udførelse mislykkedes for opgave ': source-sets: compileItestJava'. > Kompilering mislykkedes; se compilerfejloutputtet for detaljer.

I modsætning til det forrige løb får vi en kompileringsfejl denne gang. Hvad skete der?

Dette nye kildesæt skaber en uafhængig konfiguration.

Med andre ord, itestImplementation arver ikke JUnit afhængighed, og det får heller ikke output fra vigtigste.

Lad os rette dette i vores Gradle-konfiguration:

sourceSets {itest {compileClasspath + = sourceSets.main.output runtimeClasspath + = sourceSets.main.output java {}}} // afhængighedserklæringskonfigurationer {itestImplementation.extendsFrom (testImplementation) itestRuntimeOnly.extendsFrom (testRuntimeOnly)}

Lad os nu køre vores integrationstest igen:

$ ./gradlew clean itest> Task: source-sets: itest com.baeldung.itest.SourceSetsItest> givenImmutableList_whenRun_ThenSuccess PASSED

Testen består.

3.3. Formørkelse IDE-håndtering

Vi har hidtil set, hvordan man arbejder med kildesæt direkte med Gradle. Men det meste af tiden bruger vi en IDE (såsom Eclipse).

Når vi importerer projektet, får vi nogle kompileringsproblemer:

Men hvis vi kører integrationstesten fra Gradle, får vi ingen fejl:

$ ./gradlew clean itest> Task: source-sets: itest com.baeldung.itest.SourceSetsItest> givenImmutableList_whenRun_ThenSuccess PASSED

Hvad skete der? I dette tilfælde er guava afhængighed hører til itestImplementation.

Desværre, Eclipse Buildship Gradle plugin håndterer ikke disse brugerdefinerede konfigurationer særlig godt.

Lad os ordne dette i vores build.gradle:

anvend plugin: "eclipse" // tidligere erklæringer eclipse {classpath {plusConfigurations + = [configurations.itestCompileClasspath]}} 

Lad os forklare, hvad vi gjorde her. Vi tilføjede vores konfiguration til Eclipse classpath.

Hvis vi opdaterer projektet, er kompileringsproblemerne væk.

Imidlertid, der er en ulempe ved denne tilgang: IDE skelner ikke mellem konfigurationer.

Det betyder vi kan nemt importere guava i vores prøve kilder (som vi specifikt ønskede at undgå).

4. Konklusion

I denne vejledning dækkede vi det grundlæggende i Gradle-kildesæt.

Derefter forklarede vi, hvordan tilpassede kildesæt fungerer, og hvordan de bruges i Eclipse.

Som sædvanlig kan vi finde den komplette kildekode på GitHub.