James Williams
LinkedInMastodonGithub

Building PlayN applications with Gradle

Tags: HTML5 Groovy

PlayN is a cross-platform game library that allows you to write Java code and build games for Desktop Java, HTML5 Browsers, and, Android. Rovio's AngryBirds used PlayN for the version that launched in the Chrome Web Store.

I've been messing around with PlayN ever since it was chuckle-inducingly named ForPlay. One of the things that bugged me a little bit was its embrace of Ant and Maven. Strategic because of the greater mindshare on Java no doubt but I very much prefer Gradle as a build system. It isn't constrained to Java as much as Ant and Maven are and doesn't require me to write miles-long command-line arguments or write XML.

In this post, we're going to set up a PlayN application to use Gradle for building and packaging code. This tutorial is going to assume that you have already got maven installed and have already built and installed PlayN. You could build it with Ant as well but that involves a bit more work. You can download my forked version of the PlayN Samples repo and follow along.

Install Gradle.

Gradle is a build tool that uses Ivy for dependency management, can integrate with Maven repositories, and is highly extensible. Gradle has plugins for many common Java ecosystem tasks such as creating a installable application, creating a WAR file, and compilation support for other JVM and non-JVM languages(Groovy, Scala, Clojure, and C++ among others). That means that you can take the time and learn one tool rather than many. And installation is super easy too. Just download, extract to somewhere on your path and you are good to go.

Organize your source files.

Unless you tell it otherwise, for a Java project, Gradle assumes that you are using a Maven style project directory structure (src/main/java, src/test/java, and the like). There wasn't much to do other that moving the images from src/main/java/.... to src/main/resources. This is easily configurable if you want to preserve the original structure.

Create your main build.gradle file.

Like Ant's build.xml file and Maven's pom.xml, Gradle has a special build file to control builds. The native programming language of the build.gradle file is Groovy. In addition to managing dependencies, you can create new tasks in code and create complex build logic. One of the most basic build files is listed below.

    apply plugin: 'java'

It tells Gradle to expose the build tasks in the Java plugin. To find out what tasks are available, simply run the following at a command prompt.

gradle tasks

Next we need to tell Gradle both what dependencies we have and where to find them. This is where our local Maven repository comes in.

subprojects {
  repositories {
    mavenRepo name:'Local', urls: "file://" + System.properties['user.home'] + "/.m2/repository"
    mavenCentral()
  }
  playN_version = '1.0.1'
}

We are telling Gradle to check the local Maven repository for dependencies first and if not found, look on Maven Central. If you'd prefer not to use the local repository, you could instead use a local directory. groupId and artifactId from Maven correspond to group and name in Gradle parlance. The subprojects keyword indicates that the included instructions will be shared between all subprojects. View the main build gradle file.

Create your settings.gradle file.

The settings.gradle file is where you declare what subprojects are present. If we were building only a single target and would never add any more, we could get away without having this file. But it is worth keeping modularity.

include "core", "java"

Create subproject build.gradle files.

We can see from the settings.gradle file that we have two more build files to create. Let's begin with the core project which is used by every other project. I grabbed the core dependencies from its pom.xml file. Gradle looks first in its repository, then to Maven or any other repositories we have set up to locate the files and their dependencies. The keyword in front of the Maven details is the phase for which this is a dependency. Many are available but you will mostly deal with compile or runtime.

playN_version = '1.0.1'

dependencies {
    compile (
        [group: 'com.googlecode.playn', name : 'playn-jbox2d', version: playN_version],
        [group: 'com.googlecode.playn', name : 'playn-core', version: playN_version],
        [group: 'com.threerings', name : 'tripleplay', version : '1.0']
    )
}

I'm now able to run gradle build to see my app get all the required dependencies and build. Let's move on to the java project, for creating a desktop Java game. It depends on the core project and has some desktop Java-specific APIs as show below.

dependencies {
  compile project(':core')
  compile group: 'com.googlecode.playn', name : 'playn-java', version: playN_version
}

I'd like to be able to run it straight from Gradle so let's start by applying the application plugin.

apply plugin: 'application'

Adding to the build file gives us access to the tasks: run, installApp, and distZip. Those tasks allow us to run, install, and distribute an archive of the application, respectively. So that Gradle knows what class to execute, we also need to add the following somewhere in the file:

mainClassName = 'playn.sample.hello.java.HelloGameJava'

Running gradle run gives us a Java Swing window with some cheerful spinning peas. We can even install it or zip it and the files will work. Here are the full core and java project build.gradle files.

Bonus: We can even run create Java desktop games with another JVM language like Groovy. Just drop in a some groovy files and add the following dependency and we're all set.

groovy group: 'org.codehaus.groovy', name: 'groovy', version: '1.7.10'

I've only explored using Gradle for a Java-only PlayN application. Check back in the future for updates on using Gradle to produce projects for the other PlayN targets.