Skip to content
Snippets Groups Projects
Commit e93a4969 authored by Hallvard Trætteberg's avatar Hallvard Trætteberg
Browse files

Litt mer om Gradle.

parent eb58c3f3
No related branches found
No related tags found
No related merge requests found
...@@ -25,9 +25,11 @@ repositories { ...@@ -25,9 +25,11 @@ repositories {
} }
} }
sourceCompatibility = JavaVersion.VERSION_1_10 application {
targetCompatibility = JavaVersion.VERSION_1_10 sourceCompatibility = JavaVersion.VERSION_1_10
mainClassName = 'simpleex.ui.FxApp' // application plugin targetCompatibility = JavaVersion.VERSION_1_10
mainClassName = 'simpleex.ui.FxApp' // application plugin
}
// javafx specific way of specifying dependencies // javafx specific way of specifying dependencies
javafx { javafx {
...@@ -71,14 +73,14 @@ checkstyle { ...@@ -71,14 +73,14 @@ checkstyle {
dependencies { dependencies {
// persistens // persistens
compile "com.fasterxml.jackson.core:jackson-databind:2.9.8" implementation 'com.fasterxml.jackson.core:jackson-databind:2.9.8'
// brukergrensesnitt // brukergrensesnitt
compile name: 'fx-map-control-1.0' implementation name: 'fx-map-control-1.0'
testImplementation 'junit:junit:4.12' testImplementation 'junit:junit:4.12'
// brukergrensesnitt // brukergrensesnitt
testImplementation "org.testfx:testfx-core:4.0.16-alpha" testImplementation 'org.testfx:testfx-core:4.0.16-alpha'
testImplementation "org.testfx:testfx-junit:4.0.16-alpha" testImplementation 'org.testfx:testfx-junit:4.0.16-alpha'
testImplementation "org.mockito:mockito-core:2.28.2" testImplementation 'org.mockito:mockito-core:2.28.2'
} }
...@@ -2,34 +2,69 @@ ...@@ -2,34 +2,69 @@
## Hva er bygging? ## Hva er bygging?
Moderne IDE-er gjør det nokså greit å sett opp et prosjekt slik at kompilering gjøres automatisk og kontinuerlig og kjøring gjøres med et tastetrykk eller klikk. I det skjulte håndteres riktig oppsett og bruk av biblioteker, tilsvarende å kalle java-kompilatoren med riktig classpath (og med de siste versjonenen av java, også modulepath osv). Så mens man i gamle dager måtte skrive inn kompileringskommandoer på kommandolinja, så gjøres det automatisk, i tillegg til at editoren kan komme med alskens automatiske forslag til koden basert på full oversikt over tilgjengelige API-er. Moderne IDE-er gjør det nokså greit å sett opp et prosjekt slik at kompilering gjøres automatisk og kontinuerlig og kjøring gjøres med et tastetrykk eller klikk. I det skjulte håndteres riktig oppsett og bruk av biblioteker, tilsvarende å kalle java-kompilatoren med riktig classpath (evt. modulepath med den siste versjonenen av java). Så mens man i gamle dager måtte skrive inn kompileringskommandoer i terminal, så gjøres det automatisk. I tillegg kommer editoren med alskens automatiske forslag til koden basert på full oversikt over tilgjengelige API-er.
Dette er vel og bra, men utvikling av applikasjoner handler ikke bare om å skrive kode, det er mange relaterte aktiviteter som er med og sikrer kvaliteten. Hvis en f.eks. skriver tester, så må disse forholde seg til egne testbibliotek (som [junit](https://junit.org/) og [mockito](https://site.mockito.org)) kjøres jevnlig. Testkjøring av systemer som består av mange moduler, kanskje én av dem er en web-server som skal startes som en del av en test, gjør det mye mer komplisert. Dette er vel og bra, men utvikling av applikasjoner handler ikke bare om å skrive kode, det er mange relaterte aktiviteter som er med og sikrer kvaliteten. Hvis en f.eks. skriver tester, så må disse forholde seg til egne testbibliotek (som [junit](https://junit.org/) og [mockito](https://site.mockito.org)) og kjøres jevnlig. Testkjøring av systemer som består av mange moduler, kanskje én av dem er en web-server som skal startes som en del av en test, gjør det mer komplisert.
Det er lurt å måle hvor stor del av koden som faktisk kjøres av tester, f.eks. med [jacoco](https://github.com/jacoco/jacoco). Noen prosjekter består av mange deler som både testes hver for seg og sammen. Det finnes andre kvaliteter enn korrekthet som også kan analyseres av diverse verktøy, f.eks. ryddighet, om man har fulgt konvensjoner for koding og unngått typiske kodingsfeil. Det er lurt å måle hvor stor del av koden som faktisk kjøres av tester, f.eks. med [jacoco](https://github.com/jacoco/jacoco). Noen prosjekter består av mange deler som både testes hver for seg og sammen. Det finnes andre kvaliteter enn korrekthet som også kan analyseres av diverse verktøy, f.eks. ryddighet, om man har fulgt konvensjoner for koding og unngått typiske kodingsfeil.
Hvis alt dette skal gjøres/kjøres manuelt, så gidder man ikke å gjøre det (ofte nok). IDE-er kan riktignok være til hjelp, men da blir det til gjengjeld opp til hver utvikler å sette det opp og det kan kreve nokså mye konfigurasjon. I stedet konfigurerer man prosjektet til å bruke et såkalt byggeverktøy, som lar deg kjøre utvalgte byggeoppgaver i riktig sekvens, basert på instruksjoner om hva slags prosjekt en har, hvilke byggetrinn som skal være med og detaljer ved disse. Innstillingene er uavhengig av hvilken IDE du bruker, skrevet i et (mer eller mindre) leselig format og kan sjekkes inn i kode-repo og deles med alle. Hvis alt dette skal gjøres/kjøres manuelt, så gidder man ikke å gjøre det (ofte nok). IDE-er kan riktignok være til hjelp, men da blir det til gjengjeld opp til hver utvikler å sette det opp og det kan kreve nokså mye konfigurasjon. I stedet konfigurerer man prosjektet til å bruke et såkalt *byggeverktøy*, som lar deg kjøre utvalgte *byggeoppgaver* i riktig sekvens, basert på deklarasjoner om hva slags prosjekt en har, hvilke byggetrinn som skal være med og detaljer ved disse. Innstillingene er uavhengig av hvilken IDE du bruker, skrevet i et (mer eller mindre) leselig format og kan sjekkes inn i kode-repo og deles med alle.
## Gradle ## Gradle
[Gradle](https://docs.gradle.org/current/userguide/userguide.html) er et slikt byggesystem, som automatiserer oppgaver knyttet til utvikling og kvalitetssikring av programvare, f.eks. [Gradle](https://docs.gradle.org/current/userguide/userguide.html) er et slikt byggesystem, som automatiserer oppgaver knyttet til utvikling og kvalitetssikring av programvare, f.eks.
kompilering, kjøring av enhetstester og integrasjonstester, konvertering av dokumentasjon til HTML, pakking som kjørbart program, osv. Det finnes teknisk sett ikke grenser for hva byggesystem som gradle kan gjøre, generelt handler det om å automatisere bort alt praktisk fikkel, som ellers hindrer en å jobbe effektivt. kompilering, kjøring av enhetstester og integrasjonstester, konvertering av dokumentasjon til HTML, pakking som kjørbart program, osv. Det finnes teknisk sett ikke grenser for hva byggesystem som gradle kan gjøre, generelt handler det om å automatisere bort alt praktisk fikkel, som ellers hindrer en å jobbe effektivt.
Det finnes flere byggesystem, de viktigste i Java-verdenen er https://maven.apache.org[Maven] og Gradle, mens Javascript-verdenen har sine, bl.a. [npm](https://docs.npmjs.com). Når vi velger å bruke gradle, så er det fordi det er enklere å skrive og lese oppsettet og trigge kjøring, mer fleksiblet, og det vi ønsker å automatisere i akkurat dette prosjektet er innafor det Gradle håndterer godt. For andre Java-prosjekter [kan Maven være et bedre alternativ](https://phauer.com/2018/moving-back-from-gradle-to-maven/). Det finnes flere byggesystem, de viktigste i Java-verdenen er [Maven](https://maven.apache.org) og altså Gradle, mens Javascript-verdenen har sine, bl.a. [npm](https://docs.npmjs.com). Når vi velger å bruke gradle, så er det fordi det er enklere å skrive og lese oppsettet og trigge kjøring, mer fleksiblet, og det vi ønsker å automatisere i akkurat dette prosjektet håndteres godt av Gradle. For andre Java-prosjekter [kan Maven være et bedre alternativ](https://phauer.com/2018/moving-back-from-gradle-to-maven/).
Gradle er bygget rundt tre sentrale elementer: Gradle er bygget rundt tre sentrale elementer:
- oppgaver (tasks) - det som automatiseres, f.eks. kompilering, kjøring av tester, osv. - oppgaver (tasks) - det som automatiseres, f.eks. kompilering, kjøring av tester, osv.
- prosjekter - enhetene som oppgaver utføres innenfor - prosjekter - enhetene som oppgaver utføres innenfor
- tillegg (plugins) - angir hvilke oppgaver som hører til et visst type prosjekt. - tillegg (plugins) - angir hvilke oppgaver som hører til et visst type prosjekt
**settings.gradle**-fila angir navn på prosjektet og eventuelle delprosjekter. Resten angis i **build.gradle**-fila, bl.a. hvilke avhengigheter det er til eksterne moduler og mellom prosjektene, hvilke tillegg som bør aktiveres for disse prosjektene (basert på hva slags type prosjekt det er) og hvordan hver type oppgave skal konfigureres. Disse tre elementene beskrives i to filer. **settings.gradle**-fila angir navn på prosjektet og eventuelle delprosjekter. Resten angis i **build.gradle**-fila, bl.a. hvilke avhengigheter det er til eksterne moduler og mellom prosjektene, hvilke tillegg som bør aktiveres for disse prosjektene (basert på hva slags type prosjekt det er) og hvordan hver type oppgave skal konfigureres.
Det litt spesielle med Gradle er at filene for å sette opp et Gradle-bygg egentlig er [kode skrevet i det Java-lignende språket Groovy](https://docs.gradle.org/current/userguide/groovy_build_script_primer.html). Koden brukes primært til konfigurasjon, altså bygge opp beskrivelsen av oppgavene, prosjektene og tilleggene og. API-et er utformet slik at koden skal se deklarativ ut. Det litt spesielle med Gradle er at filene for å sette opp et Gradle-bygg egentlig er [kode skrevet i det Java-lignende språket Groovy](https://docs.gradle.org/current/userguide/groovy_build_script_primer.html). Koden brukes primært til konfigurasjon, altså bygge opp beskrivelsen av oppgavene, prosjektene og tilleggene og. API-et er utformet slik at koden skal se deklarativ ut.
En kan flette inn vanlig kode også, hvis en skjønner litt om hvordan API-et virker. Dette gir enorm fleksibilitet, men kan også gjøre filene vanskelige å forstå. En kan flette inn vanlig kode også, hvis en skjønner litt om hvordan API-et virker. Dette gir enorm fleksibilitet, men kan også gjøre filene vanskelige å forstå.
## Gradle-tillegg ## Gradle-tillegg
`plugins`-blokken i **build.gradle** angir hvilke tillegg som skal aktiveres for prosjektet. Det handler dels om hva slags prosjekt en har, f.eks. om det er et Java-prosjekt og evt. bruker JavaFX, dels om hva som skal automatiseres. Deklarasjonen under angir at prosjektet er et Java-applikasjonsprosjekt og en ønsker å automatisere måling av testdekningsgrad (code coverage) med **jacoco**.
```
plugins {
// java application with main method
id 'application'
// test coverage
id 'jacoco'
}
```
## Konfigurasjon av oppgaver ## Konfigurasjon av oppgaver
For hvert tillegg vil en gjerne ha ytterligere konfigurasjon, enten som enkeltinstruksjoner eller blokker. F.eks. angir instruksjonen `mainClassName = ...` hvilken klasse som inneholder `main`-metoden, og dette brukes av `application`-tillegget. Detaljene finner en typisk ved å google, prøv f.eks. å søke på `gradle application plugin`.
## Avhengigheter ## Avhengigheter
En av de viktigste blokkene i **build.gradle** er `dependencies`, altså *avhengigheter*. Her lister man opp hvilke kodebiblioteker (jar-filer) ens egen kode er avhengig av og til hva slags formål. Dette hjelper ulike tillegg å bruke riktig classpath til kompilering og kjøring av både vanlig kode og testkoden. Blokken under angir f.eks. at koden bruker `jackson-databind`-biblioteket og at en til testing også trenger `junit`-biblioteket:
```
dependencies {
implementation 'com.fasterxml.jackson.core:jackson-databind:2.9.8'
testImplementation 'junit:junit:4.12'
}
```
Denne blokken angir hvilke biblioteker en trenger, men ikke hvor de finnes. Med `repositories`-blokken lister en opp hvor Gradle vil søke etter biblioteker (inkludert Gradle-tilleggene). De fleste vanlige bibliotek finnes i `jcenter()`, men det hender en må inkludere jar-filer (i mapper) i prosjektet. Med blokken under vil Gradle først søke etter biblioteker i `jcenter()` og deretter i mappa `libs`.
```
repositories {
jcenter()
flatDir {
dirs 'libs'
}
}
```
Formatet for identifikasjon av et bibliotek er avhengig av hvor (hva slags sted) det finnes. `jcenter()` bruker såkalte *maven-koordinater* på formatet *gruppe*:*navn*:*versjon*. Så siden `jackson`-biblioteket finnes i `jcenter()` så brukes `com.fasterxml.jackson.core:jackson-databind:2.9.8` i eksemplet over. Hvis en har et bibliotek i en lokal mappe, så brukes `name:` etterfulgt av jar-filnavnet (uten .jar).
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment