A Gentle Introduction to Gradle

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello and welcome to a gentle introduction to Gradle I'm Timberland trainer author and speaker on Gradle and other topics if you're watching this I'm assuming that you're interested in learning what Gradle is all about maybe you know a little something about it you probably know something about the build ecosystem that already exists in the Java landscape including popular tools like ant and Mayman now I'm going to spend most of our time talking about Gradle itself but there's a question I always like to answer up front namely why would we introduce another build tool well there are a few reasons for this number one has to do with some of the tensions that the community has been feeling with the existing solutions they're very good at what they're designed for and each of them those being ant and mavin have introduced key innovations into the build space but as we move forward from perhaps where builds were a decade ago to where we see builds going in the next five to ten years there's a few pressures number one is the pressure for customization builds in the end print and enterprise context don't tend to look that much like one another there's a very simple if you think of the simple sort of java template for a build which is a project I'm going to live code in front of you we'll build a really simple Java project today it's really easy to get that work done but when you expand from that simple self-contained Java project to a profoundly multi module build that spans lots of different teams and technologies that tends to be a fairly custom thing and actual code gets written as a part of that build the build isn't sort of a quick and dirty little activity that helps us get on to the business of serious software development but it's its own domain of software development by itself and that becomes clear nowhere clearer than in the enterprise where there's lots and lots of custom work done on builds and that's really the state of affairs right now as we look into the future from complex Enterprise builds today to complex automated deployment pipelines tomorrow and this is something that some people in the enterprise experimenting with right now the idea of continuous deployment and software where there isn't just a build server that builds the code and runs the tests but perhaps when the tests pass does some kind of automated deployment to actual production hardware that your business relies on when we look to that world the future world of increased deployment automation again you have even more demands on the build tool and an environment really that is hyper customized so I have to show you throughout the course this webinar how Gradle delivers on the need to build simple things in an easy way but also gives you a path gives developers on your team a path to build custom build standards that can be anything any sort of deployment environment or automation pipeline that you can think of those can be made into Gradle customizations that users of the build can think about an express in a very simple way again there's always this tension between the declarative and the imperative and this is something what we're going to see in the demos that we get to in a few minutes come out in a few different ways it's easy to look again at the the legacy Java world build pools of ant and maven to express the difference between a declarative build and an imperative build a typical ant build which I'm sure a lot of you have seen and are used to is a very imperative thing to express build activity in ant you script a series of tasks you describe in an imperative way what the build should be doing in a step by step by step fashion by contrast in a maven build that's a very declarative thing and this is one of the great innovations that maven brought to the world after ant had achieved some popularity which is that we didn't have to necessarily describe in this step by step by step way that could become very pedantic in a large build you might have thousands of lines of XML in this big ant build file saying over and over again things that that you might wish to be able to express in a simpler way they even said well you know really what we ought to do is just kind of configure the parameters of a build and have the machinery the actual building activity all that imperative stuff be going on underneath inside the engine things maven is doing or maven plugins are doing and inside the maven pom file will simply declare kind of parameters about the build and have those be interpreted by the engine so there's this tension between the idea of an imperative build and a declarative build and if Gradle as a technology has an opinion it really is that declarative is where you should be a good build is a declarative build that's always our goal we don't want to see lots and lots of code in a build file or certainly not lots of lots of XML you know that's not that's not a readable thing and a great deal of code inside a build file can be difficult to maintain difficult for tooling to access it and difficult to test and there's all kinds of dangers there putting lots of imperative code in your build so we definitely like the declarative approach but the problem with too much of the declarative approach is that now there's a tension between the conventions that our declarative build system will afford US and the adaptability of the build and I hope to show you this again as we as we get into the demos Gradle wants your builds to be declarative it thinks you know really that that was the right way to go but if a build has to be declarative all the time and there are a few opportunities to customize the kinds of things we declare then that implies that the build tool is going to have to have a strong set of opinions about what the conventions of a build ought to be in other words the tool is going to have some kind of abstraction that exposes it exposes to you saying here's what all builds ought to look like and we'll just let you configure some parameters about how those builds run and that works up to a point but typically as build become more elaborate and more complex in enterprise environment as software grows and as the needs of the deployment pipeline grow the tool has a hard time keeping up with the development in the build and the complexity of the build so while we like this idea of conventions and simple and declarative builds we also want to make the tool adaptable and we want to give your software development teams or you as a developer the ability to extend that tool and build your own brand new conventions see Gradle doesn't think that it can imagine all of the build conventions that ought to exist ever it can imagine a good base set of build conventions which it gives you and from that point on it gives you a toolkit to develop your own conventions and your own language to be able to describe them and with that it would be good if we could have a look at some actual Gradle builds the fundamental unit of build activity in Gradle is a thing called a task if you're familiar with ant this is a lot like an ant target but it turns out to be a much much richer idea so I'm going to go ahead and break into some actual Gradle code here and I'm going to rely on you in the questions or in the chat to let me know if you need a font size increase or anything like that I'm going to assume that everything is in good shape but let me go ahead and build create a Gradle build I'm going to be doing this as a text file no tooling yet we'll see if we can introduce maybe eclipse or IntelliJ IDEA a little bit later but right now we're just going to be playing with some basic tasks in a very simple Gradle build file now the most simple Gradle build I could possibly think of would look like that now of course that bill doesn't do anything but what that does is that declares a thing called a task and task being the basic unit of build activity in Gradle is also an object and that's an important lesson for us to take a look at here I'm going to since we're in code and we're not in slides anymore I'm just going to make a comment up here that will be able to take some notes in for any any lesson as we learn here and the first lesson is that a task is an object which means that a Gradle build is program now let me go ahead and run this build it's not going to do a whole bunch that delay is fault that delay is actually an external hard drive on the presenters computer that kicked on and a kernel level driver there that causes that delay so you're not going to see that start up the way again our apologies for that so here we are I've run Gradle and let me ask Gradle to tell us what sort of tasks we have in that build I can always ask us Gradle what I can I can ask it great what tasks are there and you see right here I've created a task called hello world so that's a valid Gradle build that does something that declares this object but now we have to configure this object and give it something to do because by default a Gradle task of course doesn't have any work to do now to configure a task we use this syntax right here I'm going to pass it this block between curly braces groovy programmers will recognize that as a closure the closure syntax if you're not a groovy programmer you don't have to be you can just kind of learn this syntax as I go along as a part of configuring a task I have a rich task API to access because remember a task is an object up here and this is going to remind us that a task has an API in that API there's a method I have called do last I can call that do last method on this task object and give the task some work to do a task being an object also has inside it a list of activities let's just remember that lesson right here a task has a list of activities all right and I'm going to give it something to do and that something is simply going to be to print out the message helloworld I'll go ahead and run Gradle again but this time I'm going to tell Gradle that I want to run the task hello world see how much faster that startup is look at that alright so there we are I've printed out the hello world message and I think everybody will agree that's totally worth the price of admission we had a build tool say hello world all right maybe you're looking for a little bit more than that let me give you a few more ideas in the basics of kind of build syntax and this task API so you know the fundamentals and then I can begin to introduce some things like how to build Java code how to build do multi project builds how to run tests interesting things like that all right so I've declared a task I've configured the task with stuff to do now in the real world we usually have more than one task we usually have multiple tasks with dependencies so let me just refactor this build a little bit I'm going to have a task called hello that does that and this task I am going to have it's going to be called world and it's going to print the message world so there we go I think you kind of get the idea that I can run hello and I can run world and I'm going to start doing - Q which is going to since all our bills are just printing messages out I'm going to have Gradle suppress those lifecycle messages like this thing here and this build successful which you know we all appreciate the affirmation of a successful build but since we're just printing things right now I'm going to do dash Q that's going to get that stuff out of our hair all right so great we have those two what I would also like to do though is Express a dependency before world runs it is going to need to have the hello tasks run so I could express a task dependency like that so now when I run world you I get the helloworld task running the hello task running first and then the world task running next I could continue this I could say here's a task called hello world and it depends on a slightly different way of expressing this world and hello now I can go to Gradle I can run hello world I'll clear the screen again and I forgot my dash cube but I get those two tasks to run in the order that I need I'll give you another nice little bit of Gradle short shorthand syntax here any time I have a task name that's expressed in camel case like hello world where the first letter is lowercase but words are delimited by uppercase I can abbreviate the task name like that that's a nice little bit of command-line syntax sugar for you sometimes I'll come up with plugins or custom tasks that have really long names like you know generate change log or change log sync or something like that for some automated database deployment pipeline and I'd much rather type something like GC W or CLS or something like that's a really nice little shortcut to have in mind alright so that's the basics of the tasks API and where might I go to learn more about that because I told you a task as an object and therefore that object has an API and if I could assume I don't know all of your technical backgrounds but if I'll assume for a minute that you basically come from the Java world broadly speaking and have a little bit of familiarity in that world if you're giving Gradle either if you are a Java developer or if you're giving this to a team of Java developers to use well there's great news for them and that is that all of this API this whole idea of a task being an object and having methods and properties and all these things is documented in the default Gradle installation we have the Gradle build language reference or what's sometimes called the da sell the domain-specific language reference we can scroll down here if you look off to the left you'll see core types and here is tasks and we can click on tasks and I can read about the nature and purpose of that task object here are a few examples of how to create and configure tasks like we've seen I can scroll down there's a nice narrative giving you a good introduction to all the basics and then we see a list of properties see here's depends on you notice I used that property I added things to that collection and I initialized it to be a list of dependencies I can continue to scroll down a rich rich API there's a day of detailed training at least in learning all this stuff and here we have the task methods so the details of this API are exposed to you notice do last that's the method that I was calling just to have our hello and world tasks print stuff so those things aren't magical you don't just have to know them they're fully documented here in this great collection of documentation that comes with every Gradle download so please if you're developer if you're giving this to developers to use make sure they feel comfortable digging around in this stuff I'll come back to this theme of this programming documentation existing and how we can dig into this documentation and sort of the appropriate way to think about the layers of abstraction in Gradle and this frankly is a fairly low level of abstraction right I'm saying explicitly I've got these tasks and they have this imperative this is the imperative build mode here and I said before cradles preference is to be declarative so this really looks like to me if I were to back up a step and think about this I would say this looks conceptually like an ant build that I get to express in a slightly more friendly syntax there are no angle brackets unless I want there to be angle brackets somewhere it looks a little bit like Java this actually think Lee is a groovy based domain-specific language but it's still imperative and we said before we don't like imperative so we can do about moving towards a more declarative style in building some Java code now before I make that transition and begin the discussion of plugins I'm going to pause for just a minute and give everybody a chance to throw some questions at me either in the chat or the formal questions interface and I'll address those questions live before we move on to the discussion of the Java plugin you you we have a guest shamone that pointed out that hello world depended on world and hello world depended on hello but Gradle was smart enough only to run world once and that's right I'll point out because what's happening is before Gradle actually runs the build and in this case running the build refers to executing this line and this line the two print statements that's what this build is so to execute this build means to print hello and to print world but before it can execute the build it has to figure out what the build is made up out of it has to build a graph of these tasks and there's another great lesson for us to learn in this task module which is that tasks form a directed acyclic graph so before q ssin of the build it builds a graph of the tasks and their dependencies it's directed of course because one task hello world depends on other tasks this does not express that hello depends on hello world but hello world depends on hello and world in turn depends on hello and so forth so it's directed it's a cyclic in that you can't have one task a depending on B and B depending on a if you try that Gradle will slap you gently on the risk wrist and fail the build if there's a cycle in the dependencies there's no way to calculate what you should do first and so that graph has to be a cyclic but this graph of tasks is being built up during kind of an initialization phase of Gradle x' technically it's called the configuration phase and I may emphasize that again in a little bit during this configuration phase Gradle is reading the build file building the graph once the graph is built it can come back to this command line that says ah we have asked for hello world to be run now I can go into my graph compute the dependencies execute them and actually run the build alright another person pointed out the difference in syntax between this depends on a left shift and depends on equals and you're absolutely right I did that completely intentionally that's two ways of expressing the same thing if you were to read in the DSL documentation you'd see that depends on is a collection so a task can depend on many other tasks which makes a lot of sense now Gradle the build file syntax that I'm using here is actually an elaboration of the groovy language it's a domain-specific extension of groovy so inside this if you're a groovy programmer if you know any any groovy I can actually write groovy code hey glad you're learning about Gradle today this is a Gradle method definition now this is a perfectly pragmatic way to kind of sketch things and make little extensions and and begin to think of your build as a little piece of code that you're writing ultimately you probably don't want a lot of this directly in a Gradle build by the time the build is production-ready that would be sort of like having an all imperative build but it's important to know and keep in mind that this is Gradle code that you're writing so you can do this kind of thing so this is one partly this is groovy code this is one groovy syntax for adding an object to a collection up here on line 14 this is syntax for creating a list and assigning it to the collection so this isn't adding to the dependencies this is saying hello world your dependencies are these two things and the thing in square brackets is the groovy syntax for declaring a list so you're right I use those two syntaxes those are available to me because this is a groovy DSL all other groovy syntax is available to you which gives you tremendous power and flexibility of making a very expressive and readable build also of course some danger that instead of filling up a build file two thousand lines of unreadable XML you'll fill it up with two thousand lines of readable but untested groovy and through the plug-in API of Gradle whereby you can write your own custom plugins that's kind of how you save yourself from that overly scripted untested and difficult to read build file we want to keep the build file small declarative and expressing our build in terms of our own language a question from Mattias could I write depends on world hello the short answer is no no that wouldn't work so these two ways I've written are good ways to do it a question from Antonia is there a way to get rid of the initial startup penalty again the startup that you unfortunately saw the first time I ran Gradle was completely an artifact of the presenters computer there's an external backup drive that I have that sometimes when it spins up it makes this five second kind of kernel level lock on everything so that's completely my fault for not disconnecting that before the talk I don't want you to think that that's a part of the Gradle startup on so the Gradle startup time that you should expect to see looks like this that's JVM and groovy startup time and it's pretty pretty really pretty nice at this point Gradle 1.0 has a feature in it called enabled by default called the daemon which keeps kind of a live warm started JVM in memory ready to go if I were to run Gradle for some reason with the no daemon option you see a longer startup time but I'm not going to do that so again that that first startup time pay attention every time I run Gradle you're not going to see it be that long at all isn't to the Jeff asks isn't the use of depends on discouraged short answer Jeff no it's fine to document your dependencies in that way and there we go so with no more questions I'm going to move on to plugins very good you now there's another great set of documentation and that's the Gradle user guide user's guide that comes with Gradle and currently in its chapter 22 it defines the list of standard Gradle plugins and those are plugins that come with Gradle you've already got them you don't have to do very much to to apply them to your build it's a single line of code and there's a whole ecosystem of other plugins contributed by open-source authors by commercial product vendors inside your own enterprises you're building out your build framework based on Gradle you are certainly going to create plugins of your own that are going to be distributed internally we'll be looking at the standard plugins and particularly the Java plug-in this is going to help us build some Java code in a very simple way now there are some other language plugins right now C++ is currently considered experimental very soon that won't be experimental anymore there are plugins for integrating with eclipse with IntelliJ IDEA for running findbugs for running check style if you have groovy code you can run the code nark quality checker lots and lots of built-in plugins here we're going to concentrate a pop on the java plug-in and let me give you an idea how this works to do that let's create a little bit of Java code get up out of this directory and we'll go into a blank directory and make a little Java project I'm going to do this very quickly source main Java org Gradle poetry and we'll call this poetry Java it's going to be a single file one line Java code of course yeah got a little excited there I didn't want to make a directory called that I just wanted to make a directory called that and then will open up in here and make this Java program so here we are I will say we are in the org Gradle poetry package is that right yes or Gradle poetry we can consider this a 100 person group pair programming programming exercise so if you see me make any mistakes just just throw a comment in the question so we'll make a class poetry and it'll have a public static void main method and it'll have si will make another method called void no public list Caesar very good and we'll make a list of strings here so very interesting little Java program in fact to make this easier I'm going to grab this little Java program from somewhere else and I'm going to copy and paste that and that's you'd much rather me do that than watch me type all that right I can type that live but takes a while so there we are we'll import a couple classes and this method called Julius Caesar is creating a new array list called lines and then adding a bunch of these lines to it and returning that list at the very end so it's going to return a little section of a play from Shakespeare so down here we have the main method and it will make a new instance of poetry and let's see we have Julius Caesar will want to call that and see this class should also have a method called omit which is going to take that lines list iterate through it and simply print out every line in it alright works well enough and here we'll say we'll call P 'i emit and pass the lines from julius caesar so when we run this program we should see it print out these what is this sixteen or so lines of marc anthony being upset that the conspirator has just killed his friend good enough now that's great there is our poetry java program and i'm going to come back here i'm going to run a command call tree to show you the directory structure of this java project source main java that looks familiar if you've seen if you're familiar with the standard maven directory format and Gradle thinks that's just great and then or Gradle poetry poetry Java very nice what I need now is a build file build.gradle so we've got our poem or rather our program written that spits out a poem now we need to do the difficult work of there let's think what are the things we need to do here we need a way to compile the Java code we need to maybe run some tests we need to copy static resources I don't have any static resources right now but I might need some in the future that's something that my build might need to do run tests format test results we need to build a jar we might need to tie all these things together have some kind of a top-level task that does it all that's kind of easy we saw how to do that before does all of these things so oh man we've only got 25 minutes left that's an awful lot of work to do so I don't know if we gonna be able to do it but let me try apply plug in Java that's actually all we need so let's go back to our build here I'll show you the tree again we've got source May in Java or Gradle poetry poetry we've got a build file up here I can simply run Gradle and let me again run Gradle tasks like I did before to show you suddenly having applied this Java plug-in I have a these tasks now I have a task that compiles code I have a task that builds a jar here's one that does all the compiling and then copying of static resources here's a task that runs tests if we were to introduce tests here's a task that builds Java Docs this is great I'll just run Gradle build that's kind of the the total containing do everything Java plug-in task ah here we are built now I'll clear the screen again I'm going to show you the directory tree suddenly we have build with classes here's our class file of our compiled Java code it's built a jar for us it didn't find any tests but it tried to run tests and build some formatted output it's done everything we need so now I could build classes main if I wanted to do this in or Gradle poetry a very pedantic way I can run that program from the command line and there you are and that's great okay so all that Java work done for us let's add a few more things number one this whole business of command-line Java nobody likes that okay that's just not fun at all so I'll introduce you to a new kind of task definition and that's a task with a type remember I said how tasks are objects and tasks have an API well tasks being objects can also inherit from task types and this is a documented task type that we could go into the DSL documentation and find and it would tell us this is a task for running Java programs so instead of all that command line class path stuff and it's pretty simple because I don't have any external dependencies right now if I wanted to bring in some external dependencies my life would get harder and I will in a minute but here I can just tell it run Tim runtime class path I can just tell it please go run this class or Gradle poetry poetry and please for your class path rather than having to compute the CP and figure out where everything is and how that's such a pain I can just tell it Gradle is automatically accumulating this list of all my classes all my modules I depend on and putting them there in that runtime class path variable so now I've got this task called Caesar and yeah as I said Caesar see a II there we are compile the code run it all from one place so if I were now to go change my code so if I took those commas away for example I could simply go back and run Caesar again it's going to recompile that code and we'll see the commas are gone in that line notice on that point up here cradles giving me this message that says the process resources task is up to date now process resources is looking for a directory called source main resources they see we don't have a directory called source main resources we just have source main Java so Gradle knows it doesn't have any work to do that process resources task is just idle and it's not bothering to rerun it because it knows it's work is already done in this case I changed the Java code and compile had work to do so it didn't say that it was up-to-date but suppose I run Caesar again Gradle is going to say I compile Java is up-to-date I don't need to do that not really saving us a lot of time in the case of this one file but in a practical build context that can be incredibly time-saving and all of the defaults or all of the standard plugins and the built-in tasks that come with them have automatic up-to-date checking in every case where up-to-date checking is appropriate for tasks that you write that do your own transformation building of resources and copying files and whatever it is a custom task you write there's an API for you to engage that incremental compilation framework all right I'll pause again very briefly just to make sure anybody who wants a question has a minute to get it in before we move on all right now most people are keen to understand how dependencies work with Gradle and I would love to show you that and let me briefly do that it would be kind of cool if we could encode all this output rather than just dumping the text straight out right so let's think about how we might do that I'm going to add a method to this class called encode encode takes a line of text grabs a base64 a class called base64 and attempts to base64 encode that line of text and return a new string that's the base64 encoded version of the string that we pass in so where does this base64 class come from well naturally it comes from the Apache Commons the Commons codec project no better place for it right so let's go ahead and run this and see what happens of course we should have automatic base64 encoding of everything and it should be a wonderful world we're going to go and start up we're going to compile and we've got a compile error because the Java compiler doesn't know where to get that from of course it doesn't because that class is not in our class path how do we get it there well Gradle is compatible with maven style repositories so with the Java plug-in applied I can simply say I have a dependency it's a compile time dependency on Commons codec and here we have the standard maven group artifact Version format dependency declaration and on telling Gradle that it should hook this in to not just the runtime class path but also the compiler class path this is a compile time dependency because here in poetry Java I'm including it so Java C as it's compiling program needs to have this class in its class path so that's a compile time dependency and Plaza Tories here we are Gradle is not going to assume that those should come from any particular repository I could define potentially IV repositories I could point it at a flat directory of files if I just had a directory with all my jars in it I could create it two pointed to an on-site Nexus or artifactory local maven repository of my own I could I could point it at my local m2 cache but here I'm just going to keep it simple and say I would just like you could download this from maven central and with that we have an external dependency in our project now it may or may not actually show the download happening this is probably cached locally for me so there we are and of course yeah we made we created the encode line but we never called it so let's go ahead and actually call it there we are we're encoding each one oh that's the wrong place for that and again we're repair programming so I'm sure you caught that mistake and you were getting ready to tell me in the chat but here we are in our omit method as we iterate over all those lines for each line that we emit we will also encode it first I'll go back here clear the screen run Caesar and there we are we've got basics coded stuff with that dependency already having been downloaded so if I were still playing the game of trying to run this from the command line and I was saying org Gradle poetry poetry like that it would of course tell me that I've got a class not found if I wanted that to work I'd have to go here and somehow put Commons codec on my command line here though Gradle is taking advantage of first-hand knowledge it has of the build and saying well I know what's in your runtime class path I'm just going to put that here suppose you had to in a more practical context create some kind of runtime deployment archive that maybe was a custom thing maybe it wasn't a war it wasn't an ear but it was work you had to do to bundle up these dependencies together well you have access to this list of dependencies you have access to this list now Commons codec is a trivial thing and it so happens that it does not have any transitive dependencies it's just one jar that you get but it's not too far that you have to reach into the world of open source Java before you have all kinds of transitive dependencies what if you're downloading spring core or something like that that's got wellspring cores pretty lightweight these days got like four or five but still it has transitive dependencies and what if you want to access those and use them well you've got this API inside the tool here where I could say configurations dot compile as path I could say would you please go print that out or grab this collection of files and bundle it into this custom zip file archive that I'm using that my production team expects to see since I am programming and I'm in really a development environment this nice clean declarative format is reexpose to me as a readable API that I can see as a programmer and I'll go ahead and take that line out will not continue to be distracted down that path but I want to make clearly the point that not only can we declare things easily but we can later in an imperative sense access those things as if we were programmers I see a few questions have appeared that scrolled off the bottom of the screen one question from Ivan how does Gradle know that when you run Gradle Caesar it should run all these tasks because I didn't declare any dependencies did I awesome question Ivan it's magic but it's magic that's very carefully defined and the bottom line here is that because I'm accessing this internal variable here called runtime class path that's a variable in the Gradle domain model Gradle knows how that thing gets populated and it gets populated in two places number one from compile and run time dependencies that I declare and number two from the output of a task called compile Java we've seen compiled Java run when we run the build compile Java generates outputs those outputs are inputs to this thing Gradle knows that and so it auto wires the dependency in other words it will figure out dependencies that are that are formally present even if you don't indicate them explicitly so I could go depend on compiled Java here but it's not necessary Gradle does that for me and it does that in a formally correct way where did Gradle get the plug-in from apply plug-in Java it's packaged with Gradle the Java plug-in classes and a plug-in is a class and a collection of other APAP isin dependencies it needed those are bundled into Gradle so I get that for free when I'm introducing or when I'm asking for or applying a plug-in that isn't a standard built-in plug-in then I need to provide some other help for Gradle to know where to go get that from for example I've written an open sourced liquid-based plug-in that's available on github and for you to use that and you can pay me later if anybody's interested in that as an aside if you want to get to an open source plug-in like that there's a little bit more text you give it to say hey go get it from maven central here's the group artifact version etc dimitri asks where does plugin reside same question again that's inside Gradle inside the Gradle installation Demitri asks can I distribute plugins via repositories and pick them up automatically during the build the answer Dimitri is absolutely positively yes Sangeeta asked where is maven central defined that's defined as a part of the Gradle DSL so it's a feature of Gradle that it understands that maven central Maps to the standard URL for maven now if I wanted to define other maven repositories there'd be another syntax that I use here that would look something like this and I won't do that I don't have that other maven repository available to me but I'm able to define other local maven repositories if I don't want to use central if I just want to use central I use it like that and we have one report from a few minutes ago of losing audio can I get a few people indicating whether or not you have audio you you okay thank you everybody all right this is a great project and and groundbreaking it's okay it's pretty simple project but look at what we've seen here we've seen we get this plugin that's built-in that applies all of this conventional behavior I don't have to be imperative about a single thing ever I get all my Java built to work I could go write tests and I'd have a task called Gradle test that would run the tests form out the app form at the output and do all that work for me so that's that's really the right way to get large bulk amounts of functionality into your build and keep the build file simple we've seen how to integrate with external dependencies we've seen how to add tasks of our own we've seen that tasks can have types and with task types come the imperative behavior the actual forking of a JVM and formulating of the command line and all that stuff that you got to do to go execute Java code that's all hidden inside that task definition inside Gradle itself and then I have declaratively just a few parameters the minimum number of parameters that I need to make that task do the thing I want and it turns out if you look in the DSL docs for Java exec there's a rich API there's a couple dozen properties I can set the input stream the output stream I can set heap parameters anything I'd want to do with a JVM I can set and those are all just declarative parameters not imperative things so that's pretty great I'd like to translate this a question quickly from Santi do we need to worry about things like maven lifecycle phases goals etc with Gradle and the answer is no you don't activity is organized into tasks and tasks are the things that get executed dependencies are computed by Gradle such that all of the things that need to run based on the dependencies you've defined those things run so there isn't any kind of specific or rigid life cycle that a build has in Gradle just doesn't exist so you get to define the idiom of your build and the language of your build by defining those tasks rather than conforming it to the lifecycle phases that some kinds of builds have now the maven lifecycle really isn't it isn't like it's some bad idea or somehow harmful it's a really good idea in a really strong set of of activities to divide a build up into but only certain types of builds so for the builds for which it makes sense it makes all kinds of sense and some of the smartest builders that we have have identified those lifecycle phases for us to use but your build might not look like that so Gradle doesn't want to half you half you won't want to force you to have to fit your build activities into that sort of thing it would rather say why don't you just define your tasks as needed and express your build activity in that way all right I'm going to go ahead and close this down we'll save that file I'm going to close this and we'll save this and we're going to go up into a multi project build which is for the most part already put together for us and I'll show you roughly what that looks like so let's see if we can get the tree here here we are here's the tree of this project I'll start at the bottom I've got source main Java comm no fluff poetry a different packaging system there but here's this top-level project called the poetry emitter this class here then I've got a sub project of content alright and this has a single class called poetry that generates the content and I've broken my codex stuff into another project the codec sub project so let's take a look at how these individual pieces work and I'm just going to open this up as one big project and we will quickly work through this it actually won't take us long to build this whole thing in the time we have remaining so here's our top level kind of command line driver or program that runs all the other programs our main method still looks into this poetry class for content called Julius Caesar and tries to omit that the omit method is right here in the poetry emitter a good place for us but it expects this codec object to be present to be doing the encoding we instantiate that codec object right here the codec isn't here and worse yet poetry isn't here those are in sub projects so over here we have our sub project called content that introduces this poetry class that does what our other Julius Caesar method did see there it just spits out all those lines and we've broken out the content or pardon me that the codec stuff into a class of its own in a project of its own all right now how do we put all that together well the way we do that I'll walk you through this build we can do this actually in a single build file so I'll take you to this block here called all projects all projects in a multi project build defines a block where we're giving configuration that applies to all of the projects in the build so we're saying all of them are Java plug-in projects and if any of them needs to go get dependencies it should get those dependencies from maven central if we jump down here to line 14 I'm able to define configuration for the content sub project just this sub project on its own just the content guy with the poetry class in it I'm saying well it has a dependency on j-unit it's going to run some tests down here on line 20 I'm saying I would like to define some configuration that applies only to the codec project so the codec project itself has a dependency on Commons codec just like we saw before now notice what's a little bit surprising about this this way of config during the build doesn't have a build in the codec directory and a build in the content directory it has one top-level build that does all that work all by itself this is just one way of configuring a multi project build and Gradle and I'm showing you this to illustrate something very very important that's that as a multi project build in Gradle I have a means of accessing all of the other project builds in the project graph so from the top level I'm able to specify configuration that my sub projects should have and in some cases that might be very important for example you might want to say well all you sub projects you're only allowed to use our internal nexus repo as to resolve your dependencies you can't define any other repositories and if you do we'll fail the build so you want to be able to reach down into project codec and project content and see how have you done this and make sure they're doing things in the right way alternatively I could take configuration like this dependencies in this codec file and factor it into a build file that lives specifically in that codec directory so with Gradle in a multi project build I have the option of having this kind of radical unified build with everything in one place I could have a radically onion if I'd build where all of the sub project configuration is at the sub project level or I can decide to factor that configuration between sub project and top level project in whatever way I want it's a completely programmable model and all of that task configuration is available to me from here and I had planned on let's see what are my poetry is my task here I planned on having to tweak this code a little bit to get everybody familiar with how structured we'll see if it works on first run and you see it's now building wonderful it's it's compiling Java in the codec project it's compiling Java in the content project now at the top level it's compiling project it's running the poetry task and it spits out all our encoded poetry again with this multi-project module I see there are a few questions here let me make sure I take those is it possible to keep Paulo is it possible to keep import dependencies from a pom an XML file yes there is a community contributed plug-in or a maven integration plug-in that will allow you to import dependencies from a pom.xml file once you can reach out to me after the webinar and we can talk about details of that offline does the Java plug-in Patrick asked does the Java plug-in point to Java home or is there a Gradle config there are a number of Gradle configurations and I'll point you briefly I'm here in the DSL documentation I would scroll to task types and I would go to Java exact and then I would feast on the rich library of configuration parameters that I can give Java exec that tell it exactly where to go for all that stuff so Patrick Java exactly is deeply configurable for running that Java program Ivan asks does sub-project name in the Gradle build file depend on the subdirectory name and the short answer Ivan is yes that's the most convenient way to make that reference we're right at the end of our time we've pretty much gotten through all the things I wanted to be able to show you I wanted to give you some of graybles philosophy why it's being another build tool how Wyatt values declarative over imperative and why it sees tremendous value in build configurations but also really wants to make it easy for you to customize your build we we took a look at the basics of Gradle tasks I showed you how to use the Java plug-in in a very simple way and how to convert that Java project into a multi project Java build or a multi module Java build and a little bit about how the Gradle API interacts with multi project builds there's much more to say about multi project builds there's much more to say about plug-ins about other little corner cases of the the the Java plug-in and the API is it exposes there's really lots to talk about there particularly in the topic of plugins and build customization that stuff that really gets me going I just get totally excited about that because that's where the magic of Gradle happens the magical Gradle isn't in building simple projects like this we kind of the world already knows how to build things like this it's good to know the Gradle idioms for simple projects but the rest of the world is composed of profoundly customized increasingly highly automated very complex builds and it's in Gradle plug-in API that you really start to get a handle on how to tame that complexity how to write a bunch of high value custom build software for your organization but then expose it to the developers who use it with a very simple domain specific language exposed in terms that all of your developers understand so this is the stuff again that that really gets me going in terms of Gradle so thank you very much for being here you guys I'm going to stick around for a few minutes and answer your questions but I'll say for now we are officially concluded and I thank you very much for your attendance we'll follow up with you by email and give you some additional resources so thank you very much for attending and we'll hope to talk to you soon
Info
Channel: Gradle
Views: 133,285
Rating: undefined out of 5
Keywords: gradle, java, groovy, Java (Programming Language)
Id: OFUEb7pLLXw
Channel Id: undefined
Length: 59min 45sec (3585 seconds)
Published: Fri Jul 25 2014
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.