JRuby 10.1(CRuby 4.0互換)のCI対応と旧バージョン向けワークアラウンドの整理

rspec/rspec

JRuby 10.1がリリースされたことを受け、rspecのCIマトリクスに追加するとともに、EOLとなったJRuby 9.1向けのハック群を削除し、既知の互換性問題を適切にpend/skipで管理するよう整理しました。

背景

JRuby 10.1(CRuby 4.0互換)の正式リリースに伴い、rspecのテストスイートを新バージョン上で実行できるようにする必要がありました。同時に、長らくEOLとなっていたJRuby 9.1(9.1.17.0)向けのワークアラウンドがコードベースに残っており、メンテナンスコストになっていました。

具体的には、aruba_support.rbにはJRuby 9.1.17.0のrequire_relativeバグを回避するためのKernelモンキーパッチが存在し、aruba.rbではNameError/LoadErrorを握りつぶすrescueブロックがJRuby 9.1専用に実装されていました。これらは現行バージョンでは不要であるにもかかわらず、コードの可読性を下げる要因となっていました。

JRuby 10.1上でテストを実行した結果、jruby/jruby#9398(ネストしたrescue内でのcircular causesエラー)とrspec/rspec#321respond_to?スタブ時の無限再帰問題)という2件の既知の互換性問題が特定されています。

技術的な変更

CIマトリクスへのJRuby 10.1追加

.github/workflows/rspec.ymlのJRubyテストマトリクスにJRuby 10.1が追加されました。

変更前:

ruby:
  - jruby-9.4
  - jruby-10.0

変更後:

ruby:
  - jruby-10.1 # ruby 4.0 compatible
  - jruby-10.0 # ruby 3.4 compatible
  - jruby-9.4  # ruby 3.1 compatible

各エントリにCRuby互換バージョンのコメントが付記され、どのRubyバージョン互換として実行されているかが明示されるようになりました。

JRuby 9.1向けワークアラウンドの削除

spec/support/aruba_support.rbから、JRuby 9.1.17.0固有のrequire_relativeバグを回避する22行のKernelモンキーパッチが削除されました。rspec-mocks/spec/support/aruba.rbでは、JRuby 9.1.17.0でのロード失敗を握りつぶすためのbegin/rescue NameError, LoadErrorブロックが除去され、aruba/rspecrequireが直接的なコードになりました。

その他にも、以下のJRuby 9.1/9.2向けのガード条件が各スペックファイルから削除されています:

  • rspec-core/spec/integration/bisect_spec.rb:JRuby 9.1.17.0でのskip
  • rspec-core/spec/rspec/core/formatters/exception_presenter_spec.rb:JRuby 9.2未満でのpendingjruby/jruby#4737参照)
  • rspec-core/spec/rspec/core_spec.rb:JRuby環境でのrubygemsのallowed_loaded_features例外
  • rspec-core/spec/rspec/core/formatters/snippet_extractor_spec.rb:JRuby向けの:skipフラグ

JRuby 10.1の既知問題に対するpend/skip

特定済みの互換性問題については、バージョン条件付きでpendingまたはskipを設定する方式が採用されました。

rspec-mocks/spec/rspec/mocks/any_instance_spec.rbでは、jruby/jruby#9398に起因するネストしたrescue内でのcircular causesエラーに対し、テストメタデータの:pendingオプションを使用しています:

broken_on_jruby_10_1 =
  if RSpec::Support::Ruby.jruby? && RSpec::Support::Ruby.jruby_version >= '10.1.0.0'
    "re-raising exceptions currently broken due to https://github.com/jruby/jruby/issues/9398"
  else
    false
  end

it "stubs the method correctly", :pending => broken_on_jruby_10_1 do

rspec-mocks/spec/rspec/mocks/matchers/receive_spec.rbでは、rspec/rspec#321に起因するrespond_to?スタブ時のフレーキーな無限再帰について、ブロック内条件分岐によるskipを使用しています:

if RSpec::Support::Ruby.jruby? && RSpec::Support::Ruby.jruby_version >= '10.1.0.0'
  skip 'Flaky on JRuby 10.1 due to some interaction with Object#instance_exec (?) https://github.com/rspec/rspec/issues/321'
end

