=====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/