Start Here !

Welcome to my website. Find articles, presentations, tutorials, experiments on various technologies.

You can get in touch with me anytime at

r o m i n . i r a n i @ m i n d s t o r m s o f t w a r e . c o m

I am also active on Twitter – do follow me.

Posted in Uncategorized | Leave a comment

Gradle Tutorial : Part 3 : Multiple Java Projects

Welcome to Part 3 of the Gradle Tutorial. This part builds on Part 2, where we looked at using the Java plugin in Gradle to compile/build our Java project.

In this part of the tutorial, we shall look at a common scenario where you will have multiple Java projects that could be dependent on each other. For e.g. You could have a library project where you write some utility classes and another Java project that depends on it.

This part assumes that you have a Gradle installation on your machine and the basic environment is setup. For more information on that, refer to Part 1. Additionally, you know the basics of using the Java plugin in Gradle, which we covered in Part 2.

Just to remind readers, the focus will be on understanding Gradle and how it goes about doing stuff when it comes to Java projects. So we will not be worried about the Java code that goes into those projects.

Multiple Project Scenario

For this episode, we shall look at 3 projects that are arranged under a common directory. This is just for demonstration but it will help us understand the concepts well.

Our directory will be called javaprojects and inside of that we have 3 other folders that will house the individual projects as shown below:

javaprojects
|- api
|- common
|- app

Now, let us talk about the dependencies. These dependencies are something like this:

  1. common: This project contains some utility code and hence it will not depend on any of the other projects. Do note that this does not mean that common does not have dependencies on external libraries for compilation. So that concept that we saw in the earlier chapter still remains. It may depend on 3rd party JARs.
  2. api : This project contains some API code and it depends on common project
  3. app : This project contains the application code and it depends on api and common projects

On my machine, I have created a folder named e:\javaprojects and inside of that I have 3 empty folders api, common and app. I have intentionally left them empty for now, so that you can see how it will all come together.

You can select the appropriate drive and/or root folder, but for the purpose of this episode, e:\javaprojects is my container for the other 3 projects.

While they are empty, you can easily visualize that in reality you will have Java classes inside of each of these folders. And since we are going to eventually use the Java Gradle plugin to compile the code, the Java classes inside of these folders will follow convention i.e. they will be present under src/main/java folder as we saw in Part 2.

Including Multiple Projects in Build

The first thing you should think of is a central place to control the overall build for all the 3 projects. Gradle makes this easy for you by asking you to create a gradle.settings file in the root folder.

So, in the e:\javaprojects folder, create a file named settings.gradle and in the file, all we will need to do is mention the projects (i.e. the folders) that comprise our 3 Java Projects i.e. api, common and app. The settings.gradle file is shown below:

include ":api", ":common", ":app"

Common Configuration

You are familiar with the build.gradle file, which is what the Gradle command looks for in terms of what it has to do.

Create a build.gradle file in e:\javaprojects directory. This will be our file that will specify what Gradle needs to do.

Remember we do not have any Java files so far in any of the 3 directories : app, common and api.

Let us look at one of the recommended and fairly intuitive structures for the build.gradle file as shown below:

allprojects {
  //Put instructions for all projects
}

subprojects {
  //Put instructions for each sub project
}

To understand what is happening, update your build.gradle file in the root folder i.e. e:\javaprojects to contain the following:

allprojects {
  task hello << { task -> println "I'm $task.project.name" }
}

subprojects {
  
}

What have we done here ? We have added a task (written in Groovy) to simply print out the project name. And we have put that inside the allprojects closure. This means that it will apply to all the projects.

Save the build.gradle file and go to the root folder at the command prompt/terminal where the build.gradle file is, and fire the following command:

gradle -q hello

This will produce the output as given below:

I'm javaprojects
I'm api
I'm app
I'm common

You can also fire the task individually for any specific project, as given below:

gradle -q app:hello

This will produce only app specific output as given below:

I'm app

This should make things clear that you can apply commands to all projects and then you have full control on how to run it i.e. run it in such a way that it applies to each project or any specific project.

Apply Java plugin to Sub Projects

Now, we know that the 3 projects : api, common and app are Java projects. Hence we can do the following for the 3 Projects:

  • Apply the Java plugin
  • Setup the MavenCentral repository, assuming that these projects will have 3rd party dependencies , which we would like to pick up from Maven Central.

The build.gradle file in the root folder will now look like the following:

allprojects {
  task hello << { task -> println "I'm $task.project.name" }
}

subprojects {
  apply plugin: "java"
  repositories {
      mavenCentral()
  }
}

We know that the Java plugin adds several tasks like clean, assemble, build, etc, which make it easy to work with the build process if you follow conventions. We saw that in Part 2, if you wish to refer to that.

By putting those commands inside of subprojects, we have essentially injected common characteristics into each of the sub projects i.e. common api and app.

Go back to the command prompt or terminal and fire the following command:

gradle build

You will find in the output (which I am not listing here) that the build task got fired on each of the projects and all tasks that it was dependent on is also executed. Cool isn’t it.

Remember, if you just wish to build the common project, you can always invoke the following (gradle <project-name>:<task-name>):

gradle api:build

We do not have any Java files in any of the folders so far, but that is fine for now.

Project Specific Configuration

