an introduction to maven gradle and sbt
TRANSCRIPT
The Gangs of Three
Ciaociao
Vai a fare
ciao ciao
Dr. Fabio Fumarola
Maven, Gradle and SBT
Java Project related questions
• How do we create a java project?• How do we add dependencies? • How do we create a runnable jar?• How do we create a war?• How do we execute tests?
2
Contents
• Maven
• Gradle
• Sbt
3
What is Maven?
• Apache Maven is a software project management.• It is based on the concept of a Project Object Model
(POM)• Maven can mange a project’s build, reporting a
documentation form a central piece of information
But it isn’t a mere build tool
4
Maven features
• Dependency System• Multi-module builds• Consistent project structure• Consistent build model• Plugin oriented• Project generated sites
5
Advantages over Ant
• Eliminate complicate scripts• All the functionality required to build your project,
i.e., clean, compile, copy, resources, install, deploy • Cross Project Reuse – Ant has no convenient way to
reuse target across projects.
6
How Maven Works?
7
Maven keywords
• POM• Archetype• Artifact or dependency• Plugin• Goal
8
POM
• Unit of work in Maven• It is an XML file that contains the information and
the configuration details used by Maven to build the project
9
Archetype
• It is a template of a project with is combined with some user input to produce a working Maven project
• There are hundreds of archetypes to help us get started– $ mvn –version– $ mvn archetype:generate
-DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=true
– $ mvn eclipse:eclipse
10
Artifact
• An artifact is a module obtained by another artifact deployed to a maven repository
• Each artifact belongs to a group• Each group can have more artifacts
11
<dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> <version>2.6</version></dependency>
Goals and Plugins
• Are an extension of the standard maven lifecycles steps.– Clean, compile, test, package, install and deploy
• There are plugin to do other steps such as
12
<plugins> <plugin><artifactId>maven-assembly-plugin</artifactId> <version>2.5.3</version> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> [...]</plugin> </plugins>
What is Gradle?
• Gradle is a general purpose build system• It comes with a rich build description• language (DSL) based on Groovy• It supports ”build-by-convention” principle• But it is very flexible and extensible• It has built-in plug-ins for Java, Groovy, Scala, Web• Groovy as a base language allows imperative
programming in the build file.
13
Advanced features
• Parallel unit test execution• Dependency building• Incremental build support• Dynamic tasks and task rules• Gradle daemon
14
Hello, Gradle
• Create a file build.gradletask hello << {
println 'Hello World'
}
• Run $ gradle hello• Edit the file as below
task hello << {
print 'Hello '
}
task world(dependsOn: hello) << {
println 'World!"
}
• Run $ gradle –q world
15
Build scripts are code
task upper << {
String someString = 'mY_nAmE'
println "Original: " + someString
println "Upper case: " + someString.toUpperCase()
}
- $gradle upper
4.times { counter ->
task "task$counter" << {
println "I'm task number $counter"
}
}
16
Gradle is Groovy that is Java
JAVA
import java.ioFile;
…
String parentDir = new File(“test.txt”).getAbsoluteFile()
.getParentPath();
Groovy
def parentDir = new File(“test.txt”).absoluteFile.parentPath
Gradle
parentDir = file(“test.txt”).absoluteFile.parentPath
17
Building a Java project
apply plugin: ‘java’
18
Gradle support all ant task
task hello << {String greeting = "hello from Ant" ant.echo(message: greeting)
}
task list << {def path = ant.path {
fileset(dir: 'libs', includes: '*.jar') }
path.list().each { println it }
}
task zip << {
ant.zip(destfile: 'archive.zip') {
fileset(dir: 'src') { include(name: '**.xml') exclude(name: '**.java')
} } }19
Overriding conventions
Version = 1.0
Group = ‘org.mygroup’
task release(dependsOn: assemble) << {
println 'We release now'
}
build.taskGraph.whenReady { taskGraph -> if (taskGraph.hasTask(':release')) {
version = '1.0’
} else {
version = '1.0-SNAPSHOT’ }
}20
Referencing files & file collections• Groovy-like syntax:
File configFile = file('src/config.xml')
• Create a file collection from a bunch of files: FileCollection collection = files( 'src/file1.txt',
new File('src/file2.txt'), ['src/file3.txt', 'src/file4.txt'])
• Create a files collection by referencing project properties: collection = files { srcDir.listFiles() }
• Operation on collectionsdef union = collection + files('src/file4.txt')
def different = collection - files('src/file3.txt')}
21
Using file collections as input
• Use a File object to specify the source directory.compile { source = file('src/main/java') }
• Using a closure to specify the source files.compile {
source = {
file(‘src’).listFiles()
.findAll { it.name.endsWith('.zip') }
.collect { zipTree(it) }
}
}
}22
Copying files
• Using Gradle task type: task copyTask(type: Copy) {
from 'src/main/webapp‘
into 'build/explodedWar‘
include '**/*.jsp‘ exclude { details ->
details.file.name.endsWith('.html') &&
details.file.text.contains('staging')
}
}
23
Dependency management
24
Repository configuration
• Remote Reposrepositories {
mavenCentral()
mavenCentral name: 'multi-jar-repos', urls:
["http://repo.mycompany.com/jars1",
"http://repo.mycompany.com/jars1"]
}
• Local Reposrepositories {
flatDir name: 'localRepository',
dirs: 'lib' flatDir dirs: ['lib1', 'lib2']
} 25
Referencing dependencies
dependencies {
runtime files('libs/a.jar', 'libs/b.jar’)
runtime fileTree(dir: 'libs', includes: ['*.jar'])
}
dependencies {
compile 'org.springframework:spring-webmvc:3.0.0.RELEASE'
testCompile 'org.springframework:spring-test:3.0.0.RELEASE'
testCompile 'junit:junit:4.7'
}
26
Referencing dependencies
List groovy = ["org.codehaus.groovy:groovy-all:1.5.4@jar", "commons-cli:commons-cli:1.0@jar",
"org.apache.ant:ant:1.7.0@jar"]
List hibernate = ['org.hibernate:hibernate:3.0.5@jar',
'somegroup:someorg:1.0@jar']
dependencies {
runtime groovy, hibernate
}
27
Plugins
28
Extending your build
• Any Gradle script can be a plug-in:apply from: 'otherScript.gradle'
apply from: 'http://mycomp.com/otherScript.gradle’
• Use many of the standard or 3rd-party plug-ins:apply plugin: 'java'
apply plugin: 'groovy'
apply plugin: 'scala'
apply plugin: 'war'
29
Standard plugins
30
http://www.gradle.org/docs/current/userguide/standard_plugins.html
Example java and scala project
• http://www.gradle.org/docs/current/userguide/tutorial_java_projects.html• http://www.gradle.org/docs/current/userguide/scala_plugin.html
• http://plugins.gradle.org/
31
Sbt
The interactive build tool
32
Sbt
• It is a tool to define task and then run them from the shell
• To install on linux grab the– rpm: https://dl.bintray.com/sbt/rpm/sbt-0.13.7.rpm– deb: https://dl.bintray.com/sbt/rpm/sbt-0.13.7.deb
33
Starting with sbt
• It is based on the file build.sbt• Create a directory hello_scala• Edit a file and add
lazy val root = (project in file(".")).
settings(
name.:=("hello”),
version := "1.0",
scalaVersion := "2.11.4"
)
• Create an HelloWorld class
34
Project Structure
• Sbt is base on maven project structure
35
Running sbt
• It has a shell via $sbt• Or we can run task in batch– $ sbt clean compile "testOnly TestA TestB”
• It also support continuos delivery and run via– > ~compile– > ~run
36
Creating a project definition
• To create a project in the build.sbt file lazy val root = (project in file(.)).
settings(
organization := "com.example",
version := "0.1.0",
scalaVersion := "2.11.4"
)
• The build.sbt define a Project which holds a list of scala expression called settings
• Moreover a build.sbt can have vals, lazy vals and defs
37
SettingKey, TaskKey and InputKeylazy val root = (project in file(".")).
settings(
name.:=("hello")
)
•.:= is a method that takes a parameter and return s Setting[String]lazy val root = (project in file(".")).
settings(
name := 42 // will not compile
)•Does it run?
38
Types of key
• SettingKey[T]: a key for a value computed once (the value is computed when loading the project, and kept around).
• TaskKey[T]: a key for a value, called a task, that has to be recomputed each time, potentially with side effects.
• InputKey[T]: a key for a task that has command line arguments as input. Check out Input Tasks for more details.
• The built-in key are field of the object Keys (http://www.scala-sbt.org/0.13/sxr/sbt/Keys.scala.html) 39
Custom Keys
• Can be created with their:– settingKey, taskKey and inputKey
lazy val hello = taskKey[Unit](“An example task”)
• A TaskKey[T] can be used to define task such as compile or package.
40
Defining tasks and settings
• For example, to implement the hello tasklazy val hello = taskKey[Unit]("An example task”)
lazy val root = (project in file(".")).
settings(
hello := { println("Hello!") }
)
• Imports in build.sbtimport sbt._
import Process._
import Keys._
41
Adding library dependenciesval derby = "org.apache.derby" % "derby" % "10.4.1.3"
lazy val commonSettings = Seq(
organization := "com.example",
version := "0.1.0",
scalaVersion := "2.11.4"
)
lazy val root = (project in file(".")).
settings(commonSettings: _*).
settings(
name := "hello",
libraryDependencies += derby
)42
Dependencies
• To add an unmanaged dependency there is the taskunmanagedBase := baseDirectory.value / "custom_lib”
• To add an managed dependency there is the tasklibraryDependencies += groupID % artifactID % revision
• OrlibraryDependencies ++= Seq(
groupID % artifactID % revision,
groupID % otherID % otherRevision
)
43
Resolvers
• To add a resolver1. resolvers += name at location
2. resolvers += Resolver.mavenLocal
3. resolvers ++= Seq(name1 at location1, name2 at location2)
• Is it possible also to define if the dependency is for testlibraryDependencies += "org.apache.derby" % "derby" %
"10.4.1.3" % Test
44
Plugins
• To declare a plugin add a directory project/Build.sbt
45