Inhaltsverzeichnis
Ein Java JDBC Projekt mit dem Build Tool Gradle erstellen
Ziel ist es ein komplette Projekt per Script aus allen Quellen und Abhängigkeiten zusammen zu stellen.
Dazu kann das Open-Source Enterprise Build Automation Tool Gradle verwandt werden.
Gradle setzt auf groovy als Skript Sprache.
Setup der Gradle Umgebung
Die Installation besteht aus dem Download des aktuellen Builds und dem richtigen Setzen der Java Home Umgebungsvariable
- Download der letzten Release von https://gradle.org/
- Entpacken und Kopieren nach zum Beispiel „D:\entwicklung\gradle-2.6“
- Bei Bedarf einfügen einer Java Home Variable direkt am Anfang im gradle.bat Script (besser über die Umgebungsvariablen lösen!)
Prüfen:
#Java Home setzen und prüfen ob das gradle aufgerufen werden kann set-item -path env:JAVA_HOME -value 'C:\Program Files\Java\jdk1.8.0_45' & D:\entwicklung\gradle-2.6\bin\gradle.bat -v
Projekt einrichten
Verzeichnis für das Projekt anlegen und initialisieren
mkdir D:\entwicklung\work\JDBCChecker
Verzeichnis automatisch nach dem Default aufbauen/initialisieren:
cd D:\entwicklung\work\JDBCChecker #Java Home setzen set-item -path env:JAVA_HOME -value 'C:\Program Files\Java\jdk1.8.0_45' #Java Projekt anlegen & D:\entwicklung\gradle-2.6\bin\gradle.bat init --type java-library :wrapper :init BUILD SUCCESSFUL Total time: 3.208 secs #Verzeichnisstruktur und diverse Scripte werden angelegt S D:\entwicklung\work\JDBCChecker> tree ├───.gradle │ └───2.6 │ └───taskArtifacts ├───gradle │ └───wrapper └───src ├───main │ └───java └───test └───java
GUI starten und Einstellungen prüfen
& D:\entwicklung\gradle-2.6\bin\gradle.bat --gui
Mit der Gui können zum Beispiel auch einzelne Tasks ausgeführt werden, wie das anzeigen der Abhängigkeiten im Projekt:
Source Code
Source Code unter ..\src\main\java ablegen
Abhängigkeiten in Gradle hinterlegen
Im ersten Schritt die gewünschten Repositories (Section repositories) wählen wie:
- jcenter() ⇒ https://jcenter.bintray.com
- mavenCentral() ⇒ https://repo1.maven.org/maven2
- flatDir {} oder ein lokales Directory angeben
Im zweiten Schritt die Abhängigkeit deklarieren (Section dependencies)
- compile '<main Class>:<Name of Jar File>:<Version> wie zum Beispiel „compile 'oracle.jdbc.driver:ojdbc7:12.1.0.2.0'“
Datei „build.gradle“ öffnen und in unseren Fall die Abhängigkeit zu den JDBC Treibern hinterlegen:
// Apply the java plugin to add support for Java apply plugin: 'java' //Software version version = '0.1' //Information to build the jar file jar { manifest { attributes 'Implementation-Title': 'JDBC Test Utility', 'Implementation-Version': version } } // In this section you declare where to find the dependencies of your project // $rootProject.projectDir repositories { // Use 'jcenter' for resolving your dependencies. jcenter() //alternativ Maven //mavenCentral() //local Files System flatDir { //use a name you can reference this later name "JDBCDriver" dirs "D:/entwicklung/libraries/OracleJDBC12.1.0.2" dirs "D:/entwicklung/libraries/commons-cli-1.2" } } // In this section you declare the dependencies for your production dependencies { //Productive dependencies // Main Class - Name (Name of the Jar) - Version compile 'oracle.ucp.jdbc:ucp:12.1.0.2.0' compile 'oracle.jdbc.driver:ojdbc7:12.1.0.2.0' //Test Unit testCompile 'junit:junit:4.12' }
Abhängigkeiten aufzeigen:
& D:\entwicklung\gradle-2.6\bin\gradle.bat dependencies
Das Projekt erstellen
Projekt „bauen“:
& D:\entwicklung\gradle-2.6\bin\gradle.bat build
Projekt für die Auslieferung zusammenstellen
Für mein JDBCChecker Projekt sind auch einige Shell Skripte notwendig, daher ein Verzeichnis „delivery“ angelegt und dem alles so liegt wie es später ausgeliefert werden soll.
cd D:\entwicklung\work\JDBCChecker
mkdir delivery
mkdir delivery\lib
Datei „build.gradle“ öffnen und den Task für das Kopieren des Jar Files in das Library Verzeichnis definieren:
//upload the jar files to your delivery directory uploadArchives { repositories { flatDir { dirs 'delivery/lib' } //use alternativ a named location like the file repostiory over the name of the repository //add project.repositories.JDBCDriver } } //copy the dependencies task copyDeps(type: Copy) { from(configurations.runtime) into project.file('delivery/lib') } //alternativ //task copyDeps(type: Copy) { // from { configurations.runtime.files { it instanceof ExternalDependency } } // into project.file('delivery/lib') //} task copyAll(dependsOn: [uploadArchives, copyDeps])
Erzeugtes Jar Files (inkl. der Dependencies!) werden über den zusammengefassten Task „copyAll) kopiert:
& D:\entwicklung\gradle-2.6\bin\gradle.bat copyAll
Die Aufrufscripte beim Build parametrisieren
Die notwendigen Libraries sollen gleich beim Bulid in den Start Scripten hinterlegt werden.
Die Skripte liegen bei mir unter “.\src\main\bash„ und enthalten eine TAG “##LIBSTRING##„ der mit dem Classpath ersetzt werden muss.
Task für das Kopieren der Scripte und Anpassen des Klassen Pfades:
//set the classpath of the callscripts with the libraries of the project task copyAndSetClasspath { //get a list of the necessary jars to run the main class def jarList = [] //println configurations.runtime.files { it instanceof ExternalDependency } configurations.runtime.filter { it.name.endsWith ('.jar') }.each { //println it.name jarList.push(it.name) } //println jarList def String dosLibString='' jarList.each { jarName -> dosLibString=dosLibString + '%JDBC_DRIVER%\\'+jarName+';' } //println dosLibString def String bashLibString='' jarList.each { jarName -> bashLibString=bashLibString+'${JDBC_DRIVER}/'+jarName+':' } //println bashLibString //"JDBCChecker-"+version+".jar" def projectJar=rootProject.name+"-"+version+".jar" //list the directory def batchdir = new File('./src/main/bash/') batchdir.eachFile { if (it.isFile()) { if (it.name.endsWith ('.cmd')) { //copy and replace with ant ant.copy( file: it.canonicalPath , tofile: './delivery/'+ it.name) ant.replace(file: './delivery/'+it.name, token: '##LIBSTRING##' , value: dosLibString) ant.replace(file: './delivery/'+it.name, token: '##JDBCCHECKJAR##', value: projectJar) } if (it.name.endsWith ('.sh')) { //copy and replace with ant ant.copy( file: it.canonicalPath , tofile: './delivery/'+ it.name) ant.replace(file: './delivery/'+it.name, token: '##LIBSTRING##' , value: bashLibString) ant.replace(file: './delivery/'+it.name, token: '##JDBCCHECKJAR##', value: projectJar) //use groovy - not working - only for docu //boolean success = new File( './delivery/'+it.name).createNewFile() //new File( './delivery/'+it.name ).withWriter { w -> // new File( it.canonicalPath ).eachLine { line -> // w << line.replaceAll( '##LIBSTRING##', bashLibString) // } //} } } } } //add dependencies copyAndSetClasspath.mustRunAfter 'build'
Git und Gradle
Git Repository anlegen
Git Repository im Projektverzeichnis anlegen und eine https://github.com/github/gitignore/blob/master/Gradle.gitignore mit Gradle typischen Einstellungen anlegen.
git init --shared vi .gitignore .gradle build/ delivery/ # Ignore Gradle GUI config gradle-app.setting # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) !gradle-wrapper.jar #---- # Add all files git add -A git status git tag -a 1.0.0 -m "First Release of the JDBC Checker Tool" git commit -m "First Release of the JDBC Checker Tool"
Git Tag als Versionsnummer bei einem Build verwenden
Auslesen mit eigener Methode und Test Task
Einfügen in build.gradle:
/* * Gets the version name from the latest Git tag * Adjust your git Path settings before you use the code piece */ def getVersionNrFromGit = { -> println 'Info -- Start reading git over command line' def stdout = new ByteArrayOutputStream() exec { commandLine '"C:/Program Files/Git/bin/git.exe"', 'describe', '--tags' standardOutput = stdout println 'Info -- read'+standardOutput } return stdout.toString().trim() } //Test Call //task readVersion { //println 'Info -- get result ::' + getVersionNrFromGit() //} //Software version version = getVersionNrFromGit() //Information to build the jar file jar { manifest { attributes 'Implementation-Title': 'JDBC Test Utility', 'Implementation-Version': version } }
Mit diesen Aufrufen können dann mit Gradle beliebig komplexe Regeln abgebildet werden.
Git Plugins
Für die Git Versionsnr können auch diverse Plugins verwendet werden siehe https://plugins.gradle.org/search?term=git&page=1
Ab Gradle 2.1 können die Plugins sehr einfach am Kopf der build.gradle hinzugefügt werden (erste Zeile!)
plugins { id "com.cinnober.gradle.semver-git" version "2.2.2" }
Anleitung für diese Plugin siehe auch https://github.com/cinnober/semver-git
Der Versionstag muss in der Notation (nach Semantic Versioning 2.0.0 ) major.minor.patch. wie 1.0.0 vorliegen!
Nachteil! Git muss im Pfad liegen! Falls das nicht möglich ist, ist das dann ein Problem .-( .
set-item -path env:PATH -value "$env:PATH;C:\Program Files\Git\bin\" echo $env:PATH & D:\entwicklung\gradle-2.6\bin\gradle.bat clean build --info