Skip to content

Default gems can't be upgraded without booting RubyGems #1956

@headius

Description

@headius

TruffleRuby currently lazy-loads RubyGems to improve startup. Unfortunately this means that unless RubyGems is forced to boot, default gems will not honor gem installed upgrades.

Default gems are installed in the standard library (so they are trivially loadable by require) but also have a specially-treated set of gemspecs. Those gemspecs are parsed by RubyGems at boot time so that upgraded default gems can be activated when the related standard libraries get required.

The full set of default gems in TruffleRuby is visible here: https://github.com/oracle/truffleruby/tree/master/lib/gems/specifications/default

RubyGems can be forced to boot by running bundle exec or via a gem-based executable like rails, but a simple Ruby script that requires a default gem-based standard library will not see upgraded versions of that library.

This is important for a couple reasons:

  • Running bundler-based apps by requiring bundler/setup. By the time you require anything from the bundler/ subdir, it's too late to activate an upgraded bundler.
  • Security and functionality updates to standard libraries like json or psych won't be honored even if the gems are installed.
  • Different default gems may be activated when running a script directly or running it with RubyGems booted, which will be unexpected for users coming from CRuby.

I do not have a fix to suggest, because it may not be possible (currently) to lazy load RubyGems and support always-upgradeable default gems.

Full disclosure: I implemented the default gem feature many years ago, and it is necessarily limited by the way RubyGems and require work.

For a related example see jruby/jruby#6109 which adapts the same lazy logic to JRuby, and has the same impact on default gems.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions