Hi guys, I have the following scenario: I have th...
# wiremock-java
i
Hi guys, I have the following scenario: I have the following folder structure: -- wiremock --- src/main/java/org/company/wiremock/CustomHostTransformer.java ---src/main/resources/META-INF/services/com.github.tomakehurst.wiremock.extension.ResponseTransformerV2 --- pom.xml --- Dockerfile pom.xml looks like:
Copy code
<project xmlns="<http://maven.apache.org/POM/4.0.0>"
  xmlns:xsi="<http://www.w3.org/2001/XMLSchema-instance>"
  xsi:schemaLocation="<http://maven.apache.org/POM/4.0.0> <http://maven.apache.org/xsd/maven-4.0.0.xsd>">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.company</groupId>
  <artifactId>wiremock-transformer</artifactId>
  <version>1.0</version>

  <properties>
    <java.version>21</java.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.wiremock</groupId>
      <artifactId>wiremock-standalone</artifactId>
      <version>3.9.1</version>
    </dependency>
  </dependencies>
</project>
The docker file looks like:
Copy code
# -- Maven 'builder' stage
FROM maven:3.9.6-eclipse-temurin-21 AS builder
WORKDIR /home/builder
COPY pom.xml .
COPY src ./src

# Run Maven to build and package the custom transformer JAR
RUN mvn clean package

# -- WireMock 'runner' stage
FROM wiremock/wiremock:3.9.1 AS runner
WORKDIR /home/wiremock

# Copy the transformer JAR from the Maven builder stage to the WireMock extensions directory
COPY --from=builder /home/builder/target/wiremock-transformer-1.0.jar /home/wiremock/extensions/

# tmp
RUN apt-get update && apt-get install -y zip

# Set up WireMock to use the transformer
ENTRYPOINT ["/docker-entrypoint.sh", "--verbose", "--async-response-enabled=true", "--container-threads=1000", "--async-response-threads=500", "--disable-request-logging", "--extensions", "org.company.wiremock.CustomHostTransformer"]
My CustomHostTransformer.java looks like:
Copy code
package org.company.wiremock;

import com.github.tomakehurst.wiremock.extension.ResponseTransformerV2;
import com.github.tomakehurst.wiremock.http.Response;
import com.github.tomakehurst.wiremock.stubbing.ServeEvent;

public class CustomHostTransformer implements ResponseTransformerV2 {
  
  @Override
  public String getName() {
    return "custom-host-transformer";
  }

  @Override
  public Response transform(Response response, ServeEvent serveEvent) {
    System.out.println("CustomHostTransformer loaded!");
    return response;
  }
}
I have also added a service in META-INF/services/com.github.tomakehurst.wiremock.extension.ResponseTransformerV2. The content is:
Copy code
org.company.wiremock.CustomHostTransformer
I keep getting the following error when I try to run it:
Copy code
2024-09-12 13:59:55.187 Verbose logging enabled
Exception in thread "main" java.lang.ClassNotFoundException: org.company.wiremock.CustomHostTransformer
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(Unknown Source)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(Unknown Source)
	at java.base/java.lang.ClassLoader.loadClass(Unknown Source)
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Unknown Source)
	at com.github.tomakehurst.wiremock.extension.Extensions.loadClass(Extensions.java:223)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)
	at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(Unknown Source)
	at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
	at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(Unknown Source)
	at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Unknown Source)
	at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
	at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source)
	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source)
	at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source)
	at java.base/java.util.stream.ReferencePipeline.forEach(Unknown Source)
	at com.github.tomakehurst.wiremock.extension.Extensions.load(Extensions.java:80)
	at com.github.tomakehurst.wiremock.core.WireMockApp.<init>(WireMockApp.java:108)
	at com.github.tomakehurst.wiremock.WireMockServer.<init>(WireMockServer.java:74)
	at com.github.tomakehurst.wiremock.standalone.WireMockServerRunner.run(WireMockServerRunner.java:71)
	at wiremock.Run.main(Run.java:23)
Any insights? I also tried to log into the shell to see if all the files are present, see:
Copy code
❯ docker run --rm -it --entrypoint sh wiremock-with-custom-transformer
# ls
extensions  __files  mappings
# cd extensions
# ls
wiremock-transformer-1.0.jar
# unzip wiremock-transformer-1.0.jar
Archive:  wiremock-transformer-1.0.jar
   creating: META-INF/
  inflating: META-INF/MANIFEST.MF
   creating: org/
   creating: org/company/
   creating: org/company/wiremock/
   creating: META-INF/services/
   creating: META-INF/maven/
   creating: META-INF/maven/org.company.wiremock/
   creating: META-INF/maven/org.company.wiremock/wiremock-transformer/
  inflating: org/company/wiremock/CustomHostTransformer.class
  inflating: META-INF/services/com.github.tomakehurst.wiremock.extension.ResponseTransformerV2
  inflating: META-INF/maven/org.company.wiremock/wiremock-transformer/pom.xml
  inflating: META-INF/maven/org.company.wiremock/wiremock-transformer/pom.properties
t
Since you’ve added the service metadata to the extension you should drop the
--extensions
CLI parameter otherwise it’ll try to load it twice.
i
I tried that, but it then does not pick the extension 😞
The same result when I remove the service metadata and add the
--extentions
flag
t
Sounds like either the extension isn’t landing in the extensions directory, or for some reason the command line has changed and that directory isn’t on the classpath at startup
Suggest shelling into the running docker container then you can look at whether your extension is there and run
ps
to check the command line