=====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 [[https://gradle.org/|Gradle]] verwandt werden.
Gradle setzt auf [[http://www.groovy-lang.org/|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:
{{ :prog:gradle_gui_example_v01.png?300 |Gradle Gui - Execute a task}}
=== 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 ':: 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 [[ http://semver.org/spec/v2.0.0.html|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
===Siehe auch===
* http://kapitel26.github.io/git/2014/05/20/git-und-gradle/
* http://ryanharter.com/blog/2013/07/30/automatic-versioning-with-git-and-gradle/
----
==== Quellen ====
Web
* https://docs.gradle.org/current/userguide/tutorial_java_projects.html
* http://technicles.com/create-oracle-database-jdbc-connection-in-gradle/
Video
* https://www.youtube.com/watch?v=G4EAd514jdE&list=PLLRn4-MiSxSnAta4igywDVoiZnrkwtLvA
Groovy Einführung
* https://gradle.org/groovy-for-gradle-users/