- Overview
- How it Works
- Requirements
- How to Use - Docker
- How to Use - Standalone JAR (CLI)
- Local Development
- Examples
- License
wiremock-docker-easy-extensions is a toolkit designed to simplify building and running custom extensions with the official WireMock Docker image.
Its main purpose is to expose a ready to use service that packages provided extensions on the fly and spins upWireMock
with them, along with the necessary mappings and files.
When using the WireMock Docker image, adding custom extensions requires you to:
- Package your extension(s) as a JAR, ensuring all dependencies are included.
- Ensure the JAR is built to run with Java 11, as the base WireMock image uses a JRE 11.
- Place the JAR in the correct location and configure WireMock to load it.
This project automates these steps by dynamically generating a dedicated Gradle project, building the extensions to target JVM 11, and packaging them into a single JAR that is then fed to a running WireMock instance.
For more information on creating extensions, see the official WireMock documentation.
The tool follows these steps:
- Reads a
wdee-config.yamlfile. - Dynamically creates a temporary Gradle project.
- Copies your extension source code into this new project.
- Generates a
build.gradle.ktsfile configured to target JVM 11 and include any specified dependencies. - Builds this project to produce a single JAR containing your extensions, their dependencies and a Java ServiceLoader as WireMock requires this to discover extension classes.
- Starts WireMock, automatically loading the newly created JAR.
In order to use this tool, there will need to be a directory with the following structure:
aDirectory/
├── __files/ # (Required) Directory for WireMock `__files` files.
│ └── response.json # (Optional) If provided, it will be copied to the WireMock container's `__files` directory
├── extensions/ # Contains extension source code. Classes can also be in the parent directory.
│ ├── AJavaClass.java
│ └── AKotlinClass.kt
├── mappings/ # (Required) Directory for WireMock `mappings` files.
│ └── requests.json # (Optional) If provided, it will be copied to the WireMock container's `mappings` directory - worth noting that if there are no mappings, WireMock will not serve any responses.
└── wdee-config.yaml # (Required) Defines extensions, dependencies, and source locations.
# (Required) The location of the extension classes relative to the parent directory where `wdee-config.yaml` is located.
# If the classes are in the same directory as `wdee-config.yaml`, this can be set to "", ".", "/", "./" according to preference.
source-files-location: extensions
# (Required - cannot be empty) A list of fully qualified class names of the extensions to be included in the JAR.
source-files:
- your.package.package1.AJavaClass.java
- your.package.package2.AKotlinClass.kt
# (Required - can be empty) A list of dependencies required to run the classes.
dependencies:
- org.apache.commons:commons-lang3:3.18.0
# (Optional) Used to provide configs for the WireMock Docker image spin up via CLI `run` command.
jar-run-config:
# (Optional) The name of the Docker container that will be created. Defaults to `wiremock-docker-easy-extensions`.
docker-container-name: wiremock-docker-easy-extensions
# (Optional) The port that Docker will expose for WireMock. Defaults to `8080`.
docker-port: 8080
# (Optional - can be empty) List of WireMock CL Commands (need to be valid WireMock CL Commands). Defaults to an empty list.
wiremock-cl-options:
- --verbose
- --record-mappings-
Supported Languages: Extensions can be written in either Java or Kotlin.
-
Java 11 Compatibility: The provided source code must be compatible with Java 11. The builder tool compiles the code to target the JVM 11 runtime, which is used by the official WireMock Docker image. This means that language features from newer Java versions are not supported.
-
Example of an Incompatible Feature: Using Java's
recordkeyword will cause the build to fail, as it was introduced after Java 11.// This will fail to compile public record User(String name, int age) {}
The primary way to use this tool is via the pre-built Docker image. This method allows you to build and run your extensions without needing to install Java or Gradle locally.
The image is published to the GitHub Container Registry. The following tags are available:
latest: Points to the most recent stable (non-pre-release) version.X.Y.Z(e.g.,1.0.0): A specific release version.X.Y(e.g.,1.0): The latest release within a minor version range.X(e.g.,1): The latest release within a major version range.main: The latest build from themainbranch. This is a development version and may be unstable.
The Docker image is designed to read the directory structure from a mounted local directory. This directory must be
mounted into /home/config/(name-of-your-root-directory) inside the container.
For the example above, where the root directory is aDirectory, you would mount it to /home/config/aDirectory.
docker run -p 8080:8080 \
-v ./aDirectory:/home/config/aDirectory \
ghcr.io/alfonsoristorato/wiremock-docker-easy-extensions:latestservices:
wiremock-docker-easy-extensions:
image: ghcr.io/alfonsoristorato/wiremock-docker-easy-extensions:latest
container_name: wiremock-with-runtime-extensions
ports:
- "8080:8080"
volumes:
- ./aDirectory:/home/config/aDirectoryWith this setup, any changes to your local source files will be picked up the next time the container is restarted, triggering a new build of your extension JAR automatically.
- Because the tool needs both jdk and gradle, which are not available in the official WireMock Docker image, they are bundled together in this image, making it larger than the official WireMock image, but this setup allows for a faster startup as all dependencies to run the tool are already included.
- Because this tool builds the extensions JAR at runtime, to then feed to WireMock, it will take about 30 seconds to start every time you run the Docker image. This is because it needs to compile the source files and package them into a JAR.
For users who prefer to run the tool directly without Docker commands (the final result will still be a Docker image that spins up), the executable JAR is available for download from the project's GitHub Releases page.
This method is useful for local testing or for integrating the tool into custom scripts.
-
Download the JAR: Use
curlto download the JAR from the latest release.REPO_NAME="alfonsoristorato/wiremock-docker-easy-extensions" JAR_NAME="wiremock-docker-easy-extensions.jar" LATEST_VERSION=$(curl -s https://api.github.com/repos/$REPO_NAME/releases/latest | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') JAR_URL="https://github.com/$REPO_NAME/releases/download/${LATEST_VERSION}/${JAR_NAME}" curl -L -o $JAR_NAME $JAR_URL
-
Run the tool: Once downloaded, you can execute it using
java -jar. The tool provides two main commands:buildandrun.# Build the extension JAR without starting WireMock java -jar wiremock-docker-easy-extensions.jar build aDirectory/wdee-config.yaml# Build the JAR and immediately run WireMock in a Docker container java -jar wiremock-docker-easy-extensions.jar run aDirectory/wdee-config.yaml
This section is for those who wish to build the wiremock-docker-easy-extensions tool itself.
- Docker
- Java 21
- Gradle
The first step is to build the executable JAR for the builder tool.
./gradlew build -x testThis will create the JAR at build/libs/wiremock-docker-easy-extensions.jar.
To build the extension JAR without running WireMock:
java -jar build/libs/wiremock-docker-easy-extensions.jar build <path-to-your-config>.yamlIf successful, the bundled JAR will be located at build/extensions/wiremock-extensions-bundled.jar.
To build the JAR and immediately run it with WireMock in a Docker container:
java -jar build/libs/wiremock-docker-easy-extensions.jar run <path-to-your-config>.yamlBecause some e2e tests require a docker image to exist, there is a Gradle task that builds the image, make sure you run this at least once (or more if you are doing major changes and want them tested before CI).
./gradlew buildDockerImageForE2ETestsThen, to run all tests:
./gradlew testThe examples directory contains a fully functional sample setup that follows the required directory structure and
demonstrates how to use this tool, combining both traditional WireMock usage with the noExtension mapping and its
usage with extensions.
There are three example extensions in examples/extensions:
ResponseTransformerExtensionNoDependenciesJava.java: A simple transformer in Java.ResponseTransformerExtensionNoDependenciesKotlin.kt: A simple transformer in Kotlin.ResponseTransformerExtensionWithDependenciesKotlin.kt: A Kotlin transformer that uses an external dependency (org.apache.commons:commons-lang3).
The example config file is set up to:
- Read the source files from the
extensionsdirectory. - Include the
commons-lang3dependency.
The examples/mappings/requests.json file defines three stub mappings. Each mapping targets a specific URL and uses one of the custom response transformers. For example:
{
"request": {
"method": "GET",
"url": "/ResponseTransformerExtensionNoDependenciesKotlin"
},
"response": {
"status": 200,
"transformers": [
"ResponseTransformerExtensionNoDependenciesKotlin"
]
}
}-
Build the tool:
./gradlew build
-
Run the example: Use the
runcommand with the example configuration file. This will build the extension JAR and start the WireMock container in one step.java -jar build/libs/wiremock-docker-easy-extensions.jar run examples/wdee-config.yaml
-
Test with IntelliJ's HTTP Client: Open the examples/requests.http file in IntelliJ IDEA. This file contains requests for each of the configured endpoints. Click the "run" icon next to each request to send it to the running WireMock instance.
For example, a
GETrequest tohttp://localhost:8080/ResponseTransformerExtensionNoDependenciesJavawill return a response with the bodyResponse from ResponseTransformerExtensionNoDependenciesJava.
Steps 1 and 2 can also be executed using the provided IntelliJ run configuration:
This project is licensed under the Apache License 2.0, following the same license as WireMock itself.