What if you wanted to apply some tasks , plugins, dependencies differently to each project and or one or more projects and not all of them.

For the 3 projects that we have, the build.gradle file would need to look something like this:

allprojects {
  task hello << { task -> println "I'm $task.project.name" }
}

subprojects {
  apply plugin: "java"
  repositories {
      mavenCentral()
  }
}

//API Project specific stuff
project(':api') {
}

//Common Project specific stuff
project(':common') {
}

//App Project specific stuff
project(':app') {
}

As an example, let us say that we would like to apply the java plugin only to common project and not to any of the other projects. An example of such a build.gradle is shown below:

allprojects {
  task hello << { task -> println "I'm $task.project.name" }
}

subprojects {
   //Some other stuff (Empty for now)  
}

//API Project specific stuff
project(':api') {
}

//Common Project specific stuff
project(':common') {

   apply plugin: "java"
   
   repositories {
     mavenCentral()
   }
}

//App Project specific stuff
project(':app') {
}

Save the above build.gradle file.

Now fire the following command :

gradle app:build

This should give us the error that there is no build task for project app. This is because build task is only available in the project for which the Java plugin has been applied.

FAILURE: Build failed with an exception.

* What went wrong:
Task 'build' not found in project ':app'.

Similarly, if you fired the following command:

gradle common:build

You will find that it executes the build task successfully since it is available for that project as per our build.gradle file.

:common:compileJava UP-TO-DATE
:common:processResources UP-TO-DATE
:common:classes UP-TO-DATE
:common:jar UP-TO-DATE
:common:assemble UP-TO-DATE
:common:compileTestJava UP-TO-DATE
:common:processTestResources UP-TO-DATE
:common:testClasses UP-TO-DATE
:common:test UP-TO-DATE
:common:check UP-TO-DATE
:common:build UP-TO-DATE

BUILD SUCCESSFUL

Total time: 3.681 secs

Project Compilation Dependencies

Recollect that we had defined our project dependencies as follows:

  1. api depends on common
  2. app depends on api and common

In addition, we will also need to consider that each of the projects might have dependencies on 3rd party JAR files.

So , let us say that the requirements to compile the projects are as follows:

  1. common requires Apache Commons Lang 3.3.2
  2. api requires Apache Commons Lang 3.3.2 and Apache Log4j 1.2.7
  3. app requires Apache Log4j 1.2.7
  4. All of the projects have JUnit Test cases and require that the JUnit Jar file is linked. Any JUnit JAR file above 4.x will do.

Given the above requirements (I am not going to show you the source Java files or JUnit Test cases, since that is not necessary here), our build.gradle file that is present in the root folder will look like this:

subprojects {
  apply plugin: "java"
  repositories {
      mavenCentral()
  }

 dependencies {        
    testCompile "junit:junit:4+"
 }
}

//Common Project specific stuff 
project(':common') { 
  dependencies {
    compile 'org.apache.commons:commons-lang3:3.3.2'
  }
} 

//API Project specific stuff 

project(':api') { 
   dependencies {
      compile project(':common')
      compile 'org.apache.commons:commons-lang3:3.3.2'
      compile 'log4j:log4j:1.2.17'
   }
} 


//App Project specific stuff 

project(':app') { 
   dependencies {
      compile project(':common'), project(':api')
      compile 'log4j:log4j:1.2.17'
   }
}

Some notes on the above build.gradle file:

  • In the subprojects closure, we have added the stuff that is common to each project i.e. applied the Java plugin, added the maven repository and added the common dependency on JUnit JAR for the testCompile configuration.
  • Then for each of the sub projects, we have clearly specified the dependencies , not just on the project but also on any individual JARs.
  • Please note that we have considered only the compile configuration in the build file here. You can always target other configurations provided by Java plugin like testCompile, run, testRun and so on. So you can enhance the file depending on your requirement.
  • The compilation dependency on another project is specified via the
    compile project(<projectname>) statement
  • The compilation dependency on a JAR file is specified via the same mechanism that we saw in Part 2 i.e. “group:name:version”

As an exercise, I suggest adding a few of your own Java files, setting up the correct dependencies and then firing the gradle build command.

One or multiple build.gradle files?

The question that you should be asking now is whether it is the right approach to create a single large build.gradle file in the root folder that will:

  • Apply common code within the subprojects closure
  • Contain individual project(<projectname>) closures that will define tasks specific to that project, its own dependencies, etc.

We have an example of one such build.gradle file in the previous section. A good practice is actually not to have one single file but to break them into multiple build.gradle files and each of these specific build.gradle files will be present in the respective root folders of the 3 projects i.e. app, common and api.

In essence, what we are ending up with is a structure that looks like the following:

/javaprojects
|- /api
     |- build.gradle
     |- (Java Sources and files)
|- /common
     |- build.gradle
     |- (Java Sources and files)
|- /app
     |- build.gradle
     |- (Java Sources and files)
|- settings.gradle
|- build.gradle

Notice how at the root, we will continue to have the settings.gradle that includes all the projects as we saw.

There is a build.gradle at the root also. This will contain stuff that is common to each of the sub projects. For e.g. since each of our sub projects are Java projects and we plan to use the Maven Central repository, the contents of our build.gradle could be as short as the following:

