spring-restdocs: spring-restdocs-asciidoctor is incompatible with AsciidoctorJ 1.6 and later

Using the latest version (1.5.10) of the gradle plugin org.asciidoctor.convert causes the following exception to be thrown:

Exception in thread "main" java.lang.IncompatibleClassChangeError: Found interface org.asciidoctor.extension.JavaExtensionRegistry, but class was expected
        at org.springframework.restdocs.asciidoctor.RestDocsExtensionRegistry.register(RestDocsExtensionRegistry.java:32)
        at org.asciidoctor.extension.internal.ExtensionRegistryExecutor.registerAllExtensions(ExtensionRegistryExecutor.java:21)
        at org.asciidoctor.internal.JRubyAsciidoctor.registerExtensions(JRubyAsciidoctor.java:113)
        at org.asciidoctor.internal.JRubyAsciidoctor.processRegistrations(JRubyAsciidoctor.java:102)
        at org.asciidoctor.internal.JRubyAsciidoctor.create(JRubyAsciidoctor.java:82)
        at org.asciidoctor.internal.JRubyAsciidoctor.create(JRubyAsciidoctor.java:78)
        at org.asciidoctor.Asciidoctor$Factory.create(Asciidoctor.java:713)
        at org.asciidoctor.gradle.backported.AsciidoctorJavaExec.getAsciidoctorInstance(AsciidoctorJavaExec.groovy:71)
        at org.asciidoctor.gradle.backported.AsciidoctorJavaExec.run(AsciidoctorJavaExec.groovy:39)
        at org.asciidoctor.gradle.backported.AsciidoctorJavaExec.main(AsciidoctorJavaExec.groovy:194)

Using the previous version (1.5.9.2) works fine.

It would be a good idea I guess to release a new version of spring-restdocs that is built against the newest stable version of AsciidoctorJ (the gradle plugin currently uses AsciidoctorJ version 1.6.1, and the latest version is 1.6.2). Unfortunately, the Maven plugin still uses AsciidoctorJ version 1.5.8. Not sure if it’s possible to be compatible with the two versions.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 4
  • Comments: 28 (15 by maintainers)

Commits related to this issue

Most upvoted comments

Here’s my feedback on the 2.0.4 snapshot release (I tested it with gradle 5.1).

I started by setting the version of the spring-restdocs-mockmvc and spring-restdocs-asciidoctor dependencies to 2.0.4.BUILD-SNAPSHOT.

  • using it with the “org.asciidoctor.convert” plugin, version 1.5.9.2 that I was using already still works fine
  • using it with the “org.asciidoctor.convert” plugin, version 1.6.0 works fine too
  • using it with the “org.asciidoctor.convert” plugin, version 2.2.0 fails with the deprecation warning and error below. But (TL;DR;), it’s possible, by making some simple adaptations to the build, to get it working. See below for details.

So, @wilkinsona, everything works fine with the snapshot 👍 , with all the tested versions of the asciidoctor plugin, even though using the latest version needs adaptations (and thus changes to the spring-restdocs documentation)

> Configure project :backend
You are using one or more deprecated Asciidoctor task or plugins. To help with migration run with --warnings=all

> Task :backend:asciidoctor
Exception in thread "main" org.asciidoctor.gradle.remote.AsciidoctorRemoteExecutionException: Error running Asciidoctor whilst attempting to process /Users/jb/projects/amies-server/backend/src/main/asciidoc/index.adoc using backend html5
        at org.asciidoctor.gradle.remote.AsciidoctorJavaExec$_convertFiles_closure4.doCall(AsciidoctorJavaExec.groovy:87)
        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.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:104)
        at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:326)
        at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:264)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1041)
        at groovy.lang.Closure.call(Closure.java:411)
        at groovy.lang.Closure.call(Closure.java:427)
        at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2296)
        at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2281)
        at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2334)
        at org.asciidoctor.gradle.remote.AsciidoctorJavaExec.convertFiles(AsciidoctorJavaExec.groovy:78)
        at org.asciidoctor.gradle.remote.AsciidoctorJavaExec.access$1(AsciidoctorJavaExec.groovy)
        at org.asciidoctor.gradle.remote.AsciidoctorJavaExec$_run_closure3.doCall(AsciidoctorJavaExec.groovy:70)
        at org.asciidoctor.gradle.remote.AsciidoctorJavaExec$_run_closure3.call(AsciidoctorJavaExec.groovy)
        at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2296)
        at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2281)
        at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2322)
        at org.asciidoctor.gradle.remote.AsciidoctorJavaExec.run(AsciidoctorJavaExec.groovy:65)
        at org.asciidoctor.gradle.remote.AsciidoctorJavaExec.main(AsciidoctorJavaExec.groovy:47)
