まとめ
- CDI-Unit 4.0.2 (執筆時点最新版) はJAX-RS実装としてRESTEasy 3.0.14に依存
- RESTEasy 3.0.14はJAX-RS 2.0 (Java EE 7) の実装
- よってJAX-RS 2.1 (Java EE 8) のサービスが動かせないことがある
- RESTEasyを3.5.0以降に上げることで回避可能
検証
単にHTTP OKを返すだけのWebサービスをテストクラスから呼んでみる。
@RequestScoped @Path("hoge") public class HogeService { @POST @Path("new") @Consumes(MediaType.APPLICATION_JSON) public Response add(@Valid Hoge hoge) { return Response.ok().build(); } }
@RunWith(CdiRunner) @SupportJaxRs class HogeServiceTest { @Inject private HogeService sut @Test @InRequestScope void new_hoge() { def request = newRequest() def response = sut.add(request) assertThat(response.status, is(Response.Status.OK.statusCode)) } }
何も考えずにCDI-Unitをdependenciesに含めてみる。
// ✗ NG dependencies { providedCompile 'javax:javaee-web-api:8.0' testCompile 'org.jglue.cdi-unit:cdi-unit:4.0.2' testRuntime 'org.jboss.weld.se:weld-se-core:3.0.0.Final' testRuntime 'org.jboss.weld.module:weld-web:3.0.0.Final' }
実行すると AbstractMethodError
が出てしまう。
java.lang.AbstractMethodError: javax.ws.rs.core.Response$ResponseBuilder.status(ILjava/lang/String;)Ljavax/ws/rs/core/Response$ResponseBuilder; at javax.ws.rs.core.Response$ResponseBuilder.status(Response.java:921) at javax.ws.rs.core.Response.status(Response.java:592) at javax.ws.rs.core.Response.status(Response.java:603) at javax.ws.rs.core.Response.ok(Response.java:638)
JAX-RS 2.1のAPI群がロードされているにもかかわらず、CDI-Unitが依存しているRESTEasyにはJAX-RS 2.1で追加された抽象メソッド ResponseBuilder#status(int, String)
が実装されていないことが原因。
RESTEasyをJAX-RS 2.1に対応したバージョン、すなわち3.5.0以降に上げてやる。
// ✓ OK dependencies { providedCompile 'javax:javaee-web-api:8.0' testCompile 'org.jglue.cdi-unit:cdi-unit:4.0.2', { exclude module: 'resteasy-jaxrs' } testRuntime 'org.jboss.resteasy:resteasy-jaxrs:3.6.1.Final' testRuntime 'org.jboss.weld.se:weld-se-core:3.0.0.Final' testRuntime 'org.jboss.weld.module:weld-web:3.0.0.Final' }
今度は問題なく実行出来た。
この回避策によって他に悪影響ないかとかは未確認。暫くの間この策を試していこうと思う。