subprojects {

  apply plugin: "java"
 
  repositories {
    mavenCentral()
  }

  dependencies {
     testCompile "junit:junit:4+"
  }
}

Now, our individual build.gradle for the specific projects will be roughly as shown below:

build.gradle for app project

dependencies {
      compile project(':common'), project(':api')
      compile 'log4j:log4j:1.2.17'
}

build.gradle for api project

dependencies {
      compile project(':common')
      compile 'org.apache.commons:commons-lang3:3.3.2'
      compile 'log4j:log4j:1.2.17'
   }

build.gradle for common project

dependencies {
    compile 'org.apache.commons:commons-lang3:3.3.2'
  }

In this way, you can manage the Gradle build files separately for each project. It will be easier in the long run to do things in this fashion, so that any new project can be added and its specific dependencies / tasks can be handled in its own build.gradle file.

Keep in mind that each of these individual build.gradle files can be enhanced to as much extent as you want depending on your requirements.

Recommended Reading

I suggest that you look at the following documentation in Gradle that contains a lot more examples and will help in solidifying your understanding : Multi-Project Builds.

As an exercise, if you use Android Studio and have attempted to generated both an Android project and an App Engine project, you will now be able to understand what has been generated when it comes to Gradle. You will find a settings.gradle there with all your modules in the Android Studio Project. It will contain a base build.gradle file that will contain common behaviour and then individual build.gradle files for each of the plugins. You should feel more confident of things now. We will get to those in a while, so if you do not want to revisit your Android Studio for now, that is fine too. 

Moving forward

We have moved quite a bit now in our Gradle journey. By now, you should start feeling comfortable with the whole thought process of building your projects and how Gradle fits into the project.

But we still have a long way to go and the next logical step to take for us is to look at Gradle War (Web Application Archive) plugin that helps with Java Web projects. Till then, Happy Gradling!

References

Posted in Tools | 2 Comments

Gradle Tutorial : Part 2 : Java Projects

Welcome to Part 2 of the Gradle Tutorial. This part builds on Part 1, where we looked at installing Gradle and learnt a few basic commands.

In this part of the tutorial, we shall look at how you can use Gradle to compile/build/test your Java projects. The focus will be more on Gradle mechanics rather Java code, so I will be using simple Java projects that help illustrate the Gradle concept. You should be able to build on this while tackling a larger Java code base.

This part assumes that you have a Gradle installation on your machine and the basic environment is setup. For more information on that, refer to Part 1.

Gradle : Project , Tasks and Plugins

Let us recap a few things from the previous session and add to it some more stuff that will be required in this tutorial.

To summarize, the build.gradle was the file that we wrote to drive our Gradle build process and the build file contained tasks i.e. instructions to do something. Think of tasks as the ones that we would normally do if we did not have any of these tools to manage the build process. These tasks would be compile, test, build the jar, deploy, etc.

We do not have to write all these tasks by hand and just like what we have seen with other build tools and our IDEs, plugins come to our rescue. There are several Gradle plugins that make it easier for us to simply invoke the Tasks and if we follow convention, then Gradle does the rest for us.

What do we mean by a Plugin ? A plugin is a mechanism by which we can extend the capabilities of Gradle. Gradle need to know how to build everything and anything for us. But we can make that possible if we know a certain process and can create pre-built tasks that it can then perform for us. This is the role of a plugin.

The series will not focus on how to write a Gradle plugin. Rather we will use great Gradle plugins that are available to us to do our job. These plugins will add tasks that we can invoke straightaway. And you know what a Task is .. correct ? We saw that in the first part.

Just bear with me a little bit more .. things will fall in place.

Java plugin

Let us start with the most important of all for Java developers : the Java plugin. As expected, this plugin adds the following capabilities to a project:

  • compilation
  • testing
  • bundling

Logically, this is all we need to do with our Java projects, isn’t it ? The bundling typically would mean a JAR file in most cases.

Any plugin that you need to use should be added to the build.gradle file via the following statement:

apply plugin: <plugin-name>

In our case, since we want to use the Java plugin, we will use the following statement:

apply plugin: "java"

Let us get started with understanding what goes on behind the scenes.

Create a folder say example2 on your machine. You can use any folder that you wish on your machine. Just make sure that you follow one that suits your environment and that gradle is available from any directory on your machine.

Create our standard build.gradle in this folder. Just put the following line shown below in the build.gradle:

apply plugin: "java"

As discussed earlier, the plugin will add a bunch of tasks that know how to deal with typical Java projects. Let us fire the following command to understand what tasks have been added:

gradle -q tasks

This will produce the following output ( I am only including the buildTasks from my output):

Build tasks
-----------
assemble - Assembles the outputs of this project.
build - Assembles and tests this project.
buildDependents - Assembles and tests this project and all projects that depend
on it.
buildNeeded - Assembles and tests this project and all projects it depends on.
classes - Assembles classes 'main'.
clean - Deletes the build directory.
jar - Assembles a jar archive containing the main classes.
testClasses - Assembles classes 'test'.

As you can see, various tasks have been added and most of them are intuitive enough for you as a Java Developer to understand. For e.g.

  • clean will delete a build directory, all your classes will be removed for a fresh compile.
  • assemble will create an archive (JAR) file from your Java project and will run all other tasks that require compile, test and so on.

These tasks could also depend on each other and so on. Refer to the documentation for a complete dependency graph of these tasks.