Caused by: java.lang.IllegalStateException: asciidoctor: FAILED: /Users/jb/projects/amies-server/backend/src/main/asciidoc/index.adoc: Failed to load AsciiDoc document
        at org.springframework.restdocs.asciidoctor.SnippetsDirectoryResolver.getRequiredAttribute(SnippetsDirectoryResolver.java:78)
        at org.springframework.restdocs.asciidoctor.SnippetsDirectoryResolver.getRequiredAttribute(SnippetsDirectoryResolver.java:68)
        at org.springframework.restdocs.asciidoctor.SnippetsDirectoryResolver.lambda$getGradleSnippetsDirectory$0(SnippetsDirectoryResolver.java:63)
        at org.springframework.restdocs.asciidoctor.SnippetsDirectoryResolver.getRequiredAttribute(SnippetsDirectoryResolver.java:76)
        at org.springframework.restdocs.asciidoctor.SnippetsDirectoryResolver.getGradleSnippetsDirectory(SnippetsDirectoryResolver.java:62)
        at org.springframework.restdocs.asciidoctor.SnippetsDirectoryResolver.getSnippetsDirectory(SnippetsDirectoryResolver.java:39)
        at org.springframework.restdocs.asciidoctor.DefaultAttributesAsciidoctorJ16Preprocessor.process(DefaultAttributesAsciidoctorJ16Preprocessor.java:36)
        at org.asciidoctor.extension.processorproxies.PreprocessorProxy.process(PreprocessorProxy.java:95)
        at org.asciidoctor.extension.processorproxies.PreprocessorProxy$INVOKER$i$2$0$process.call(PreprocessorProxy$INVOKER$i$2$0$process.gen)
        at org.jruby.internal.runtime.methods.JavaMethod$JavaMethodTwoOrN.call(JavaMethod.java:1008)
        at org.jruby.RubyMethod.call(RubyMethod.java:121)
        at org.jruby.RubyMethod$INVOKER$i$call.call(RubyMethod$INVOKER$i$call.gen)
        at org.jruby.internal.runtime.methods.JavaMethod$JavaMethodZeroOrOneOrTwoOrNBlock.call(JavaMethod.java:353)
        at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:201)
        at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:326)
        at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
        at org.jruby.ir.interpreter.Interpreter.INTERPRET_BLOCK(Interpreter.java:128)
        at org.jruby.runtime.MixedModeIRBlockBody.commonYieldPath(MixedModeIRBlockBody.java:151)
        at org.jruby.runtime.IRBlockBody.doYield(IRBlockBody.java:187)
        at org.jruby.runtime.BlockBody.yield(BlockBody.java:116)
        at org.jruby.runtime.Block.yield(Block.java:165)
        at org.jruby.RubyArray.each(RubyArray.java:1792)
        at org.jruby.RubyArray$INVOKER$i$0$0$each.call(RubyArray$INVOKER$i$0$0$each.gen)
        at org.jruby.internal.runtime.methods.JavaMethod$JavaMethodZeroBlock.call(JavaMethod.java:537)
        at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:82)
        at org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:91)
        at org.jruby.ir.instructions.CallBase.interpret(CallBase.java:544)
        at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:362)
        at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
        at org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:80)
        at org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:138)
        at org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:125)
        at org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:191)
        at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:325)
        at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:141)
        at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:346)
        at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
        at org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:92)
        at org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:204)
        at org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:191)
        at org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:207)
        at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:367)
        at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:203)
        at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:326)
        at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
        at org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:105)
        at org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:92)
        at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:303)
        at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:84)
        at org.jruby.ir.instructions.CallBase.interpret(CallBase.java:547)
        at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:362)
        at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
        at org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:105)
        at org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:92)
        at org.jruby.RubyMethod.call(RubyMethod.java:129)
        at org.jruby.RubyMethod$INVOKER$i$call.call(RubyMethod$INVOKER$i$call.gen)
        at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:303)
        at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:84)
        at org.jruby.ir.instructions.CallBase.interpret(CallBase.java:547)
        at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:362)
        at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
        at org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:105)
        at org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:92)
        at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:82)
        at org.jruby.ir.instructions.CallBase.interpret(CallBase.java:547)
        at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:362)
        at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
        at org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:105)
        at org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:92)
        at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:82)
        at org.jruby.ir.instructions.CallBase.interpret(CallBase.java:547)
        at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:362)
        at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
        at org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:105)
        at org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:92)
        at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:82)
        at org.jruby.ir.instructions.CallBase.interpret(CallBase.java:547)
        at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:362)
        at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
        at org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:105)
        at org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:92)
        at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:303)
        at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:84)
        at org.jruby.ir.instructions.CallBase.interpret(CallBase.java:547)
        at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:362)
        at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
        at org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:105)
        at org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:92)
        at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:303)
        at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:84)
        at org.jruby.ir.instructions.CallBase.interpret(CallBase.java:547)
        at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:362)
        at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
        at org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:80)
        at org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:138)
        at org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:125)
        at org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:191)
        at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:325)
        at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:141)
        at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:346)
        at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
        at org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:92)
        at org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:204)
        at org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:191)
        at org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:207)
        at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:367)
        at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:203)
        at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:326)
        at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
        at org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:92)
        at org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:204)
        at org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:191)
        at org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:207)
        at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:367)
        at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:203)
        at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:326)
        at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
        at org.jruby.ir.interpreter.Interpreter.INTERPRET_BLOCK(Interpreter.java:128)
        at org.jruby.runtime.MixedModeIRBlockBody.commonYieldPath(MixedModeIRBlockBody.java:151)
        at org.jruby.runtime.IRBlockBody.doYield(IRBlockBody.java:187)
        at org.jruby.runtime.BlockBody.yield(BlockBody.java:116)
        at org.jruby.runtime.Block.yield(Block.java:165)
        at org.jruby.RubyIO.ensureYieldClose(RubyIO.java:1163)
        at org.jruby.RubyIO.open(RubyIO.java:1157)
        at org.jruby.RubyIO$INVOKER$s$0$0$open.call(RubyIO$INVOKER$s$0$0$open.gen)
        at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:303)
        at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:84)
        at org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:91)
        at org.jruby.ir.instructions.CallBase.interpret(CallBase.java:544)
        at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:362)
        at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
        at org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:105)
        at org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:92)
        at org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:173)
        at org.jruby.RubyClass.finvoke(RubyClass.java:888)
        at org.jruby.runtime.Helpers.invoke(Helpers.java:442)
        at org.jruby.RubyBasicObject.callMethod(RubyBasicObject.java:374)
        at org.asciidoctor.internal.JRubyAsciidoctor.convertFile(JRubyAsciidoctor.java:488)
        at org.asciidoctor.internal.JRubyAsciidoctor.convertFile(JRubyAsciidoctor.java:469)
        at org.asciidoctor.gradle.remote.AsciidoctorJavaExec$_convertFiles_closure4.doCall(AsciidoctorJavaExec.groovy:83)
        ... 22 more
