🍃
Spring Boot 4でwiremock-jetty12を使うときの注意点
環境
- Spring Boot 4.0.1
- wiremock-jetty12 3.13.2
今後のバージョンアップにより、本記事の対応が不要になる可能性があります。
発生した問題
普通にpom.xmlを記述した。
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>4.0.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>sample-function</artifactId>
<version>1.0.0</version>
<properties>
<java.version>25</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-restclient</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-restclient-test</artifactId>
<scope>test</scope>
</dependency>
<!-- WireMock -->
<dependency>
<groupId>org.wiremock</groupId>
<artifactId>wiremock-jetty12</artifactId>
<version>3.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<!-- (以下略) -->
</project>
WireMockを使ったテストを書いた。
SampleClientTest.java
@SpringBootTest
class SampleClientTest {
@RegisterExtension
static WireMockExtension wireMock = WireMockExtension.newInstance()
.options(wireMockConfig()
.port(9999)
).build();
@Autowired
SampleClient sampleClient;
@Nested
@DisplayName("getMessage()")
class GetMessage {
@Test
@DisplayName("200: メッセージを取得できる")
void success() {
// WireMock設定
stubFor(get("/api/message")
.willReturn(aResponse()
.withStatus(200)
.withHeader("Content-Type", "application/json")
.withBody("""
{"message":"Hello!"}
""")
)
);
// 実行
SampleResponse actual = sampleClient.getMessage();
// 検証
assertEquals(new SampleResponse("Hello!"), actual);
}
}
}
テストを実行すると、次のような例外になった🫠
実行結果
Test ignored.
Test ignored.
java.lang.NoSuchMethodError: 'org.eclipse.jetty.util.component.Environment org.eclipse.jetty.util.component.Environment.ensure(java.lang.String)'
at org.eclipse.jetty.ee10.servlet.ServletContextHandler.<clinit>(ServletContextHandler.java:135)
at com.github.tomakehurst.wiremock.jetty12.Jetty12HttpServer.addAdminContext(Jetty12HttpServer.java:256)
at com.github.tomakehurst.wiremock.jetty12.Jetty12HttpServer.createHandler(Jetty12HttpServer.java:195)
at com.github.tomakehurst.wiremock.jetty.JettyHttpServer.<init>(JettyHttpServer.java:101)
at com.github.tomakehurst.wiremock.jetty12.Jetty12HttpServer.<init>(Jetty12HttpServer.java:74)
at com.github.tomakehurst.wiremock.jetty12.Jetty12HttpServerFactory.buildHttpServer(Jetty12HttpServerFactory.java:33)
at com.github.tomakehurst.wiremock.WireMockServer.<init>(WireMockServer.java:75)
at com.github.tomakehurst.wiremock.junit5.WireMockExtension.startServerIfRequired(WireMockExtension.java:233)
at com.github.tomakehurst.wiremock.junit5.WireMockExtension.beforeAll(WireMockExtension.java:300)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1604)
原因
Maven Central Repositoryを確認したところ、wiremock-jetty12 3.13.2はJetty 12.0.30に依存している。
抜粋
...
<version>3.13.2</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-bom</artifactId>
<!-- これがJettyのバージョン -->
<version>12.0.30</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.ee10</groupId>
<artifactId>jetty-ee10-bom</artifactId>
<!-- これがJettyのバージョン -->
<version>12.0.30</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
...
しかし、先ほどテストしたアプリケーションの依存性を確認すると、Jetty 12.1.5になっている。これが原因っぽい。本来あるべき12.0.30とバージョンが異なるので、対象のメソッドが削除されていてもおかしくない。

なぜこうなっているかと言うと、Spring Boot 4.0.1が管理しているJettyのバージョンが12.1.5だから。

対策
ということで、Jettyのバージョンを無理やり12.0.30にすればよい。具体的には次のようにする。
pom.xml(修正後)
...
<properties>
<java.version>25</java.version>
</properties>
<!-- これを追加!!! -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-bom</artifactId>
<version>12.0.30</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
...
これでJetty 12.0.30になり、JUnitテストも無事に実行できました。

Discussion