Basic Java Project with Gradle Java plugin

Given this basic information, the first question that should strike you is that now that you have added the Java plugin and have some idea about the tasks that it provides i.e. clean, assemble, build, etc. , how do we invoke it ?

We already know that to invoke the tasks, all we need to do is fire the gradle <task-name> command. That is fine but what about my Java project i.e. the .java files and so on. Where is that ? What are the rules to follow for that ? Is there any conventions to follow so that the plugin knows exactly what to do ? What if my folder structure is different, will Gradle be able to help there?

The above are valid questions and Gradle has an answer for all of them. In this tutorial, we shall be following convention which means that the Java plugin of Gradle will look for files in certain folders. But be assured that if you prefer a non-convential way, you can get those things addressed via Gradle too – just that it is out of scope of this tutorial series.

From the official documentation, the Java plugin expects the following folder structure for your Java code and Java test classes:

img4

This is not mandatory and if you wish you could have different folders. Just look up SourceSets in the official documentation for the Java plugin to see how you can specify alternate Sourceset.

What is a SourceSet ? It identies the source i.e. grouping for your source files that need to be compiled and built together, some sort of a logical grouping or component. As per the official documentation, the Java plugin defines two standard source sets, called main and test. The main source set contains your production source code, which is compiled and assembled into a JAR file. The test source set contains your unit test source code, which is compiled and executed using JUnit or TestNG.

Given this information, we are going to put all our sources and test files as per the folder structure recommended by default by the Java plugin. This means:

  • Put all your Java files (full package,etc) into the src/main/java folder
  • Put all your Test files (JUnit stuff) into the src/main/test folder

I have gone ahead and put one Java source file inside of src/main/java folder. The folder structure as per the package is :

img5

Inside this quoteapp folder i.e. package com.mindstorm.quoteapp I have my one single Java file named Quote.java as shown below:

package com.mindstorm.quoteapp;

public class Quote {
 private Long id;
 private String who;
 private String what;
 
 public void setId(Long id) {
 this.id = id;
 }
 public void setWho(String who) {
 this.who = who;
 }
 public void setWhat(String what) {
 this.what = what;
 }
 public Long getId() {
 return id;
 }
 public String getWho() {
 return who;
 }
 public String getWhat() {
 return what;
 }
}

Now, let us go back to the root folder i.e. example2 where I have my build.gradle file. The file still has just a single statement i.e. apply plugin: “java”

Now fire the following command as given below (Note that I have removed the -q so that you can see all the console output)

gradle assemble

This will do all the hard work of compiling, building your Java files into a JAR file. Multiple tasks are fired, which shows that the assemble task in return depends on several tasks that it is executing first. The output of the command is shown below:

E:\gradle-projects\example2>gradle assemble
:compileJava
:processResources UP-TO-DATE
:classes
:jar
:assemble

You can experiment with introducing compilation errors and seeing what happens if you try to run the assemble command.

What did the command result in? If everything went well, the command resulted in a build folder in your project root directory. Inside of that, you will find a libs folder and inside which is the example2.jar . Your file name might be different depending on your folder name.

If you wish to clean (empty) the build directory and do a clean build again, you can invoke a gradle clean command first and then a gradle assemble command.

You can also fire the following task which does all the check and assemble for you:

gradle -q build

Let us improve things a bit. What if we wanted to give a version to the JAR file and a different name. To do that, simply do the following:

Update your build.gradle so that it looks like this:

apply plugin: 'java'
archivesBaseName = "quote"
version = '1.0-FINAL'

Now, fire the gradle assemble command and you should have a JAR file that is named as <name>-<version>.jar in the build/libs folder. In my case, it will be quote-1.0-FINAL.jar.

Note : You might be wondering from where do I produce stuff like archivesBaseName, etc. The only answer I can give is that the documentation is vast and you will have to navigate yourself through it. For e.g. go to the official page of the Java plugin, search for archivesBaseName and you will understand what is going on. My only advice is to keep the documentation handy, some property or the other will be there, just think logically and you will find the answer in the documentation.

The beginning of Dependencies

We have to tackle this sooner or later. And the moment has arrived. There is not much chance for any of your Java projects to not depend on 3rd party libraries. Consider the above Quote.java where we just wrote a simple Java Bean and there was nothing else to it. What if we modify it a bit by adding a toString() method implementation that makes use of the 3rd party library : Apache Commons JAR.

Let us first look at the code:

package com.mindstorm.quoteapp;
import org.apache.commons.lang3.builder.ToStringBuilder;

public class Quote {
 private Long id;
 private String who;
 private String what;
 
 public void setId(Long id) {
 this.id = id;
 }
 public void setWho(String who) {
 this.who = who;
 }
 public void setWhat(String what) {
 this.what = what;
 }
 public Long getId() {
 return id;
 }
 public String getWho() {
 return who;
 }
 public String getWhat() {
 return what;
 }

 public String toString() {
 return ToStringBuilder.reflectionToString(this);
 }
}

This is fairly straightforward Java stuff. Nothing much of interest here.

Obviously if you try to fire a gradle assemble command now, you will face issues. I suggest that you do, so that you can see the error reporting in all its glory. You should see the standard compilation error along with the BUILD FAILED message.