rspec-support/spec/rspec/support_spec.rbでは、同じくjruby/jruby#9398に起因するNameErrorの代わりにArgumentError: circular causesが送出される問題をブロック内pendingで管理しています。

spec_file_load_errors_specの条件修正

rspec-core/spec/integration/spec_file_load_errors_spec.rbでは、テストレベルの:skip属性として設定されていたRSpec::Support::Ruby.jruby?による一括スキップが、ブロック内の条件付きスキップに変更されました。これにより、JRuby 10.0以降(バージョン文字列比較で'10'未満のもの)のみをスキップし、JRuby 10.1ではテストが実行されるようになっています。

設計判断

JRubyのテストサポートをベストエフォートと位置づける方針が今回の変更全体を貫いています。PR説明にも「running specs on JRuby I believe is best efforts anyway」と明示されており、完全な互換性保証ではなく、既知の問題を追跡可能な形で管理することを優先しています。

JRuby 10.1固有の問題に対してpend/skipを選択するにあたり、pendingskipが使い分けられています。pendingはテストが実行されて期待通り失敗することを確認するのに対し、skipはテスト実行自体を省略します。receive_spec.rbskipが選ばれた理由は、当該テストが「フレーキー(不安定)」であるためで、結果が非決定的な場合にはpendingよりskipが適切と判断されています。いずれの場合も、Issue URLをコメントとして埋め込むことで、ワークアラウンドの理由と追跡先を明示しています。

JRuby 9.1向けのモンキーパッチをインライン除去し、aruba.rbrescueブロックも削除することで、テストサポートコードがシンプルになりました。これはEOL済みバージョンのサポートを明示的に打ち切る判断であり、メンテナが現行バージョンのJRuby問題に集中できる体制を整えています。

まとめ

この変更はJRuby 10.1(CRuby 4.0互換)をrspecのCI対象に加えながら、EOL済みのJRuby 9.1向けワークアラウンドを一掃した整理です。既知の互換性問題は上流Issueへのリンク付きでpend/skipとして記録されており、JRubyサポートをベストエフォートとして維持しつつ問題の追跡可能性を確保しています。

記事メタデータ

Generated by:
Claude Sonnet 4.6 for DiffDaily
LLM Trace:
bf80ad53

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

「総論→各論→結論」の構成が明確です。リード文で要旨を述べ、背景、技術的な変更、設計判断、まとめがそれぞれ適切に配置されており、理想的な記事構成です。

カスタムMarkdown構文 ✓ PASS

シンタックスハイライト・GitHubリンク記法の正確性

ファイル名付きシンタックスハイライト(`言語:ファイルパス`)およびGitHubのIssue/PRリンク記法が正しく使用されています。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

JRuby、rspec、CIに関する専門的な内容でありながら、冗長な初心者向け解説がなく、対象読者であるエンジニアに適切なレベルで書かれています。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各パラグラフはトピックセンテンスで始まり、1段落1トピックの原則が守られています。段落の長さも適切で、非常に読みやすい文章構造です。

Diff内容との照合 ✓ PASS

コードブロックとDiff内容の一致

記事内のコードブロックは提供されたDiff情報と完全に一致しています。また、「22行のKernelモンキーパッチ」のようなDiffのメタ情報に基づいた記述も正確です。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

「EOL」「CIマトリクス」「モンキーパッチ」「pend/skip」「circular causes」などの技術用語が文脈に応じて正確に使用されています。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

JRubyのバージョンごとの互換性問題や、`pend`と`skip`の使い分けに関する説明が、技術的に正確かつ論理的です。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

記事内のすべての主張(新バージョンのCI追加、旧バージョン向けハックの削除、既知問題の対処法など)は、PRのDescriptionやDiff内の情報によって完全に裏付けられています。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR番号(#323)、Issue番号(jruby/jruby#9398など)、バージョン番号(JRuby 10.1など)がすべて正確に記載されています。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事のタイトルは、PRのタイトル「test: test against JRuby 10.1」の意図を汲み取りつつ、ワークアラウンドの整理というもう一つの重要な側面も加えており、内容を的確に要約しています。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

記事で言及されている情報はすべてPRのタイトル、Description、Diff内に根拠があり、PRに記載のない外部知識の持ち込みはありません。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

「リリースされた」「長らくEOLとなっていた」などの時間に関する表現は、PR Descriptionの記述と正確に一致しています。