I tried my best to hack together something that would preserve the formatting of my notes. The end result was sub-par. @0:00 to 3:25: Gradle is hyper customizable. @3:25 to @5:52 : Declarative / Imperative ----@3:25 to @4:12: Ant is imperative: ----@4:12 to @5:07: Maven is declarative. ----@5:08 If gradle has an oppinion it is ---- ---- "declarative is where you should be" ----@5:40: The problem of: ---- ---- "too much of a declarative approach" ---- ---- @5:52 to @7:40 : Conventions / Adaptability @7:45 : Tasks (Like ant targets) @8:28 : Begins writing build.gradle -----@9:35 : BASH> gradle ----- ----- (Runs helloWorld task?) -----@10:00: BASH> gradle tasks -----@10:20: Configuring helloWorld task ----- ----- @10:30: "Closure Syntax" ----- ----- @10:50: A task has an API ----- ----- @11:10: doLast -----@11:30: BASH> gradle helloWorld ----- ----- (running a gradle task) -----@12:25: MULTIPLE tasks with DEPENDENCIES ----- -----@12:50: BASH> gradle hello ----- -----@13:00: BASH> gradle world ----- -----@13:02: gradle -q world ----- -----(Suppress lifecycle messages) ----- ----- ----- -----@13:30: world dependsOn hello ----- -----CODE: dependsOn gradle -q world ----- ----- ----- -----@14:00: helloWorld: ----- -----task helloWorld{ ----- ----- dependsOn = [ world, hello ] ----- -----} ----- ----- ----- -----@14:10: BASH> gradle helloWorld ----- -----@14:30: CamelCase Shorthand: ----- -----BASH> gradle -q hW ----- -----(hW == helloWorld) ----- ----- ----- -----@15:20: Once again, ----- -----"A task is an object" ----- @15:50: Gradle Build Language Reference ----@16:00: DSL (Domain Specific Language) ----@16:55: doLast( action ) @17:50: build.gradle continued. ----@17:50: // IMPERATIVE!!!! ----@18:25: Imperative --> Declarative refactor ---- ----- @18:40: plugins @19:20: Questions and answers intermission. ---- @19:50: Dependency Graph (DAG) ---- ------: (DAG==Directed Acyclic Graph) ---- ------: All that means is look at the ---- ------: tree of dependencies and ---- ------: turn everything that needs to ---- ------: be done into a linear list ---- ------: of tasks. ---- @21:20: dependsOn = [ .... ] ---- ------: VS ---- ------: dependsOn gradle ceasar ---- @32:05: BASH> gradle caesar ---- @35:25: Arbitrary java code change. ---- @35:45: "UP-TO-DATE" @37:05: Question Intermission (Again) @37:55: Adding "encode" method to java program. /****/ public String encode( String text ){ /****//***/ Base64 codec = new Base64(); /****//***/ return new String( codec.encode(text.getBytes())); /****/ } @38:24: import org.apache.commons.codec.binary.Base64 @38:50: "That class is NOT in our classpath. How do we get it there?" @38:54: "Gradle is compatbile with Maven style repositories." ------- dependencies{ ------- /**/ compile 'commons-codec:commons-codec:1.6' ------- } @39:50: ------- repositories{ ------- /**/ mavenCentral(); ------- } ------- @40:45: Fixing Java Code: (But this fix was WRONG) ------- public static void main( String[] args){ ------- /**/ Poetry p = new Poetry(); ------- /**/ p.emit( p.encode(p.juliusCaesar() )); ------- } ------- @41:00: ------- public void emit( List lines){ ------- /**/ for( String line : lines ){ ------- /**/ //: System.out.println( p.encode(line)); ------- /**/ System.out.println( p.encode(line)); //:@41:12 ------- /**/ } ------- } @41:20: BASH> gradle caesar @42:25: "Transitive Dependencies" @43:00: println configurations.compile.asPath @44:05: How "runtimeClasspath" is populated. @46:10: "Where is mavenCentral() defined?" Answer: As part of the gradle DSL. @46:33: mavenRepo url: [ ... ] @48:55: "Activity is organized into tasks" @46:33 to 50:20: Review + rant on maven lifecycle tasks.
@50:25: BASH> cd ../multiproject @50:40: BASH> tree @51:50: PoetryEmitter.java @52:00: Sub Project: Poetry.java @52:15: Sub Project: Codec.java @52:30: build.gradle for multi-project build. (I think this is the 3rd build.gradle seen in tutorial) allprojects { /**/ apply plugin: 'java' /**/ /**/ repositories { /**//**/ mavenCentral(); /**/ } } dependencies{ /**/ compile project(':codec'); /**/ compile project(':content'); } project(':content') { /**/ dependencies { /**//**/ testCompile 'junit:junit:4.9' /**/ } } project(':codec') { /**/ dependencies { /**//**/compile 'commons-codec:commons-codec:1.6' /**/ } } task wrapper( type: Wrapper ) { /**/ gradleVersion = '1.0' } task poetry(type: JavaExec ){ ........... } @53:45: ONLY ONE TOP LEVEL BUILD. No "sub" build.gradle files. @55:00: "Radically Unified Build" ------- "Radically UN-Unified Build" @55:32: BASH> gradle poetry @56:03: "I see there are a few questions here" @56:20: Plugin to allow you to import dependencies from a Maven POM.xml file. @56:40: JAVA_HOME for gradle java plugin? ------ @56:50: Gradle documentation --> task types --> javaExec ------ ------: Then look at configuration parameters. ------ ------: (My experience is gradle will prioritize JAVA_HOME over ) ------ ------: (PATH variable if BOTH exist. If both exist but JAVA_HOME is ) ------ ------: (pointing to an invalid path, you get a build failure. ) ------ ------: JAVA_HOME | PATH -| ------ ------: | -YES--- | -YES -| ===> Uses JAVA_HOME ------ ------: | - NO--- | -YES -| ===> Uses PATH ------ ------: | -YES--- | - NO -| ===> Uses JAVA_HOME ------ ------: | INVALID | -YES -| ===> BUILD FAILS ------ ------: | INVALID | - NO -| ===> BUILD FAILS ------ ------: | -YES--- |INVALID| ===> Uses JAVA_HOME, build success ------ ------: | - NO--- |INVALID| ===> Uses PATH, build FAILS. @57:15: "Does the subproject name in the gradle build file depend" ------: "on the subdirectory name?" ------: Short Answer: YES
Very nice tutorial, thanks Mr. Berglund! Just a small precision, as of 3/18/2018 I had to write *sourceSets.main.runtimeClasspath* instead of *runtimeClasspath* . I don't know if we can change this behavior but it looks like in newer versions of gradle we have to explicitly specify the source set where we wish to access the properties, or else it will think *runtimeClasspath* is one property of the JavaExec type task. Hope it helps other people as I was confused myself watching this 2014 video. Cheers
Excellent intro on Gradle! I am very new to this kind of thing and this is spot on. Now I know what build tools are and what are they used for. I am on my way now to read on the official resources. Thank you!
Thanks for that, great intro, in multiproject, had to change line 34 to: classpath = sourceSets.main.runtimeClasspath or it did;nt work, (using gradle 2.3)
I got the "Could not find property 'runtimeClasspath' on task ':caesar'" error and had to re-format my code to apply plugin: 'java' task(ceasar, type: JavaExec) { main = 'org.gradle.test.Test' classpath = sourceSets.main.runtimeClasspath } I have Gradle 2.9.
One thing I would like as part of any opening on a new tool is the statement of what the product is... Don't start taking about how to use it... just say... Gradle it lets you automatically feed your cat. Now here why it used and now here's how to use it.
Kobe Wild no, I'm glad he talked about how we use it. Because this showcases the actual practical use of the software rather than talk useless shit about it and call it a "sales pitch"
The short answer is: include "codec", "content" This is the documentation link, if you want to read more: docs.gradle.org/current/userguide/tutorial_java_projects.html#sec:defining_a_multiproject_build My project could not build without this one liner in the file - Gradle was complaining that it could find project :codec.
.Which of the following are benefts of using Gradle over Maven? Select ALL answers that apply A. Gradle supports more languages than Maven. (not really sure, maven supports a lot of languages too) B. Gradle incorporates Maven features as well as additional functionality. C. Gradle builds are sucessful more often than Maven builds. D. A Gradle build is 1000 times faster than a Maven build. (Gradle is faster, but not 1000 times faster I don’t think. )
I don't expect to receive an answer here, but still. If task 'world' depends on taks 'hello' and task 'helloWorld' depends on [world, hello] why is output not "hello, worldhello, "? helloWorld would first run world which depends on hello, so we get "hello, world", then helloWolrd would execute hello, which would add another "hello, ". What am i missing?
annoying.sniper If task A depends on task B, it means that B must run before A starts running (A requires B to have run first). So when he wants to run "helloworld", the tasks "hello" and "world" must run before "helloworld" itself, since it depends on those two.
This lecture should be considered poetry. Beautiful !
Very good introduction to Gradle! Thanks for this!
Awesome intro, this is how things shall be explained...
I tried my best to hack together something that would preserve the formatting of my notes.
The end result was sub-par.
@0:00 to 3:25: Gradle is hyper customizable.
@3:25 to @5:52 : Declarative / Imperative
----@3:25 to @4:12: Ant is imperative:
----@4:12 to @5:07: Maven is declarative.
----@5:08 If gradle has an oppinion it is
---- ---- "declarative is where you should be"
----@5:40: The problem of:
---- ---- "too much of a declarative approach"
---- ----
@5:52 to @7:40 : Conventions / Adaptability
@7:45 : Tasks (Like ant targets)
@8:28 : Begins writing build.gradle
-----@9:35 : BASH> gradle
----- ----- (Runs helloWorld task?)
-----@10:00: BASH> gradle tasks
-----@10:20: Configuring helloWorld task
----- ----- @10:30: "Closure Syntax"
----- ----- @10:50: A task has an API
----- ----- @11:10: doLast
-----@11:30: BASH> gradle helloWorld
----- ----- (running a gradle task)
-----@12:25: MULTIPLE tasks with DEPENDENCIES
----- -----@12:50: BASH> gradle hello
----- -----@13:00: BASH> gradle world
----- -----@13:02: gradle -q world
----- -----(Suppress lifecycle messages)
----- -----
----- -----@13:30: world dependsOn hello
----- -----CODE: dependsOn gradle -q world
----- -----
----- -----@14:00: helloWorld:
----- -----task helloWorld{
----- ----- dependsOn = [ world, hello ]
----- -----}
----- -----
----- -----@14:10: BASH> gradle helloWorld
----- -----@14:30: CamelCase Shorthand:
----- -----BASH> gradle -q hW
----- -----(hW == helloWorld)
----- -----
----- -----@15:20: Once again,
----- -----"A task is an object"
-----
@15:50: Gradle Build Language Reference
----@16:00: DSL (Domain Specific Language)
----@16:55: doLast( action )
@17:50: build.gradle continued.
----@17:50: // IMPERATIVE!!!!
----@18:25: Imperative --> Declarative refactor
---- ----- @18:40: plugins
@19:20: Questions and answers intermission.
---- @19:50: Dependency Graph (DAG)
---- ------: (DAG==Directed Acyclic Graph)
---- ------: All that means is look at the
---- ------: tree of dependencies and
---- ------: turn everything that needs to
---- ------: be done into a linear list
---- ------: of tasks.
---- @21:20: dependsOn = [ .... ]
---- ------: VS
---- ------: dependsOn gradle ceasar
---- @32:05: BASH> gradle caesar
---- @35:25: Arbitrary java code change.
---- @35:45: "UP-TO-DATE"
@37:05: Question Intermission (Again)
@37:55: Adding "encode" method to java program.
/****/ public String encode( String text ){
/****//***/ Base64 codec = new Base64();
/****//***/ return new String( codec.encode(text.getBytes()));
/****/ }
@38:24: import org.apache.commons.codec.binary.Base64
@38:50: "That class is NOT in our classpath. How do we get it there?"
@38:54: "Gradle is compatbile with Maven style repositories."
------- dependencies{
------- /**/ compile 'commons-codec:commons-codec:1.6'
------- }
@39:50:
------- repositories{
------- /**/ mavenCentral();
------- }
-------
@40:45: Fixing Java Code: (But this fix was WRONG)
------- public static void main( String[] args){
------- /**/ Poetry p = new Poetry();
------- /**/ p.emit( p.encode(p.juliusCaesar() ));
------- }
-------
@41:00:
------- public void emit( List lines){
------- /**/ for( String line : lines ){
------- /**/ //: System.out.println( p.encode(line));
------- /**/ System.out.println( p.encode(line)); //:@41:12
------- /**/ }
------- }
@41:20: BASH> gradle caesar
@42:25: "Transitive Dependencies"
@43:00: println configurations.compile.asPath
@44:05: How "runtimeClasspath" is populated.
@46:10: "Where is mavenCentral() defined?"
Answer: As part of the gradle DSL.
@46:33: mavenRepo url: [ ... ]
@48:55: "Activity is organized into tasks"
@46:33 to 50:20: Review + rant on maven lifecycle tasks.
@50:25: BASH> cd ../multiproject
@50:40: BASH> tree
@51:50: PoetryEmitter.java
@52:00: Sub Project: Poetry.java
@52:15: Sub Project: Codec.java
@52:30: build.gradle for multi-project build.
(I think this is the 3rd build.gradle seen in tutorial)
allprojects {
/**/ apply plugin: 'java'
/**/
/**/ repositories {
/**//**/ mavenCentral();
/**/ }
}
dependencies{
/**/ compile project(':codec');
/**/ compile project(':content');
}
project(':content') {
/**/ dependencies {
/**//**/ testCompile 'junit:junit:4.9'
/**/ }
}
project(':codec') {
/**/ dependencies {
/**//**/compile 'commons-codec:commons-codec:1.6'
/**/ }
}
task wrapper( type: Wrapper ) {
/**/ gradleVersion = '1.0'
}
task poetry(type: JavaExec ){ ........... }
@53:45: ONLY ONE TOP LEVEL BUILD. No "sub" build.gradle files.
@55:00: "Radically Unified Build"
------- "Radically UN-Unified Build"
@55:32: BASH> gradle poetry
@56:03: "I see there are a few questions here"
@56:20: Plugin to allow you to import dependencies from a Maven POM.xml file.
@56:40: JAVA_HOME for gradle java plugin?
------ @56:50: Gradle documentation --> task types --> javaExec
------ ------: Then look at configuration parameters.
------ ------: (My experience is gradle will prioritize JAVA_HOME over )
------ ------: (PATH variable if BOTH exist. If both exist but JAVA_HOME is )
------ ------: (pointing to an invalid path, you get a build failure. )
------ ------: JAVA_HOME | PATH -|
------ ------: | -YES--- | -YES -| ===> Uses JAVA_HOME
------ ------: | - NO--- | -YES -| ===> Uses PATH
------ ------: | -YES--- | - NO -| ===> Uses JAVA_HOME
------ ------: | INVALID | -YES -| ===> BUILD FAILS
------ ------: | INVALID | - NO -| ===> BUILD FAILS
------ ------: | -YES--- |INVALID| ===> Uses JAVA_HOME, build success
------ ------: | - NO--- |INVALID| ===> Uses PATH, build FAILS.
@57:15: "Does the subproject name in the gradle build file depend"
------: "on the subdirectory name?"
------: Short Answer: YES
Thank you for not using any of the tools and sticking to CLI and Text Mate, it removed all the fluff and fancy stuff and explained gradle as it is.
Thank you very much for this Tim. It helped me a lot to understand the role of gradle in Android Development!
Thanks for this comment, just given the reason why I should invest my time in this. Exactly matches my agenda.
Thank you so much, 7:58 where the great deal begins :)
Very nice tutorial, thanks Mr. Berglund! Just a small precision, as of 3/18/2018 I had to write *sourceSets.main.runtimeClasspath* instead of *runtimeClasspath* . I don't know if we can change this behavior but it looks like in newer versions of gradle we have to explicitly specify the source set where we wish to access the properties, or else it will think *runtimeClasspath* is one property of the JavaExec type task. Hope it helps other people as I was confused myself watching this 2014 video. Cheers
Excellent intro on Gradle! I am very new to this kind of thing and this is spot on. Now I know what build tools are and what are they used for. I am on my way now to read on the official resources. Thank you!
Thanks for this, I actually understand what Gradle is all about now!
Awesome intro to gradle, very clear 👏
Just a great webinar ! Thank you
My eyes are open... please post an updated one at least 4 hours long!
Haha, we're working on one that's 5 hours long for yah
Great Introduction !!! usefull one. Thank you!
Thanks for that, great intro, in multiproject, had to change line 34 to:
classpath = sourceSets.main.runtimeClasspath or it did;nt work, (using gradle 2.3)
Thanks, I needed that fix. (using gradle 3.3)
I got the "Could not find property 'runtimeClasspath' on task ':caesar'" error and had to re-format my code to
apply plugin: 'java'
task(ceasar, type: JavaExec) {
main = 'org.gradle.test.Test'
classpath = sourceSets.main.runtimeClasspath
}
I have Gradle 2.9.
Thanks Shane, i had the same problem and it works now
Thank you so much Shane. Finally solved this problem.
great explanation! thank you
I get to know how Gradle works now. Thanks!
What's the difference between using dependsOn
This was brilliant, thanks a lot!
Is there anyway to use an IDE with Gradle? instead of writing on text editor? this will take forever to write the code :(
+NeverMore IntelliJ IDEA works with Gradle very well
it's right in the startup menu of Intellij
Please share the slides.
that was really helpful
very good example and great explaination!
One thing I would like as part of any opening on a new tool is the statement of what the product is... Don't start taking about how to use it... just say... Gradle it lets you automatically feed your cat. Now here why it used and now here's how to use it.
Kobe Wild no, I'm glad he talked about how we use it. Because this showcases the actual practical use of the software rather than talk useless shit about it and call it a "sales pitch"
Is this course still valid for the latest versions of the gradle?
The good ol "You're muted" troll. Classic
Really good intro, enjoyed it.
Gradle for developers should have the following 1. How to debug gradle 2. List of all steps in a gradle task
What's the difference between `print` and `println`? I didn't find the references in Groovy language.
'println' (print line) probably appends a newline character at the end of the string
This Looks Very Cool!!!
where do i get that doc u mentioned over there
Hi, are you talking about this doc? docs.gradle.org/current/userguide/userguide.html
This is good!!
Great Introduction , I have one question , what is the use of settings.gradle file ?
The short answer is:
include "codec", "content"
This is the documentation link, if you want to read more: docs.gradle.org/current/userguide/tutorial_java_projects.html#sec:defining_a_multiproject_build
My project could not build without this one liner in the file - Gradle was complaining that it could find project :codec.
This speaker’s voice is like the person who explains about Kafka in confluent.
great introduction, thank you.
man gradle seems awesome
Great tutorial
are the information on this tutorial still valid ?
The information is from 2013, you can sign up for the Gradle Training course here - gradle.com/training/introduction-to-gradle/?time=1616457600
Fantastic!!
8:00
very good, very clear!
very usefull ,thanks!
brilliant and enlightment
He sounds so much like Sal Khan.
.Which of the following are benefts of using Gradle over Maven?
Select ALL answers that apply
A. Gradle supports more languages than Maven. (not really sure, maven supports a lot of languages too)
B. Gradle incorporates Maven features as well as additional functionality.
C. Gradle builds are sucessful more often than Maven builds.
D. A Gradle build is 1000 times faster than a Maven build. (Gradle is faster, but not 1000 times faster I don’t think. )
I don't expect to receive an answer here, but still.
If task 'world' depends on taks 'hello' and task 'helloWorld' depends on [world, hello] why is output not "hello, worldhello, "?
helloWorld would first run world which depends on hello, so we get "hello, world", then helloWolrd would execute hello, which would add another "hello, ".
What am i missing?
+annoying.sniper nvm, someone actually asked that question and he answered :)
I was wondering where is the answer. Found at 19:05. Thank you!
annoying.sniper If task A depends on task B, it means that B must run before A starts running (A requires B to have run first). So when he wants to run "helloworld", the tasks "hello" and "world" must run before "helloworld" itself, since it depends on those two.
thank you
Hi. I fuckn hate Gradle. Jesus christ it's such a pain in my ass. The number of wasted hours is second only NullPointerExceptions for Android devs