The solution is obviously to tweak the build.gradle file so that it is aware of 2 things:

  • What JAR files are needed to compile the code ?
  • Where to find those JAR files ?

Enter the world of Repositories in Gradle. A Repository in Gradle is a location where Gradle can locate the JAR files in our case. Gradle supports popular public repositories like Maven Central, Ivy and even your local repositories if you want. So if you are coming in from a Maven world, this will sound familiar.

To configure a Remote Repository, you will need to add the following element to your build.gradle file:

repositories {
  mavenCentral()
}

This will make Gradle look for any dependency (JAR files) that you specify in the Maven Central Repository.

Just keep this point in mind and we shall come to it later. Each file when published to Maven Central or any repository for that matter will have the following characteristics:

  • A Group Id (group)
  • An Artifact Id (name)
  • A Version (version)

So for example, if you want to locate the Apache Commons 3.3.2 JAR (which is the latest at this time of writing), it will be available in Maven Central as given below:

img1

The above screen is taken from Maven Central repository. If you are in doubt for any of your dependent JAR files, simply search in the Maven Central Repository.

Allright, more on this later. But first, let us understand Configurations in Gradle.

Configurations provided by Java plugin

All we have talked about so far, is that we found that we need to provide the build.gradle file with additional information on which dependencies (JAR files) are needed to compile the code and where it can find that. We solved the where part by mentioning the mavenCentral() repository from where it can pick up the files. But we are yet to specify which files to build.gradle, especially in our case the Apache Commons Lang library.

Now, it is perfectly possible that you may one set of JAR files for compiling and maybe some additional files for testing and so on. For e.g. if you are compiling JUnit Test Cases and want to run them too, you might need to provide the JUnit JAR file under those circumstances. But under other situations for compiling your main source files, you may not need the JUnit JAR files.

To address this, Gradle has the concept of Confgiurations. A Configuration is simply a named set of dependencies. You can use them to declare the external dependencies of your project.

But what are these configurations and what are their names. It turns out that typically plugins will add a list of configurations that we can use to specify our dependencies. For the Java plugin, it adds several standard configurations that we can use to specify our dependencies. Some of these are:

  • compile
  • runtime
  • testCompile
  • testRuntime

I will quote the official documentation here:

compile

The dependencies required to compile the production source of the project.

runtime

The dependencies required by the production classes at runtime. By default, also includes the compile time dependencies.

testCompile

The dependencies required to compile the test source of the project. By default, also includes the compiled production classes and the compile time dependencies.

testRuntime

The dependencies required to run the tests. By default, also includes the compile, runtime and test compile dependencies.

Now, since we have to compile our Quote class that has a dependency on the Apache Commons Lang 3.3.2 , we add the following entry now to our build.gradle

apply plugin: 'java'
version = '1.0-FINAL'

repositories {
  mavenCentral()
}

dependencies {
  compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.3.2'
}

Some notes on the dependencies block:

  • Each dependency is defined separately.
  • You specify first the configuration name i.e. compile in our case. Then you mention the library via its group, name and version as earlier mentioned.
  • Currently there is only one compile time dependency shown. But we can add more dependencies too. Just add them on each line.
  • There is also a short form of specifying the dependency library. Instead of using group:value,name:value,version:value, you can just give the value in the form ‘group-value:name-value:version-value’. As an example, we could have rewritten the above dependencies as given below:
dependencies {
  compile 'org.apache.commons:commons-lang3:3.3.2'
}

Save this build.gradle and try running the gradle assemble command. This time, you will find that it will work by first downloading the JAR file from the Maven Central Repository, adding it to the local cache and then continuing with the compilation of the project.

 

Note (Very Important):
Make sure you are patient and you have a good working Internet connection, since Gradle looks in its local cache if you have already downloaded this library and version. If not, it will need to go to the Internet , access the Maven Central Repository, download it first and then continue with the build process. This process of doing a local check first and then downloading the artifacts is a major source of problem for most newcomers (I suffered from it!). The point is that if your dependencies are large for e.g. as we shall see in the later episodes (App Engine SDK), then it is a good 200 MB of download and you might just feel that the whole process has stopped working and has gone into a loop, whereas on the other hand, it is sincerely doing its job of downloading the JARs and any other transitive dependencies for you. 

Hope things are becoming a bit clear and you have been able to successfully build your Java project via Gradle and which has dependencies on external libraries.

Some more dependencies

Now that we have seen how to add a compile dependency, it makes sense to look at what we should do to add a test dependency. Remember that we can add our own JUnit Test cases. These test cases (Java classes) would be present in the src/test/java folder.

Recollect that the Java plugin added the following configurations to the Gradle project:

  • compile
  • runtime
  • testCompile
  • testRuntime

Now, we can easily see that we will need to add the JUnit JAR file dependency to the testCompile configuration. To do that, simply add your JUnit Test classes to the respective source directories and update your build.gradle so that it looks like this:

apply plugin: 'java'
version = '1.0-FINAL'

repositories {
  mavenCentral()
}

dependencies {
  compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.3.2'
  testCompile group: 'junit', name: 'junit', version: '4.+'
}

The format should look familiar. Just that you will notice one difference in the version. There is a sign instead of a specific version number. This is a hint to Gradle that it should go and fetch the latest version that is available.

Summing up

