In the previous Gradle series post we built Wrapper to execute Gradle tasks without installed version on your machine. It’s time to write some code and make our project useful. In this post Gradle will help us to start a web server.

To make it happened we need:

Dropwizard

All the aspects related with providing readable RESTful API via reliable Web Server are covered by Dropwizard. These folks give all of these nice features for us:

  • Jetty – lighweight Java Web Server
  • Jersey – building RESTful web applications (JAX-RS implementation)
  • Jackson – parsing JSON data format
  • Metrics – measure app performance
  • and more!

To start using all of above features you must add Dropwizard core as a dependency to the project:

apply plugin: 'java'
sourceCompatibility = 1.8
project.ext {
dropwizardVersion = '0.8.2'
}
repositories {
mavenCentral()
}
dependencies {
compile group: 'io.dropwizard', name: 'dropwizard-core', version: dropwizardVersion
}

view raw
build.gradle
hosted with ❤ by GitHub

Configuration

It stores all the project and environment related settings. Our simple configuration contains just one field: appName

package com.karollotkowski.cleancode;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.dropwizard.Configuration;
import org.hibernate.validator.constraints.NotEmpty;
public class AppConfiguration extends Configuration {
@NotEmpty
private String appName;
@JsonProperty
public String getAppName() {
return appName;
}
@JsonProperty
public void setAppName(final String appName) {
this.appName = appName;
}
}

@NotEmpty annotation will assure that application will not start if appName value will be not defined.

@JsonProperty allows to deserialise and serialise from a YAML property.

Let’s add YAML configuration file with property appName and value equals ‘Clean code rulez!

appName: Clean code rulez!

view raw
app_config.yml
hosted with ❤ by GitHub

I placed config file in the new directory config at the top project level.

Application

The last Dropwizard part is to create a new Application class to start web server with simple logic.

package com.karollotkowski.cleancode;
import io.dropwizard.Application;
import io.dropwizard.setup.Environment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CleanCodeApplication extends Application<AppConfiguration> {
public static final Logger LOGGER = LoggerFactory.getLogger(CleanCodeApplication.class);
public static void main(final String[] args) throws Exception {
new CleanCodeApplication().run(args);
}
@Override
public void run(final AppConfiguration configuration, final Environment environment)
throws Exception {
LOGGER.info("Application name: {}", configuration.getAppName());
}
}

This class is using our Configuration class and is a main entry point to the application. To run the app we just need a main method to start a run method which starts a web server as a process.

During spin on the Dropwizard we should see appName value in the logs:

LOGGER.info("Application name: {}", configuration.getAppName());

To start web server I will use Gradle plugin.

Gradle Application plugin

Gradle provides Application plugin to create an executable JVM application. This plugin contains java and distribution plugins.

At this moment we can replace standard java plugin with application plugin.

apply plugin: 'application'

After refresh you should see 2 new sections on Gradle tasks list: Application and Distribution

Application tasks
-----------------
installApp - Installs the project as a JVM application along with libs and OS specific scripts.
run - Runs this project as a JVM application

Distribution tasks
------------------
assembleDist - Assembles the main distributions
distTar - Bundles the project as a distribution.
distZip - Bundles the project as a distribution.
installDist - Installs the project as a distribution as-is.

We will use run task to start application. This task needs full name of the main class to execute and execution parameters:

mainClassName = "com.karollotkowski.cleancode.CleanCodeApplication"
project.ext {
    configPath = "$rootProject.projectDir/config/"
}
run {
 args 'server', configPath + 'app_config.yml'
}

Full build.gradle file with Dropwizard and Gralde plugin settings:

apply plugin: 'application'
sourceCompatibility = 1.8
project.ext {
configPath = "$rootProject.projectDir/config/"
dropwizardVersion = '0.8.2'
}
repositories {
mavenCentral()
}
dependencies {
compile group: 'io.dropwizard', name: 'dropwizard-core', version: dropwizardVersion
}
mainClassName = "com.karollotkowski.cleancode.CleanCodeApplication"
run {
args 'server', configPath + 'app_config.yml'
}

view raw
build.gradle
hosted with ❤ by GitHub

Spin on web server

All the stuff is ready to start a server. Execute run Gradle task from cmd or IDE:

$ ./gradlew run

Output should looks similar to this:

:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:run
INFO [2015-10-13 22:28:52,049] org.eclipse.jetty.util.log: Logging initialized @2319ms
INFO [2015-10-13 22:28:52,297] com.karollotkowski.cleancode.CleanCodeApplication: Application name: Clean code rulez!
INFO [2015-10-13 22:28:52,305] io.dropwizard.server.ServerFactory: Starting CleanCodeApplication
INFO [2015-10-13 22:28:52,498] org.eclipse.jetty.setuid.SetUIDListener: Opened application@75d0911a{HTTP/1.1}{0.0.0.0:8080}
INFO [2015-10-13 22:28:52,499] org.eclipse.jetty.setuid.SetUIDListener: Opened admin@75e91545{HTTP/1.1}{0.0.0.0:8081}
INFO [2015-10-13 22:28:52,504] org.eclipse.jetty.server.Server: jetty-9.2.9.v20150224
INFO [2015-10-13 22:28:53,415] io.dropwizard.jersey.DropwizardResourceConfig: The following paths were found for the configured resources:
NONE
INFO [2015-10-13 22:28:53,423] org.eclipse.jetty.server.handler.ContextHandler: Started i.d.j.MutableServletContextHandler@4d4960c8{/,null,AVAILABLE}
INFO [2015-10-13 22:28:53,431] io.dropwizard.setup.AdminEnvironment: tasks =
POST /tasks/log-level (io.dropwizard.servlets.tasks.LogConfigurationTask)
POST /tasks/gc (io.dropwizard.servlets.tasks.GarbageCollectionTask)
WARN [2015-10-13 22:28:53,432] io.dropwizard.setup.AdminEnvironment:
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! THIS APPLICATION HAS NO HEALTHCHECKS. THIS MEANS YOU WILL NEVER KNOW !
! IF IT DIES IN PRODUCTION, WHICH MEANS YOU WILL NEVER KNOW IF YOU'RE !
! LETTING YOUR USERS DOWN. YOU SHOULD ADD A HEALTHCHECK FOR EACH OF YOUR !
! APPLICATION'S DEPENDENCIES WHICH FULLY (BUT LIGHTLY) TESTS IT. !
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
INFO [2015-10-13 22:28:53,442] org.eclipse.jetty.server.handler.ContextHandler: Started i.d.j.MutableServletContextHandler@5d39f2d8{/,null,AVAILABLE}
INFO [2015-10-13 22:28:53,475] org.eclipse.jetty.server.ServerConnector: Started application@75d0911a{HTTP/1.1}{0.0.0.0:8080}
INFO [2015-10-13 22:28:53,477] org.eclipse.jetty.server.ServerConnector: Started admin@75e91545{HTTP/1.1}{0.0.0.0:8081}
INFO [2015-10-13 22:28:53,477] org.eclipse.jetty.server.Server: Started @3749ms

view raw
Dropwizard.log
hosted with ❤ by GitHub

As you see there is an appName variable value:

INFO  [2015-10-13 22:28:52,297] com.karollotkowski.cleancode.CleanCodeApplication: Application name: Clean code rulez!

Dropwizard started two services: