asciidoctorj icon indicating copy to clipboard operation
asciidoctorj copied to clipboard

Rouge test fails with JRuby 10

Open robertpanzer opened this issue 4 months ago • 3 comments

When upgrading to JRuby 10 the test for the rouge syntax highlighter fails. The log shows this error:

(NameError) uninitialized constant Rouge::Lexers::PlainText
org.jruby.exceptions.NameError: (NameError) uninitialized constant Rouge::Lexers::PlainText
	at org.jruby.RubyModule.const_missing(org/jruby/RubyModule.java:4857)
	at RUBY.create_lexer(uri:classloader:/gems/asciidoctor-2.0.23/lib/asciidoctor/syntax_highlighter/rouge.rb:71)
	at RUBY.highlight(uri:classloader:/gems/asciidoctor-2.0.23/lib/asciidoctor/syntax_highlighter/rouge.rb:18)
	at RUBY.highlight_source(uri:classloader:/gems/asciidoctor-2.0.23/lib/asciidoctor/substitutors.rb:962)
	at RUBY.apply_subs(uri:classloader:/gems/asciidoctor-2.0.23/lib/asciidoctor/substitutors.rb:104)
	at org.jruby.RubyArray.each(org/jruby/RubyArray.java:2079)
	at RUBY.apply_subs(uri:classloader:/gems/asciidoctor-2.0.23/lib/asciidoctor/substitutors.rb:91)
	at RUBY.content(uri:classloader:/gems/asciidoctor-2.0.23/lib/asciidoctor/block.rb:117)

I tracked this down to the rouge lexers not being registered here: https://github.com/rouge-ruby/rouge/blob/2a8b21b530076f0df4515397482651099ce789b2/lib/rouge.rb#L49-L54

    def load_lexers
      lexer_dir = Pathname.new(LIB_DIR) / "rouge/lexers"
      Pathname.glob(lexer_dir / '*.rb').each do |f|
        Lexers.load_lexer(f.relative_path_from(lexer_dir))
      end
    end

In this code and in our environment LIB_DIR is uri:classloader:/gems/rouge-4.5.2/lib (found out through my amazing puts debugging capabilities). Apparently, Pathname.glob does not find anything with JRuby 10. The same code seems to work with JRuby 9. The test passes after changing the function to this:

    def load_lexers
      lexer_dir = Pathname.new(LIB_DIR) / "rouge/lexers"
      lexer_dir.glob('*.rb').each do |f|
        Lexers.load_lexer(f.relative_path_from(lexer_dir))
      end
    end

@headius: Do you know if Pathname::glob behaves differently than Pathname#glob, in particular when the pathname starts with "uri:classloader:/"? In particular I see a difference between these 2 statements:

This prints nothing:

      Pathname.glob(Pathname.new("uri:classloader:/org") / "*").each do |path|
        puts "path: #{path}"
      end

This starts to list everything on the class path below /org:

      Pathname.new("uri:classloader:/org").glob("*").each do |path|
        puts "path: #{path}"
      end

prints

path: uri:classloader:/org/apache
path: uri:classloader:/org/asciidoctor
path: uri:classloader:/org/assertj
...

/cc @abelsromero who was also looking at this issue already

robertpanzer avatar Jul 06 '25 15:07 robertpanzer

I haven't put time this weekend, but that's consistent with what I had seen so far. I'll wait for Charles to comment.

In this code and in our environment LIB_DIR is uri:classloader:/gems/rouge-4.5.2/lib (found out through my amazing puts debugging capabilities).

You are not the only one 😅

abelsromero avatar Jul 06 '25 20:07 abelsromero

I created an issue for this at https://github.com/jruby/jruby/issues/8973. While it might be possible to patch the rouge code to fix the problem, I think it would be better if the problem is fixed in JRuby. Maybe other projects are experiencing the same problem.

robertpanzer avatar Aug 23 '25 16:08 robertpanzer

We fixed the glob issue in jruby/jruby#8978 and jruby/jruby#8980 and have resolved @robertpanzer's issue for JRuby 9.4.14.0 (releasing in the next few days) and JRuby 10.0.3.0 (next couple of weeks, probably).

Please let us know if there are further issues!

headius avatar Aug 28 '25 15:08 headius