Month: September 2017

Integrating ErrorProne and NullAway with an Android project

2017-09-15 Android, Gradle, Java, Static Code Analysis No comments

Recently, with the remote help of guys from Uber in California, I integrated NullAway and ErrorProne with the one of my open-source Android projects.

What is NullAway?

Basically, it’s a tool to help eliminate NullPointerExceptions (NPEs) in your Java code. It detects situations where NPE could occur at the compile time.

Let’s have a look at the following code:

static void log(Object x) {
    System.out.println(x.toString());
}
static void foo() {
    log(null);
}

NullAway will find out that we’re passing null and we’ll get appropriate error message:

warning: [NullAway] passing @Nullable parameter 'null' where @NonNull is required
    log(null);
        ^

It’s good to have checks like that because they eliminate possible bugs in advance and follows Clean Code principles.

A few words about ErrorProne

NullAway is built as a plugin to ErrorProne and can run on every single build of our code. Moreover, ErrorProne can perform other checks on our code, which can find out commonly people mistakes. E.g. it can detect a situation, where programmer forgot to add @Test annotation in the unit test method in a test suite and other things. It has built-in bug patterns, which are used during code analysis.

Integration with the Android project

I’ve integrated ErrorProne and NullAway with ReactiveNetwork Android library.

First, in the main build.gradle file, I’ve added the following lines:

ext.deps = [
            ...
            nullaway          : 'com.uber.nullaway:nullaway:0.1.2',
            errorprone        : 'com.google.errorprone:error_prone_core:2.1.1',
            ...
            ]

buildscript {
  repositories {
    jcenter()
    maven {
      url 'https://plugins.gradle.org/m2/'
    }
  }
  dependencies {
    ...
    classpath 'net.ltgt.gradle:gradle-errorprone-plugin:0.0.11'
    classpath 'net.ltgt.gradle:gradle-apt-plugin:0.11'
    // NOTE: Do not place your application dependencies here; they belong
    // in the individual module build.gradle files
  }
}

Next, in the library/build.gradle file, I’ve added appropriate plugins in the top:

apply plugin: 'net.ltgt.errorprone'
apply plugin: 'net.ltgt.apt'

Afterwards, I could add dependencies:

dependencies {
  ...

  annotationProcessor deps.nullaway
  errorprone deps.errorprone
}

The last thing to do, is the task responsible for running analysis during project compilation:

tasks.withType(JavaCompile) {
  if (!name.toLowerCase().contains("test")) {
    options.compilerArgs += ["-Xep:NullAway:ERROR", "-XepOpt:NullAway:AnnotatedPackages=com.github.pwittchen.reactivenetwork"]
  }
}

That’s it! Now, I could run analysis by typing:

./gradlew check

and fix the issues.

I think, a quite similar approach and configuration could be applied to a regular, pure Java project built with Gradle.

If you’re interested in the complete configurations, check it out in my project at: https://github.com/pwittchen/ReactiveNetwork.
You can also view Pull Request #226 made by @msridhar (kudos for him!).

Building and running SAP Hybris Commerce Platform via Gradle

2017-09-01 Gradle, Hybris 1 comment

Introduction

I really like Gradle build system for JVM apps. It has flexibility like Ant and great dependency management capabilities like Maven. It addition, it doesn’t use XML notation, but Groovy programming language, so builds configurations are simple, concise, easier to read and easier to create. In my opinion, Gradle is truly modern build system for JVM apps. Nevertheless, there are projects, which are pretty old and use older systems like Ant. For example, all Hybris projects are based on Ant. Moreover, they have their custom setup and configurations, internal extensions system, etc. I was wondering if it’s possible to migrate Hybris Platform build from Ant to Gradle. That’s why I created a simple Proof of Concept.

Migrating from Ant to Gradle

If we want to use Gradle, we need to install it first.

sudo apt-get install gradle         # if we're on Ubuntu Linux
brew install gradle                 # if we're on macOS

For more details and instructions for other systems, check official Gradle installation guide.

Then, we need to go to our Hybris platform directory and navigate to hybris/bin/platform

After that, we need to initialize gradle inside this directory by running gradle command.
Next, we need to create gradle wrapper by running gradle wrapper command.
Now we should have the following elements in our directory:

  • .gradle (directory)
  • graldew (wrapper file for Unix)
  • gradlew.bat (wrapper file for Windows)

Afterwards, we can create build.gradle configuration file.

It should have the following contents:

ant.importBuild 'build.xml'
apply plugin: 'java'

repositories {
  jcenter()
}

task run() {
  doLast {
     exec {
          executable "./hybrisserver.sh"
      }
  }
}

task cleanGeneratedDirs(type: Delete) {
  delete "../../data"
  delete "../../log"
  delete "../../roles"
  delete "../../temp"
}

task cleanConfig(type: Delete) {
  delete "../../config"
}

dependencies {
  compile fileTree(dir: 'lib', include: ['*.jar'])
}

Now, we can execute the following command:

./gradlew clean build

and platform will be built.

In order to initialize the platform, we can call:

./gradlew initialize

If we want to start the Hybris server, we can simply call:

./gradlew run

To clear directories generated during build and initialization, we can run:

./gradlew cleanGeneratedDirs

I tried to make clean task dependent on this one, but I got a few errors and didn’t spend too much time on investigating them.

As you probably noticed, this solution is just a wrapper around Ant build defined in build.xml file and it’s not pure Gradle build configuration. Nevertheless, these tips may be useful for the people who need to have custom build configurations and dependencies. There’s no doubt that creating and maintaining configurations via Gradle is much easier and more convenient than doing the same job via Ant.

Summary

As we can see, it’s possible to migrate Hybris build from Ant to Gradle, but please remember that Hybris has a custom setup and it may not be the best decision in each case. We should always consider pros and cons of such solution and adjust it to our needs. In legacy systems, we often have to stick to existing setups because making “revolution” may be a huge overhead and doesn’t have to pay off. Moreover, all Hybris extensions also have build configurations based on Ant. On the other hand, I can highly recommend Gradle for greenfield JVM projects.

References

There’s another nice, short article describing migrating Java projects from Ant to Gradle: Easily Convert from Ant to Gradle (objectpartners.com).