diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 6309dfadb..1f31beb1b 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -30,6 +30,10 @@ Improvement:: * Upgrade to asciidoctorj-diagram 2.2.4 (#1140) * Upgrade to jruby 9.3.10.0 (#1138) (@alexlevinfr) +Bug Fixes:: + +* Fix ConcurrentModificationException when converting to stream concurrently (#1158) (@rocketraman) + Build / Infrastructure:: * Replace use of deprecated 'numbered' attribute by 'sectnums' (#1127) (@abelsromero) diff --git a/asciidoctorj-core/src/main/java/org/asciidoctor/jruby/internal/JRubyAsciidoctor.java b/asciidoctorj-core/src/main/java/org/asciidoctor/jruby/internal/JRubyAsciidoctor.java index ff85e1e2b..80e396940 100644 --- a/asciidoctorj-core/src/main/java/org/asciidoctor/jruby/internal/JRubyAsciidoctor.java +++ b/asciidoctorj-core/src/main/java/org/asciidoctor/jruby/internal/JRubyAsciidoctor.java @@ -10,8 +10,6 @@ import org.asciidoctor.extension.JavaExtensionRegistry; import org.asciidoctor.extension.RubyExtensionRegistry; import org.asciidoctor.jruby.AsciidoctorJRuby; -import org.asciidoctor.jruby.DirectoryWalker; -import org.asciidoctor.jruby.ast.impl.AuthorImpl; import org.asciidoctor.jruby.ast.impl.DocumentHeaderImpl; import org.asciidoctor.jruby.ast.impl.NodeConverter; import org.asciidoctor.jruby.converter.internal.ConverterRegistryExecutor; @@ -23,13 +21,29 @@ import org.asciidoctor.log.LogHandler; import org.asciidoctor.log.LogRecord; import org.asciidoctor.syntaxhighlighter.SyntaxHighlighterRegistry; -import org.jruby.*; +import org.jruby.Ruby; +import org.jruby.RubyClass; +import org.jruby.RubyHash; +import org.jruby.RubyInstanceConfig; +import org.jruby.RubyModule; import org.jruby.exceptions.RaiseException; import org.jruby.javasupport.JavaEmbedUtils; import org.jruby.runtime.builtin.IRubyObject; -import java.io.*; -import java.util.*; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.Writer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; import java.util.logging.Logger; public class JRubyAsciidoctor implements AsciidoctorJRuby, LogHandler { @@ -60,6 +74,7 @@ private JRubyAsciidoctor(final Ruby rubyRuntime) { this.rubyGemsPreloader = new RubyGemsPreloader(this.rubyRuntime); this.logHandlers.add(new JULLogHandler()); + RubyOutputStreamWrapper.getOrCreateOutputStreamWrapperClass(this.rubyRuntime); } public static JRubyAsciidoctor create() { @@ -184,7 +199,6 @@ public DocumentHeader readDocumentHeader(File file) { return toDocumentHeader(document); } - @SuppressWarnings("unchecked") @Override public DocumentHeader readDocumentHeader(String content) { @@ -217,10 +231,6 @@ private List convertAllFiles(Map options, final Iterable return asciidoctorContent; } - private List scanForAsciiDocFiles(DirectoryWalker directoryWalker) { - return directoryWalker.scan(); - } - @Override public void requireLibrary(String... library) { requireLibraries(Arrays.asList(library)); diff --git a/asciidoctorj-core/src/main/java/org/asciidoctor/jruby/internal/RubyOutputStreamWrapper.java b/asciidoctorj-core/src/main/java/org/asciidoctor/jruby/internal/RubyOutputStreamWrapper.java index 490e3f3db..496bced84 100644 --- a/asciidoctorj-core/src/main/java/org/asciidoctor/jruby/internal/RubyOutputStreamWrapper.java +++ b/asciidoctorj-core/src/main/java/org/asciidoctor/jruby/internal/RubyOutputStreamWrapper.java @@ -8,7 +8,6 @@ import org.jruby.RubyObject; import org.jruby.RubyString; import org.jruby.anno.JRubyMethod; -import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.builtin.IRubyObject; @@ -25,7 +24,7 @@ public class RubyOutputStreamWrapper extends RubyObject { public static IRubyObject wrap(final Ruby rubyRuntime, final OutputStream out) { - final RubyClass rubyClass = getOrCreateOutputStreamWrapperClass(rubyRuntime); + final RubyClass rubyClass = getOutputStreamWrapperClass(rubyRuntime); final IRubyObject wrapper = rubyClass.allocate(); @@ -53,18 +52,16 @@ public static RubyClass getOrCreateOutputStreamWrapperClass(final Ruby rubyRunti return outputStreamWrapperClass; } - final RubyClass rubyClass = asciidoctorModule.defineClassUnder(RUBY_CLASS_NAME, rubyRuntime.getObject(), new ObjectAllocator() { - @Override - public IRubyObject allocate(final Ruby runtime, final RubyClass klazz) { - return new RubyOutputStreamWrapper(runtime, klazz); - } - }); - + final RubyClass rubyClass = asciidoctorModule.defineClassUnder(RUBY_CLASS_NAME, rubyRuntime.getObject(), RubyOutputStreamWrapper::new); rubyClass.defineAnnotatedMethods(RubyOutputStreamWrapper.class); - return rubyClass; } + private static RubyClass getOutputStreamWrapperClass(final Ruby rubyRuntime) { + RubyModule asciidoctorModule = rubyRuntime.getModule("AsciidoctorJ"); + return asciidoctorModule.getClass(RUBY_CLASS_NAME); + } + @JRubyMethod(name = "write", required = 1) public IRubyObject write(ThreadContext context, IRubyObject arg) throws IOException { writeToStream(arg);