Hope you are getting the hang of Gradle now. We are barely scratching the surface in terms of its capabilities but you get the picture. I strongly recommend to go through the official documentation i.e. Gradle User Guide and more specifically the Java Quickstart  and Gradle Java plugin. I found repeated readings of this documentation very useful in my learning journey and I am still learning :-) I strongly recommend trying out this on your machine, since that will help you understand it more and provide you with ready templates that you can create for a variety of Java projects.

See you in the next episode, where we shall cover Part 3 : Building Multiple Java Projects with Dependencies, where we have one or more Java projects that are dependent on each other. For e.g. you write a library and the other Java project requires that. And moving forward, we will cover the Gradle War (Web Application Archive) plugin that helps with Java Web projects. Till then, Happy Gradling!

Posted in Tools | 3 Comments

Gradle Tutorial : Part 1 : Installation + Setup

To read an overview of this series, refer to the original blog post.

In this part of the tutorial, we shall focus on setting up Gradle on our system. While tools like Android Studio do ship with an internal Gradle distribution, our intention here is to understand the tools, its installation, the setup and firing up some basic Gradle commands.

Before we begin with that, if you are still wondering why Gradle is a good choice for build tools, I suggest that you read the following article. Though not essential to read it, it opens up your views as to why companies/developers are flocking to Gradle.

The next few sections will take you through setting up of Gradle on your machine. Gradle requires Java to be present on your machine. So, I shall assume that you are a Java developer and have setup the Java SDK on your machine. 

Download Gradle

At the time of writing, Gradle is in version 2.0 and is available for download here.

Just go ahead and download the ZIP file to your machine. You should have a file named gradle-2.0-all.zip. Expand it to a folder of your choice.

For e.g. on my machine, I have expanded the same in e:\gradle-2.0, such that I have the following sub-folders as shown below:

img3

 

You might ask why you need a separate installation of Gradle ? This would especially be on your mind if you have already downloaded Android Studio and worked with it. As you know, Android Studio ships with Gradle inside of it and no external installation of Gradle is required.

When we come to the later parts of this tutorial , where we will talk about Android Studio, we will use the Gradle distribution that comes along with it. The focus for all of us in this part and the next few lessons, will be on setting up our own setup of Gradle, running stuff from the command line and being as closed to the bare metal as possible, so that we understand what is going on. Later on, when Android Studio does these things, it will be much easier to understand what is going on ? And you will stop believing that Android Studio is doing some voodoo under the hood.

So for now, do download a separate Gradle installation as instructed and set it up.

 

Environment Settings

The \bin folder of your gradle distribution contains the gradle script file (both Unix and Windows) that you will use to run the gradle command along with various parameters.

Ideally, do the following:

  1. Create an environment variable GRADLE_HOME and point it to the Gradle Installation folder. On my machine, the Gradle installation folder is e:\gradle-2.0 and hence I have created a GRADLE_HOME Environment variable that has the value e:\gradle-2.0
  2. Add %GRADLE_HOME%\bin to the PATH environment variable. This will allow you to launch gradle command from any directory.

Verify Gradle Setup

To verify our setup, go to the command prompt / terminal and type the following:

gradle -v

This should display information about Gradle / versions and other information as shown below:

------------------------------------------------------------
Gradle 2.0
------------------------------------------------------------
Build time: 2014-07-01 07:45:34 UTC
Build number: none
Revision: b6ead6fa452dfdadec484059191eb641d817226c
Groovy: 2.3.3
Ant: Apache Ant(TM) version 1.9.3 compiled on December 23 2013
JVM: 1.7.0_40 (Oracle Corporation 24.0-b56)
OS: Windows 7 6.1 amd64

If you do not see information similar to the one above, check your installation of Gradle and ensure that you have set your PATH variable correctly that contains the direct %GRADLE_HOME%\bin as explained earlier.

A word about Groovy

Any discussion of Gradle is incomplete without Groovy. Groovy as you know is one of the most popular and powerful languages available on the JVM.

Some of the key reasons in favor of Gradle are:

  • It is less verbose
  • It is very flexible
  • It lets you configure and dictate things the way you want

Groovy plays a big role in making the above points happen. Unlike XML that is typically used in Ant and Maven, Groovy is a high level language that not only cuts down on the verbosity with its intuitive and productive syntax but it also gives you full programmatic power to tweak / specify things. All programming language advances like closures etc are available to you. And the build file that you typically ask Gradle to run is actually code that is running for you.

One question that could typically arise is “Do I need to know Groovy?” ? I am tempted to answer you do not. Unless you really want to stray away from convention and do things your own way, then you need to know Groovy because that is where the flexibility of Gradle comes in. But for all purposes, you can use various build.gradle templates that we shall look at and while it contains the Groovy DSL, you need not know much about it or for all you care, not know anything about it. 

So, while you do not have to know Groovy well to understand Gravel, it helps to know that the full power of Groovy is available to you, should you desire that.

Groovy is shipped with default with your Gradle distribution, so you do not have to separately download the same. 

Basic Gradle commands

We have not yet written any source code or build files (Gradle) and we will get to it in while. But try out the following on the command line:

gradle -q help

This command prints out basic help information for Gradle. The -q parameter is just for quiet mode in the console output. It is quite useful as you move along to see less verbose output.

gradle -q tasks

