Closed mojavelinux closed 10 years ago
@aalmiray As far as I can see, this is the only blocker for 1.5.0. If there's anything you need from me to help debug it, please feel free to shout it from the top of the Twitterverse ;)
Got an SCCE to reproduce the problem?
Only the example project thus far.
Yes, sorry. I totally forgot how to read issues. Noticed the link to the project after I hit "Send". Where's my coffee again? too early in the morning over here :P
:)
On a side note, I'm hoping to make that project an official example for the plugin, move it into the asciidoctor organization. Though, I think we should split it into 3 projects so we have super simple, something with custom gems and something with extensions. That way, we don't overwhelm new users with all the options at once.
Here's the stacktrace for future reference
Caused by: java.lang.NoClassDefFoundError: org/asciidoctor/gradle/AsciidoctorProxy
at org.asciidoctor.gradle.AsciidoctorTask.instantiateAsciidoctor(AsciidoctorTask.groovy:178)
at org.asciidoctor.gradle.AsciidoctorTask.processAsciidocSources(AsciidoctorTask.groovy:156)
at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:63)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.doExecute(AnnotationProcessingTaskFactory.java:218)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:211)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:200)
at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:570)
at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:553)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)
... 66 more
Caused by: java.lang.ClassNotFoundException: org.asciidoctor.gradle.AsciidoctorProxy
... 76 more
Kind of weird as AsciidoctorProxy
belongs to the pluign's jar. This may be a problem of two classLoaders interacting in a bad way. sigh
Yep, that's what it looks like to me. As a first step, is it possible to load an extension without using the service loader mechanism? If so, we could just recommend against using that for now. I also wonder if maybe this only happens when the extension is in the buildSrc. I wonder what would happen if we stuck it in a jar and made it a regular dependency. Not ideal, but helps us pinpoint the conditions of the failure.
Methinks we should have an asciidoctor
dependency configuration, otherwise the asciidoctor extensions will bleed out into the compile/runtime configurations. The alternative is to write your custom configuration (like we do in Griffon with compileOnly
), but then you need additional setup for the IDE's to recognize the extra JARs.
I agree, we are definitely going to want that because I anticipate mature projects loading a number of extensions from the Ruby or Java load paths. There will also be other things like webjars that people may want to include.
Silly me, we already have the asciidoctor
configuration. I'll setup a multi-project build and plug the custom extension into this configuration.
This is definitely one of those silly classloader errors we love in the Java space. A multi-project build yields the following error when invoking the asciidoctor
task
Caused by: java.lang.NoClassDefFoundError: org/asciidoctor/extension/spi/ExtensionRegistry
at org.gradle.internal.classloader.MultiParentClassLoader.loadClass(MultiParentClassLoader.java:63)
at org.gradle.internal.classloader.CachingClassLoader.loadClass(CachingClassLoader.java:41)
at org.asciidoctor.extension.internal.ExtensionRegistryExecutor.registerAllExtensions(ExtensionRegistryExecutor.java:20)
at org.asciidoctor.internal.JRubyAsciidoctor.registerExtensions(JRubyAsciidoctor.java:91)
at org.asciidoctor.internal.JRubyAsciidoctor.create(JRubyAsciidoctor.java:71)
at org.asciidoctor.Asciidoctor$Factory.create(Asciidoctor.java:662)
at org.asciidoctor.gradle.AsciidoctorTask.instantiateAsciidoctor(AsciidoctorTask.groovy:178)
at org.asciidoctor.gradle.AsciidoctorTask.processAsciidocSources(AsciidoctorTask.groovy:156)
at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:63)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.doExecute(AnnotationProcessingTaskFactory.java:218)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:211)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:200)
at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:570)
at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:553)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)
... 66 more
Caused by: java.lang.ClassNotFoundException: org.asciidoctor.extension.spi.ExtensionRegistry
... 82 more
Notice how Gradle's MultiParentClassLoader can't locate the classes. The root of the problem may be https://github.com/asciidoctor/asciidoctor-gradle-plugin/blob/master/src/main/groovy/org/asciidoctor/gradle/AsciidoctorTask.groovy#L359-L367 a custom classloader used to load AsciidoctorJ without having it spreading into other configurations/classpaths. I'll investigate a different way to make this work.
Was able to get a bit further by moving the extension to its own project (le sigh) because of the previous stacktrace, however this time I hit a problem on the Ruby side
Caused by: org.gradle.api.GradleException: Error running Asciidoctor
at org.asciidoctor.gradle.AsciidoctorTask.processDocumentsAndResources(AsciidoctorTask.groovy:204)
at org.asciidoctor.gradle.AsciidoctorTask.this$4$processDocumentsAndResources(AsciidoctorTask.groovy)
at org.asciidoctor.gradle.AsciidoctorTask$this$4$processDocumentsAndResources.callCurrent(Unknown Source)
at org.asciidoctor.gradle.AsciidoctorTask.processAsciidocSources(AsciidoctorTask.groovy:170)
at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:63)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.doExecute(AnnotationProcessingTaskFactory.java:218)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:211)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:200)
at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:570)
at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:553)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)
... 66 more
Caused by: org.jruby.exceptions.RaiseException: (NoMethodError) undefined method `include?' for nil:NilClass
at RUBY.registered_for_block?(jar:file:/Users/aalmiray/.gradle/caches/modules-2/files-2.1/org.asciidoctor/asciidoctorj/1.5.0/192df5660f72a0fb76966dcc64193b94fba65f99/asciidoctorj-1.5.0.jar!/gems/asciidoctor-1.5.0/lib/asciidoctor/extensions.rb:800)
at RUBY.next_block(jar:file:/Users/aalmiray/.gradle/caches/modules-2/files-2.1/org.asciidoctor/asciidoctorj/1.5.0/192df5660f72a0fb76966dcc64193b94fba65f99/asciidoctorj-1.5.0.jar!/gems/asciidoctor-1.5.0/lib/asciidoctor/parser.rb:675)
at RUBY.next_section(jar:file:/Users/aalmiray/.gradle/caches/modules-2/files-2.1/org.asciidoctor/asciidoctorj/1.5.0/192df5660f72a0fb76966dcc64193b94fba65f99/asciidoctorj-1.5.0.jar!/gems/asciidoctor-1.5.0/lib/asciidoctor/parser.rb:303)
at RUBY.next_section(jar:file:/Users/aalmiray/.gradle/caches/modules-2/files-2.1/org.asciidoctor/asciidoctorj/1.5.0/192df5660f72a0fb76966dcc64193b94fba65f99/asciidoctorj-1.5.0.jar!/gems/asciidoctor-1.5.0/lib/asciidoctor/parser.rb:291)
at RUBY.parse(jar:file:/Users/aalmiray/.gradle/caches/modules-2/files-2.1/org.asciidoctor/asciidoctorj/1.5.0/192df5660f72a0fb76966dcc64193b94fba65f99/asciidoctorj-1.5.0.jar!/gems/asciidoctor-1.5.0/lib/asciidoctor/parser.rb:52)
at RUBY.parse(jar:file:/Users/aalmiray/.gradle/caches/modules-2/files-2.1/org.asciidoctor/asciidoctorj/1.5.0/192df5660f72a0fb76966dcc64193b94fba65f99/asciidoctorj-1.5.0.jar!/gems/asciidoctor-1.5.0/lib/asciidoctor/document.rb:448)
at RUBY.load(jar:file:/Users/aalmiray/.gradle/caches/modules-2/files-2.1/org.asciidoctor/asciidoctorj/1.5.0/192df5660f72a0fb76966dcc64193b94fba65f99/asciidoctorj-1.5.0.jar!/gems/asciidoctor-1.5.0/lib/asciidoctor.rb:1337)
at RUBY.convert(jar:file:/Users/aalmiray/.gradle/caches/modules-2/files-2.1/org.asciidoctor/asciidoctorj/1.5.0/192df5660f72a0fb76966dcc64193b94fba65f99/asciidoctorj-1.5.0.jar!/gems/asciidoctor-1.5.0/lib/asciidoctor.rb:1415)
at RUBY.convert_file(jar:file:/Users/aalmiray/.gradle/caches/modules-2/files-2.1/org.asciidoctor/asciidoctorj/1.5.0/192df5660f72a0fb76966dcc64193b94fba65f99/asciidoctorj-1.5.0.jar!/gems/asciidoctor-1.5.0/lib/asciidoctor.rb:1528)
at RUBY.convertFile(<script>:62)
at org.jruby.gen.InterfaceImpl679234251.convertFile(org/jruby/gen/InterfaceImpl679234251.gen:13)
at org.asciidoctor.gradle.AsciidoctorTask.processSingleFile(AsciidoctorTask.groovy:236)
at org.asciidoctor.gradle.AsciidoctorTask.processSourceDir(AsciidoctorTask.groovy:220)
at org.asciidoctor.gradle.AsciidoctorTask$_processDocumentsAndResources_closure5.doCall(AsciidoctorTask.groovy:201)
at org.asciidoctor.gradle.AsciidoctorTask$_eachFileRecurse_closure8.doCall(AsciidoctorTask.groovy:249)
at org.asciidoctor.gradle.AsciidoctorTask.eachFileRecurse(AsciidoctorTask.groovy:244)
at org.asciidoctor.gradle.AsciidoctorTask.processDocumentsAndResources(AsciidoctorTask.groovy:200)
at org.asciidoctor.gradle.AsciidoctorTask.processAsciidocSources(AsciidoctorTask.groovy:170)
I've posted the setup at https://github.com/aalmiray/asciidoctor-gradle-example You'll have to build things manually for the time being
Aha! That's easy enough to fix. That's just a required config setting for the extension. I'll fill in the gap.
Fixed! Now the extension works. So the question now is, can we move it to buildSrc?
Unfortunately we're back to almost the same place where we started if the extension is placed under buildSrc. The latest exception is
Caused by: org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'org.asciidoctor.internal.JRubyAsciidoctor@25416916' with class 'org.asciidoctor.internal.JRubyAsciidoctor' to class 'org.asciidoctor.gradle.AsciidoctorProxy'
at org.asciidoctor.gradle.AsciidoctorTask.instantiateAsciidoctor(AsciidoctorTask.groovy:183)
at org.asciidoctor.gradle.AsciidoctorTask.processAsciidocSources(AsciidoctorTask.groovy:158)
at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:63)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.doExecute(AnnotationProcessingTaskFactory.java:219)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:212)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:201)
at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:533)
at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:516)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)
... 66 more
Which makes me think we have two ClassLoaders in the mix.
Would this be solved if you could pass the classloader to Asciidoctor.Factory.create? If so, we could introduce an overloaded method that takes both the gemPath and classloader for now, then implement the config object idea after the 1.5.0 plugin release.
It's worth a shot. I think this is what we're missing and the reason why I suggested an overloaded version for create()
.
:+1:
Go ahead and hack your local install of AsciidoctorJ and see if that change works. Then, we can do a pull request.
I have a feeling we're going to want to base the Gradle 1.5.0 plugin on AsciidoctorJ 1.5.1.
I agree too. We can push asciidoctor-gradle 1.5.0 to be in sync with 1.5.0 with the caveat that "in-build" extensions will not work. There are much more other goodies in 1.5.0 that people can take advantage if we release the plugin asap.
Sure, but we can also just release 1.5.1 later today / early tomorrow with the fixes we need (same for the Maven plugin). We'll still announce it as 1.5.0...but use that ever important semantic versioning.
If it's the same to you I'd rather go with 1.5.0 as it currently stands. Will finish up documenting what's changed for this release (deprecations, behavior compatibility, etc). Wednesday will be a busy, busy day :smile: off to catch some :sleeping:
Solid work! I knew my prayers to the beer gods would pay off :)
When you use extensions (at least extensions loaded from buildSrc), the plugin fails with a cast error.
You can see this error by running
gradle asciidoctor
on the following project:https://github.com/mojavelinux/asciidoctor-gradle-example
It's really important that we support extensions, especially extensions written in Groovy. (We even want to get to the point that the extensions can be written shorthand inside build.gradle).