Caused by: java.lang.IllegalStateException: asciidoctor: FAILED: <stdin>: Failed to load AsciiDoc document
        ... 162 more
Caused by: java.lang.IllegalStateException: projectdir attribute not found
        ... 162 more

Fixing the error is easy: the asciidoctor task must be modified to explicitly add the projectdir attribute:

Before:

    asciidoctor {
        inputs.dir(snippetsDir)
        dependsOn(docTest)
        sourceDir("src/main/asciidoc")
        attributes(
            "stylesheet=amies.css",
            "stylesdir=styles",
            "springbootversion=$springBootVersion"
        )
    }

After:

    asciidoctor {
        inputs.dir(snippetsDir)
        dependsOn(docTest)
        sourceDir("src/main/asciidoc")
        attributes(
            "stylesheet=amies.css",
            "stylesdir=styles",
            "springbootversion=$springBootVersion",
            "projectdir=$projectDir" // this attribute needs to be added
        )
    }

I tried running with --warnings=all to know how to avoid using deprecated tasks. But there is no such option. The correct option is (I guess) --warning-mode=all. Running it with that option gives

You are using one or more deprecated Asciidoctor task or plugins. These will be removed in a future release. To help you migrate we have compiled some tips for you based upon your current usage:

  - 'org.asciidoctor.convert' is deprecated. When you have time please switch over to 'org.asciidoctor.jvm.convert'.
  - jcenter() is no longer added by default. If you relied on this behaviour in the past, please add jcenter() to the repositories block.