This shows a list of tasks that are already available to you. Give it a shot.

gradle properties

This will list of several properties that are preconfigured for you. You can definitely modify most of these properties in your build files. But it gives you a sense to the heavy duty work that Gradle is setting up for you prior to executing your tasks.

We are not yet going to get to compiling our Java code projects, etc. That is for the next part in this series. We are going to understand how Groovy brings the whole power of programming to Gradle.

To get started, let us first talk about the build.gradle file. This is the standard name used for our build file. All instructions that you need to give to Gradle are contained over here. Over the entire series, we will essentially work with build.gradle file to create / use all sorts of plugins/tasks that will help us compile, build , test and run our Java applications.

For now, let us try out the following (I leave it to you to use a directory of your choice to store the files/code as we move along):

In a folder of your choice, for e.g. example1, create a file named build.gradle.

Put the following as contents of the build.gradle file.

task compileTask << { 
    System.out.println "compiling..." 
}

Now, go to the command line and the folder in which you created the above build.gradle and give the following command

gradle -q tasks

This will list out various tasks that you can perform and you will notice in the output that apart from the standard tasks that you noticed, you also have the task that we created i.e. compileTask 

Other tasks
-----------
compileTask

This brings us to the first concept that our gradle build file is a series of tasks that we specify and which the gradle build system can execute for us. Currently the task that we have specified is named compileTask and what you see is the Groovy code where we just define the task code, where all we are doing is just doing a System.out.println. Remember that Groovy is a high level JVM language.

Now, what if we want to run the compileTask command ?

Before, we get to that, there is one more point to understand. When we fire the gradle command, it looks for a file named build.gradle in the current directory. If it finds one, it uses that. In the above case, since it found one, it determined what tasks are present in the file and added that to the list of tasks that it can perform.

So, what happens if we just type gradle with no other parameters nor do we specify any task to be execute. Let’s try that:

gradle

This will give the following output:

:help
Welcome to Gradle 2.0.
To run a build, run gradle <task> ...
To see a list of available tasks, run gradle tasks
To see a list of command-line options, run gradle --help
BUILD SUCCESSFUL
Total time: 2.39 secs

It is clearly telling you that you need to specify the task name when you run it i.e. gradle <task>. Let us do that by giving the following command:

gradle -q compileTask

This will output the text

compiling...

Let us enhance the build.gradle file with another task, so that it looks now like the following:

task compileTask << {
 System.out.println "compiling..." 
}

task buildTask << {
 System.out.println "building..."
}

Now, if you give the following command:

gradle -q tasks

You will find that both the tasks are listed in the otherTasks as shown below:

Other tasks
-----------
buildTask
compileTask

You can now run any of the tasks via gradle compileTask or gradle buildTask and so on.

What if we want to create a default task to be executed, so that if we do not specify the task name, it should execute that.

To do that, modify the build.gradle file as shown below:

defaultTasks 'buildTask'

task compileTask << {
  System.out.println "compiling..." 
}

task buildTask << {
  System.out.println "building..."
}

Now, if we simply say gradle -q , it will print the building… string output.

The last part to note here is dependency among tasks. What if we want to make the buildTask dependent on the compileTask, so that if the buildTask is run, it should always run the compileTask first.

To do that, modify the build.gradle file as shown below:

defaultTasks 'buildTask'

task compileTask << {
  System.out.println "compiling..." 
}

task buildTask (dependsOn:compileTask) << {
  System.out.println "building..."
}

Now, when you simply invoke gradle -q , it will show the following output:

compiling...
building...

What we have covered in this episode is the very basics of Gradle. Think of your build file as a series of tasks that need to be done. If you are a Java developer and have some experience of the build process (Ant, Maven) , you can easily relate to the fact that to build any stuff, we will need to do things like: compile, build, run tests, package , etc. These are nothing but tasks in Gradle.

We do not necessary have to write all these tasks by hand, though you could if you want to. By using convention that Gradle follows and plugins that work automagically off those conventions, we can perform the same series of steps that are required to build our projects.

There are plugins available in Gradle for e.g. Java plugin, WAR plugin, AppEngine plugin, Android plugin and so on, that expose predefined tasks that you can invoke. We shall see more of that, moving forward in this series.

Next Part

In the next part of the tutorial, we shall look at using Gradle to compile / build our Java projects.

Posted in Tools | 3 Comments

Announcing .. Gradle Tutorial Series

img2

Welcome to a new blog series where I aim to cover the basics of Gradle, the build tool that not just everyone is talking about but adopting widely. Companies, small and large have adopted this tool and while you might be familiar with Ant and Maven, it is time to take a look at Gradle.

The need for writing this series has come about primarily due to my work with a few Google related technologies/frameworks. I use the Google Cloud Platform widely for my projects (both professional and hobby) and have primarily used Eclipse as my IDE for both Cloud Projects (running on Google App Engine) and front-end mobile applications (Android). With Google putting its weight behind Android Studio, one of the things that hit me immediately when I try to use Android Studio was the fact that it used Gradle as its build tool.

