Packaging Wiremock Extensions into the Standalone Server Runner

Featured image for sharing metadata for article

The Wiremock project is pretty great for stubbing out HTTP services. It has a powerful Extensions API which allows writing custom code to perform additional transformation of the responses that are sent to a caller.

These extensions can be packaged and released as their own artefacts for others to use, and consumed as part of the build.

If you're deploying Wiremock to i.e. an AWS EC2 or into a container, you may want to package a standalone JAR for Wiremock which contains all the dependencies it could need, including extensions.

This makes sure you don't have to collect classpaths on the receiving end, and can instead be sure that your packaged JAR has everything it'll need to operate, allowing us to run the following to execute it with the extension(s) we want to add:

java -jar with-extension/build/libs/with-extension.jar --extensions me.jvt.hacking.wiremock.extensions.HelloWorldHeaderExtension

This is produced using the following build.gradle:

plugins {
  id "com.github.johnrengelman.shadow" version "7.0.0"
  id 'java'

project.ext {
  wiremockVersion = '2.31.0'

dependencies {
  runtimeOnly "com.github.tomakehurst:wiremock-jre8-standalone:$wiremockVersion"
  implementation "com.github.tomakehurst:wiremock-jre8:$wiremockVersion"

shadowJar {
  mergeServiceFiles() //
  archiveClassifier.set '' // as this defaults to a separate artifact, called `-all`

jar {
  manifest {
    attributes 'Main-Class': 'com.github.tomakehurst.wiremock.standalone.WireMockServerRunner'

assemble.dependsOn 'shadowJar'

This can be seen in this sample project, including the definition for the custom HelloWorldHeaderExtension.

Note that if we don't have the mergeServiceFiles, we then receive the following exception:

Exception in thread "main" java.lang.ExceptionInInitializerError
        at org.eclipse.jetty.http.MimeTypes$Type.<init>(
        at org.eclipse.jetty.http.MimeTypes$Type.<clinit>(
        at org.eclipse.jetty.http.MimeTypes.<clinit>(
        at com.github.tomakehurst.wiremock.jetty9.JettyHttpServer.addMockServiceContext(
        at com.github.tomakehurst.wiremock.jetty9.JettyHttpServer.createHandler(
        at com.github.tomakehurst.wiremock.jetty94.Jetty94HttpServer.createHandler(
        at com.github.tomakehurst.wiremock.jetty9.JettyHttpServer.<init>(
        at com.github.tomakehurst.wiremock.jetty94.Jetty94HttpServer.<init>(
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(
        at java.lang.reflect.Constructor.newInstance(
        at com.github.tomakehurst.wiremock.jetty9.JettyHttpServerFactory.buildHttpServer(
        at com.github.tomakehurst.wiremock.WireMockServer.<init>(
        at com.github.tomakehurst.wiremock.standalone.WireMockServerRunner.main(
Caused by: java.lang.ArrayIndexOutOfBoundsException: 1
        at org.eclipse.jetty.http.PreEncodedHttpField.<clinit>(
        ... 16 more

Written by Jamie Tanna's profile image Jamie Tanna on , and last updated on .

Content for this article is shared under the terms of the Creative Commons Attribution Non Commercial Share Alike 4.0 International, and code is shared under the Apache License 2.0.

#blogumentation #java #gradle #wiremock.

This post was filed under articles.

Interactions with this post

Interactions with this post

Below you can find the interactions that this page has had using WebMention.

Have you written a response to this post? Let me know the URL:

Do you not have a website set up with WebMention capabilities? You can use Comment Parade.