I mentioned some time back that where I work we do Agile software development. This phrase, though accurate in some sense, shows a certain misunderstanding of what Agile is. Sure, you might ‘do’ Scrum, or ‘practice’ XP or Kanban or Lean or whatever, but you don’t ‘do’ Agile. You adopt these processes as a starting point so you can be Agile, and being Agile is worlds more important than doing Agile.
Doing Agile implies the mechanical application of some set of practices with no understanding of or commitment to the principles and values underlying them. Frequently this comes about because the decision to do Agile is made from the top down rather than the bottom up. If it isn’t fully embraced by the team with energy and commitment then they’re just going through the motions. Yes, they’re doing something and in some ways it might work, but they aren’t being Agile.
The issue can be further complicated when ‘doing’ some Agile process is considered more important than ‘being’ Agile. I refer to this as ‘process attachment’ and it likely happens with Scrum more often than with XP or the other Agile variants (because Scrum has a broader adoption base and more of a project management focus). This attachment manifests as a viewpoint or environment where all other methodologies are disallowed and deviation from the One True Process is frowned upon. What those fixated on the rigid adherence to the letter of a certain process miss is that this attachment to methodology is precisely one of the reasons the Agile movement started in the first place. That’s why point one of the manifesto is “Individuals and interactions over processes and tools”. Process attachment runs counter to the core of Agile because the process is of minimal concern compared to the project and the team.
By all means, start with Scrum or XP or Kanban or Lean, but after a number of iterations there should be some drift. This is because fully agile teams will find a steady-state in a zone with maximum productivity and minimum process. Agile incorporates a feedback loop every iteration for this very purpose. Retrospectives are the crucible of change for how you operate. Iterations aren’t just about the project, they also apply to refining and improving the process.
“Hold on, Ben,” those with process attachment might say. “We need to standardize on one process so we can move resources around and everyone is on the same page about how things work.” No, no, no. These resources you speak of are people, and people can’t be abstracted down to cogs in a development process machine. People bring too many variables and different strengths, weaknesses and personalities. Different teams of people have different dynamics which yield different optimal environments. Good teams can succeed with almost any process, but they can deliver better and faster when they define how they work. Process for the sake of process at that point is (at best) waste and (at worst) counter-productive.
Agile methodologies are useful tools, but Agile itself is more of a philosophy. Find energetic teams of people that are committed to the principles and values and let them decide how they work best. If the organization requires certain metrics or data points, let them know and they’ll deliver. Beyond that, leave them alone and let them build the solutions. At the end, it may not be exactly Scrum or XP that they’re doing but they will be as efficient and effective as possible. All because they’re being Agile, not doing Agile.
Java Builds with Gradle
I’ve been working on Java projects for years now and the two primary build systems for such projects have been Ant and (more recently) Maven. Both have given me headaches for various reasons and lately I just find Maven increasingly cumbersome to use. Yes, the dependency management features are great (most of the time) and the multi-project support works well, but sometimes I need it to do more (or in some cases less) and that ends up being harder than it should be. Then there’s all that XML. Hundreds to thousands of lines of it with what seems like more noise than usefulness. Maybe it’s just me, but I expect my build script to look more like … well, a script.
So I’ve been looking for alternatives and it looks like there are a few to choose from. The Apache Software Foundation has one called Buildr which is Ruby based and therefore outside of my current comfort zone. The other big frontrunner is a tool called Gradle. This is a Groovy-based DSL that combines the good things about Ant and Maven into a concise and extensible syntax that is backed by a dynamic language. I could tell you more about it, but the Gradle website does so much better than I could. Besides, I think a demonstration is much more useful.
The Example
Let’s say we have a multi-module project that uses Maven conventions. The three modules are ‘core’, ‘engine’ and ‘webapp’ which result in two jar files and one war file. Furthermore, the engine depends on the core and the webapp depends on the engine. With me so far? Good. So how do we build such a project in Gradle? First, we need to create a file called settings.gradle in the root project folder to tell Gradle what the subprojects are. Here’s what goes inside it for our hypothetical project:
One line, zero XML. Life is good. Now we need to create a file called build.gradle that will contain common information for the subprojects.
I admit, I’m throwing a lot at you at once so let’s take a look. We’re telling Gradle that our modules use the ‘java’ and ‘eclipse’ plugins (there are other plugins available, including support for groovy and scala source code). All the modules are version 1.0, the base project name is ‘ballista’ (that’s my own custom variable, not anything like a Maven artifactId) and the group for Maven repository purposes is ‘com.ioglyph.ballista’. Yes, Gradle supports downloading from and uploading to Maven repositories. The ‘repositories’ block illustrates that – we’re telling Gradle to pull dependencies from the Maven central repository. Additional repositories could be added to this section if needed. Next, we define our ‘dependencies’ block. Each line is equivalent to an entire ‘dependency’ tag in a Maven pom.xml file. We have various scopes in use here and I’ve shown two different ways to define the artifact. The first three use the format “group:artifact:version” whereas the the fourth explicitly delineates those three properties.
At the end you’ll notice we’ve added a bit to the Gradle ‘jar’ task. The subprojects will get the basename for their jar files from the name of the subdirectory they are in, so our jars would end up being called core-1.0.jar and engine-1.0.jar which isn’t what we want. Instead, we’re telling Gradle that the basename for the jar should be prepended with the value of the ‘projectName’ variable defined earlier. Now they’ll end up being called ballista-core-1.0.jar and ballista-engine-1.0.jar. We’ll still need to address the name of the war file for the webapp, but we’ll get to that.
Now that we have the basic information for the project, it’s time to work with the subprojects. First off, the core/build.gradle file.
That’s it. Yes, it’s essentially empty, but if the core needed any dependencies not defined in the parent build.gradle we would add them here. Next, the engine/build.gradle file.
Here we’ve defined the dependency between the ‘core’ subproject and the ‘engine’ subproject. As mentioned previously, any dependencies not defined in the parent could be added here. Finally, we look at the webapp/build.gradle file.
Now we’re getting somewhere. We’ve added a couple plugins, one to create a war file and the other to run the Jetty servlet container with our webapp deployed. Additionally, we’ve defined the dependency between the ‘engine’ subproject and the webapp. This will pull in the ‘core’ jar file as well unless we wanted to disable that transitive dependency. In this case we don’t. An additional dependency was added to the Apache Wicket project (if you aren’t familiar with it, I recommend taking a look after you’re done here).
We’ve extended the default ‘war’ task by defining the base name of the war file to equal the value of the projectName variable. You’ll noticed that variable isn’t defined in this file but it was defined in the parent build.gradle file. So now the final war file name will be ballista-1.0.war. Finally, we had to extend the source sets that Gradle moves during the build process. Under normal circumstances, only the Java source files are compiled and moved to the build directory. If you’re familiar with Wicket, you know that there are HTML files that need to move over as well. This ‘sourceSets’ extension takes care of that for us.
Now when we run gradle build from the root of the project, we see the following output (artifact downloads have been omitted):
Now in each of the subproject folders you’ll see the appropriate artifacts in the build/libs directories. If you crack open the webapp/build/libs/ballista-1.0.war file, you’ll see the various dependencies have been included as expected. With the Jetty plugin applied we can run the webapp by issuing the command gradle jettyRun and navigating to localhost:8080/ballista to verify that the webapp runs as expected.
I’ve only scratched the surface of what Gradle can do as I’m still learning how to use it. Additional information can be found on the Gradle web site. There they have an extensive user guide that contains most everything you will need to make Gradle work for what you need it to do. I recommend checking it out and downloading the latest version. If you’d like to view the source code and build files used in this post, you can find a link below (you’ll need to have Gradle installed to run the builds).
gradle-sample.zip