My first experience with Android Studio and Gradle was one that cannot be described. I do not want to digress from the topic at hand, but let’s say that it was a difficult time to understand the exceptions, what Gradle is doing in the background and how to correctly set up dependencies of already existing projects. If you have been trying to play with Gradle, you know exactly what I mean. This series is my attempt to explain just about enough of Gradle so that you can get going with minimum fuss and save loads of time. In fact, I am confident that the more you use Gradle, the more you will appreciate the reasons for using it and which was not very apparent to me, the first time I experienced all those problems.

The series will be more task focused with just enough explanation for you to understand what is going on behind the scenes. I will spend less time on marketing Gradle, not will I go deep into reasons on why it works in a certain way. I will reference articles at the right places for those who wish to take a deeper dive. For the rest of us, who are interested in using Android Studio + Google Cloud Platform , we want to be as comfortable with the toolset, so that we can continue to build great applications and let Gradle do the heavy work of the mechanics that eventually result in binaries that we can give to the world.

This tutorial series will take you to a journey that covers the following:

  • Part 1 : Installation of Gradle and setting it up correctly on your system
  • Part 2 : Your first Java Project Build with Gradle
  • Part 3 : Multiple Java Projects with Gradle
  • Part 4 : Java Web Applications with Gradle
  • Part 5 : App Engine Gradle Plugin
  • Part 6 : Android Studio : Multi-Module Project builds with Gradle (This includes a Project that contains App Engine backends – Cloudpoints, Android App, Wear App, etc)

Some of these parts could go over into multiple parts, but at a high level, this is what I plan to cover. If you notice, the first 3 parts will focus on Gradle basics without getting into any specific Google stuff ( Google App Engine , Android, Android Studio IDE, etc).

To all Java Developers out there, lets rock the Gradle !

 

Posted in Tools | 1 Comment

Once Upon a Time in India : #1 – Khaled and his Didi song

Part of “Once Upon a Time in India Series“: 

The musician Cheb Khaled must have got the shock of his life and maybe he has still not recovered when his song titled “Didi” captured India in the 90s (1993-1994).  It fast became a song that got the crowd into a frenzy at any joyous gathering of people. And best of all, people who started dancing to this song were not even drunk at times. I also believe (could be wrong) that 99.99% of us did not understand even one word of what he was trying to say and could only pronounce “Didi”. Maybe that was the essence, all you had to do was just say “Didi” at some intervals in the song and  you were in !

It showed music had universal appeal and it surely adds to the confusion in the minds of everyone about “what succeeds in India”.

Anyways, enjoy the song :

Do give your comments on what you think should appear in this series. You will be credited for it. The essence of this series is captured here, so please read that.

P.S: The # in the title is just a number, not a ranking.

Posted in Personal | Leave a comment

New Series titled “Once Upon a Time in India”

As you grow older, you look back at some event or the other that happened across India, which is where I was born, brought up and live. These events typically captured the imagination of the nation and while they their influence was short-lived (typically), the hysteria that it generated was tremendous.

It is with that spirit, that I wish to capture some event and chronicle it .. well .. just for the sake of it. This event could be some sporting thing, or a music video, or a cartoon, or some comment / dialogue, a film, a song, a new technology .. almost anything.

jif_2009

You can write to me in the comments on whatever you believe caught our fancy .. and I hope to target those events for which we have some online content that can be linked to, so that the readers can relive and of course enjoy that moment. Ideally I am looking for something that has occurred in the 80s and 90s but still feel free to note and let me know otherwise. I will credit you with the link, if I publish it.

I do not promise the frequency at which this series will post stuff but it should help chronicle some key incidents.

The order of publication will be completely random and in no order of significance or craziness that it caused. I am also not interested in any political/terrorist/religious activity that caused suffering/pain and divisions. 

Maybe someone has already thought of such a series and it is there on the web (in fact it should be!) but still I don’t care. In the spirit of “Let’s do this”… we move forward.

So, sit back and enjoy.

Photo Credits : http://jaxindiafest.org/mission

 

Posted in Personal | 3 Comments

Book Review : Raspberry Pi Server Essentials

This is a book review for Packt Publishing‘s Raspberry Pi Server Essentials.

packt-rpi-server

Raspberry Pi is often touted as a boon for classroom computing. I have often seen scenarios where several folks have purchased a Raspberry Pi and after a few sessions with it have not utilized it much. Well sure the hobbyists are busy building sensor networks but most people need to understand how to employ their Pi for tasks that are likely to be more useful to them, in and around their computing needs.

This is where “Raspberry Pi Server Essentials” book comes in. It contains several chapters that help you to use your Pi for a specific purpose.

The initial chapters focus on the basics of setting up your Pi, Operating System installation/updates and setting up the networking. This forms a good base to then explore the remaining chapters.

The next set of chapter focus on a specific use of the Pi. The chapters range from:

  • Using the Pi as a Web Application Server
  • Setting up a File Server
  • Setting up a Game Server
  • Media Center
  • and even a Bit Coin mining machine (Hope you get lucky with that one!)

For households that have multiple devices, setting up a File Server or Game Server powered by your Pi is a great way to streamline things. In fact, you could jump to any chapter, if the specific purpose of that chapter is what you want to use your Pi with.

The instructions in each of the chapters are very precise. Right from downloading the software, configuring and running it, the instructions are good and focus just on the task, which is how it should be for a book of this kind.

Overall, this is a good book to explore practical uses that you could put to use immediately for your Pi.

Posted in Books, Personal, Reviews | Leave a comment