Getting started with JAX-RS & Gradle

Managed to waste an hour of my life today, trying to set up a JAX-RS + Gradle project. Gradle wasn’t really the problem, nor was JAX-RS, but putting it all together in a way that works took longer than expected.

So without further ado, I present to you a simple quickstart project you can use to kickstart JAX-RS + Gradle projects.

The Gradle build file is pretty minimalistic. There’s no need for web.xml. And I’ve included an example resource.


description = 'JAX-RS Quickstart'
group = ''
version = '1.0-SNAPSHOT'
apply plugin: 'java'
apply plugin: 'eclipse'
sourceCompatibility = 1.8
repositories {
buildscript {
        repositories {
        dependencies {
                // Embedded Jetty 9 Gradle Plugin
                classpath (group: 'com.sahlbach.gradle', name: 'gradle-jetty-eclipse-plugin', version: '1.9.+')
apply plugin: 'jettyEclipse'
apply plugin: 'war'
dependencies {
        // JAX-RS 2.0(.1)
        compile ''
        // Jersey 2.15
        compile 'org.glassfish.jersey.containers:jersey-container-servlet:2.15'
        // Servlet 3
        compile 'javax.servlet:javax.servlet-api:3.1.0'

Extra quick quickstart:

git clone
cd jax-rs-quickstart
gradle jettyEclipseRun

Gradle gotcha: duplicate project names

Assume the following project structure:

│   ├── Foo
│   │   ├── build.gradle
│   ├── Bar
│   │   ├── build.gradle
│   ├── Foo
│   │   ├── build.gradle
│   ├── Quf
│   │   ├── build.gradle

I don’t think this is a terribly unreasonable structure: we have a product with a bunch of features, and each feature is split into a couple of modules. This works just fine in gradle. As long as FeatureB/Foo doesn’t have a dependency on FeatureA/Foo. Gradle doesn’t seem to be terribly fond of multi-module projects. At least not when you have a deeper, nested structure.

As soon as FeatureB/Foo has a dependency on FeatureA/Foo, gradle goes belly up. It won’t tell you, though. It’ll just quietly carry on. It won’t resolve the dependency, and you’ll end up with compile errors.


dependencies {
	compile project(':FeatureA:Foo')

The reason is actually quite simple. Gradle uses the directory name as the project name. Instead of looking at the whole path in the tree, which would be a lot more sensible, it just looks at the last leaf in the tree. So we have two projects named Foo, and gradle chokes. Not giving an error/warning strikes me as a bug, though, but still. Not terribly unreasonable.

Thankfully, there’s a fix. It involves renaming your projects via settings.gradle in the root project:


// List our projects/subprojects
include ':FeatureA:Foo'
include ':FeatureA:Bar'
include ':FeatureB:Foo'
include ':FeatureB:Quf'
// Rename each child project to its path: Foo becomes FeatureA-Foo or FeatureB-Foo, depending on the Foo.
rootProject.children.each { p ->
        p.children.each { module ->
       = + '-' +

Now you can add a project dependency and things will Just Work™:

dependencies {
	compile project(':FeatureA:FeatureA-Foo')

All fixed. Much better.