Sylvain Lemoine
Another dev blog in the nexus…

Fail of the day - Spring rest docs Vs Spring boot dependencies

· by Sylvain Lemoine · Read in about 2 min · (261 Words)
Java Spring Boot Spring Rest Docs

Today, I gave a first try to Spring REST Docs. I started a new Spring Boot project (from latest 1.5.4.RELEASE) following the Spring REST docs reference documentation and quickly face the following issue at runtime:

java.lang.NoSuchMethodError: org.springframework.restdocs.operation.OperationRequestFactory.create(Ljava/net/URI;Lorg/springframework/http/HttpMethod;[BLorg/springframework/http/HttpHeaders;Lorg/springframework/restdocs/operation/Parameters;Ljava/util/Collection;Ljava/util/Collection;)Lorg/springframework/restdocs/operation/OperationRequest;

	at org.springframework.restdocs.mockmvc.MockMvcRequestConverter.convert(MockMvcRequestConverter.java:79)
	at org.springframework.restdocs.mockmvc.MockMvcRequestConverter.convert(MockMvcRequestConverter.java:57)
	at org.springframework.restdocs.generate.RestDocumentationGenerator.handle(RestDocumentationGenerator.java:187)
	at org.springframework.restdocs.mockmvc.RestDocumentationResultHandler.handle(RestDocumentationResultHandler.java:55)
	at org.springframework.test.web.servlet.MockMvc$1.andDo(MockMvc.java:177)
	at fr.sle.AppTest.myTest(AppTest.java:47)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)

I use the latest dependency version of spring-restdocs-mockmvc

<dependency>
  <groupId>org.springframework.restdocs</groupId>
  <artifactId>spring-restdocs-mockmvc</artifactId>
  <version>1.2.1.RELEASE</version>
  <scope>test</scope>
</dependency>

As usual with NoSuchMethodError exception, I assumed that a transitive dependency was behind the error.

Project dependencies shows that spring-restdocs-mockmvc has a dependency on spring-restdocs-core which was not in the correct version (1.1.3.RELEASE instead of 1.2.1.RELEASE).

Actually it was due to spring-boot-dependencies artifact which retrieves the wrong (or too old) dependency version of restdocs-core.

      <spring-plugin.version>1.2.0.RELEASE</spring-plugin.version>
      <spring-restdocs.version>1.1.3.RELEASE</spring-restdocs.version>
      <spring-retry.version>1.2.0.RELEASE</spring-retry.version>      

Solution:

Override the spring-restdocs-core version to 1.2.1.RELEASE via a maven property in your project.

Full working pom sample:

<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>fr.sle</groupId>
  <artifactId>samplerestdocs</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>samplerestdocs</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <spring-restdocs.version>1.2.1.RELEASE</spring-restdocs.version>
  </properties>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.4.RELEASE</version>
  </parent>

  <dependencies>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>org.springframework.restdocs</groupId>
      <artifactId>spring-restdocs-mockmvc</artifactId>
      <version>1.2.1.RELEASE</version>
      <scope>test</scope>
    </dependency>

  </dependencies>

  <!-- Package as an executable jar -->
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>

      <plugin>
        <groupId>org.asciidoctor</groupId>
        <artifactId>asciidoctor-maven-plugin</artifactId>
        <version>1.5.3</version>
        <executions>
          <execution>
            <id>generate-docs</id>
            <phase>prepare-package</phase>
            <goals>
              <goal>process-asciidoc</goal>
            </goals>
            <configuration>
              <backend>html</backend>
              <doctype>book</doctype>
            </configuration>
          </execution>
        </executions>
        <dependencies>
          <dependency>
            <groupId>org.springframework.restdocs</groupId>
            <artifactId>spring-restdocs-asciidoctor</artifactId>
            <version>1.2.1.RELEASE</version>
          </dependency>
        </dependencies>
      </plugin>

      <plugin>
        <artifactId>maven-resources-plugin</artifactId>
        <version>2.7</version>
        <executions>
          <execution>
            <id>copy-resources</id>
            <phase>prepare-package</phase>
            <goals>
              <goal>copy-resources</goal>
            </goals>
            <configuration>
              <outputDirectory>
                ${project.build.outputDirectory}/static/docs
              </outputDirectory>
              <resources>
                <resource>
                  <directory>
                    ${project.build.directory}/generated-docs
                  </directory>
                </resource>
              </resources>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

Comments