@ysb33r fixing the warning message to use the correct command line option would be nice.

So I tried using the plugin “org.asciidoctor.jvm.convert” instead of “org.asciidoctor.convert”. This plugin doesn’t create the asciidoctor gradle configuration anymore, which is used to add the spring-restdocs-asciidoctor dependency. And the way to configure the asciidoctor task has changed. I managed to get everything working though, by applying the following changes (note: this uses the Gradle Kotlin DSL):

  1. recreate the asciidoctor configuration
configurations {
    create("asciidoctor")
}
  1. Add the spring rest docs extension to the configuration:
dependencies {
    // ...
    "asciidoctor"("org.springframework.restdocs:spring-restdocs-asciidoctor:2.0.4.BUILD-SNAPSHOT")
}
  1. Change the asciidoctor task configuration. Before:
    asciidoctor {
        inputs.dir(snippetsDir)
        dependsOn(docTest)
        sourceDir("src/main/asciidoc")
        attributes(
            "stylesheet=amies.css",
            "stylesdir=styles",
            "springbootversion=$springBootVersion"
        )
    }

After:

    asciidoctor {
        inputs.dir(snippetsDir)
        dependsOn(docTest)
        setSourceDir(file("src/main/asciidoc")) // different way of setting the source dir
        attributes( // different way of setting the attributes
            mapOf(
                "stylesheet" to "amies.css",
                "stylesdir" to "styles",
                "springbootversion" to "$springBootVersion",
                "projectdir" to projectDir // this attribute needs to be added
            )
        )
        baseDirFollowsSourceDir() // this needs to be called otherwise the styles are not looked up in the right directory
        configurations("asciidoctor") // this needs to be added to add the spring rest docs extension
    }

Also note that the generated html file is now located under build/docs/asciidoc instead of build/asciidoc/html5.

@wilkinsona The READMEs on Asciidoctor Gradle for the various versions (1.5.x, 1.6.x, 2.x and 3.x) now contain notes w.r.t. to spring-restdocs compatibility. Basically it boils down to people should remain using 1.5.11 or 1.5.12 if they use spring-restdocs. Once the latter is upgraded to support AsciidoctorJ 2.0 (not 1.6) they will be able to use the 3.x range of asciidoctor-gradle. (In a similar note asciidoctor-maven 2.x).

Just to clarify the versioning on Asciidoctor Gradle:

  • 1.5.x & 1.6.x are both in maintenance mode and will only take critical bug fixes. They are also only officially supported on Gradle 3.x & 4.x.
  • 2.x is the main released (production) version and is AsciidoctorJ 1.6 compatible.
  • 3.x is the new version in development and is AsciidoctorJ 2.0 compatible. (there have only been alpha releases so far)

Even though I am not a user of spring-restdocs, I am willing to help to get this resolved if someone of the Spring side can collaborate with me on this.

I’ve opened https://github.com/asciidoctor/asciidoctor-maven-plugin/issues/385 to explore the possibility of the Maven plugin aligning its AsciidoctorJ dependency with that of the Gradle plugin.

@jzinet Also see asciidoctor/asciidoctor-gradle-plugin#404 regarding your Kotlin DSL discoveries.

@ysb33r fixing the warning message to use the correct command line option would be nice.

@jzinet That has been fixed, but not released yet.

I’ve bitten the bullet and split things out into several modules so that I can compile against AsciidoctorJ 1.5, 1.6 and 2.0 and deal with their various incompatibles. The existing spring-restdocs-asciidoctor module then pulls these separate modules back together into a single jar that’s hopefully compatible with AsciidoctorJ 1.5, 1.6, and 2.0.

there aren’t enough other new features to warrant such a release at the moment.

Would a Kotlin DSL warrant such a release? I have one waiting to be reviewed 😉 See https://github.com/spring-projects/spring-restdocs/issues/547#issuecomment-466341352 and https://github.com/Ninja-Squad/spring-rest-docs-kotlin

Not yet, no. I’ve yet to have the time to figure out exactly what the right approach is going to be. Ideally, a maintenance release of REST Docs could add support for new versions of AsciidoctorJ but all the ways of achieving that [that I’ve thought of thus far] are pretty unpleasant. An alternative would be a new minor release of REST Docs that requires AsciidoctorJ 1.6, but with AsciidoctorJ 2.0 approaching, that’s only going to be a short-term solution.