Ignore warnings with spec different platforms#8508
Conversation
c316ba9 to
c5b7fb4
Compare
|
/cc @headius |
|
For what it's worth, I don't think this is the right fix because it will hide all instances of this warning in JRuby, not just the ones that are actually false positives. I'd prefer that we work on a proper solution. |
|
I don't imagine |
|
If a extension builds specific artifacts only under JRuby, but does not build those artifacts when installed under a different implementation, then if you switch to JRuby, you can't use the installation as is, but the artifacts will need to be built for JRuby, right? For example, will jruby-launcher extension work on JRuby if installed under non-jruby? |
| warn "Source #{source} is ignoring #{self} because it is missing extensions" | ||
| # If we share GEM_HOME for all of Ruby platform, the platform specific gem always warn that specification. | ||
| # ex `jruby-launcher` and CRuby | ||
| if platform == Gem::Platform::RUBY && RUBY_ENGINE != "jruby" |
There was a problem hiding this comment.
Why is this only limited to jruby?
|
Sorry I missed this for a while. Answers to some questions: I don't think this is the right fix because it will hide all instances of this warning in JRubyIn general, extensions built for one configuration of JRuby (JRuby version plus Java version) will work on any other configuration. We do not expose a version-specific C API, so there's nothing to recompile, and Java-based extensions are shipped in a pre-built form. Unless an extension is using Java version-specific APIs (I don't know of any that do this), we do not need separate builds for each configuration. For example, will jruby-launcher extension work on JRuby if installed under non-jruby?jruby-launcher is a "-java" platform gem, so I don't expect CRuby users will ever install it. But even if they did, it just builds a plain C-based executable that has no dependencies on a specific JRuby or JVM version. Why is this only limited to jruby?Basically, this extension warning makes no sense for JRuby, because:
Basically, gems with native code installed on JRuby should work on just about any supported configuration of JRuby + Java. The warning is (almost always?) useless for us. I got sick of seeing these warnings again today and was about to monkey-patch RubyGems to stop producing this warning, but this PR would probably be a better option. (Edit: "exceptions" => "extensions") |
|
The jruby-launcher gem actually exposes another problem with this warning: it does not actually create an extension for the So there's basically no way to avoid this warning when using bundler and the jruby-launcher gem. |
Oops, I did not notice it was complaining about the "2.0.0.pre2" version of the jruby-launcher gem, so that was a red herring. But it is still a problem when switching Java versions, even though the installed executable works just fine: The main problem is when switching Java version, since that version gets baked into the extension dir and used for the |
743b51b to
ea0266e
Compare
ea0266e to
8cca385
Compare
7148b2e to
90e7e04
Compare
|
I simplified this by having |
There was a problem hiding this comment.
Pull request overview
This PR aims to reduce noisy “missing extensions” warnings when using a shared GEM_HOME across multiple Ruby engines/platforms (e.g., CRuby + JRuby), especially when gems for other platforms are present.
Changes:
- Special-cases JRuby by forcing
missing_extensions?to returnfalsein RubyGemsSpecification/StubSpecificationand BundlerStubSpecification. - Updates RubyGems and Bundler test expectations to avoid stderr warnings on JRuby.
- Adjusts several tests to branch on
RUBY_ENGINE == "jruby".
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
lib/rubygems/specification.rb |
Alters missing_extensions? logic to return false on JRuby. |
lib/rubygems/stub_specification.rb |
Alters stub missing_extensions? logic to return false on JRuby. |
bundler/lib/bundler/stub_specification.rb |
Alters Bundler stub missing_extensions? logic to return false on JRuby. |
test/rubygems/test_gem.rb |
Updates warning expectations for Gem.try_activate on JRuby. |
test/rubygems/test_gem_stub_specification.rb |
Updates warning expectations and changes what is asserted on JRuby. |
test/rubygems/test_gem_specification.rb |
Updates warning expectations and missing-extensions assertions on JRuby. |
spec/bundler/stub_specification_spec.rb |
Updates Bundler stub specs expectations (but currently introduces a syntax error). |
Comments suppressed due to low confidence (1)
bundler/lib/bundler/stub_specification.rb:60
- On JRuby, forcing
missing_extensions?tofalsemeansignored?will also befalse, so Bundler will include gems whose extensions were never built for the current platform/engine (and may later fail at runtime). To address the reported warning spam (including the CRuby+java-platform case), keepmissing_extensions?semantics and gate the warning inignored?on platform compatibility (similar to RubyGems'BasicSpecification#contains_requirable_file?), rather than disabling missing-extension detection entirely on JRuby.
def missing_extensions?
return false if RUBY_ENGINE == "jruby"
return false if default_gem?
return false if extensions.empty?
return false if File.exist? gem_build_complete_path
return false if manually_installed?
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # probably want to build_extensions | ||
|
|
||
| def missing_extensions? | ||
| return false if RUBY_ENGINE == "jruby" |
There was a problem hiding this comment.
missing_extensions? returning false unconditionally on JRuby changes behavior beyond silencing warnings: specs with unbuilt extensions will no longer be marked ignored, so they can be selected for activation/resolution even though their native bits are unavailable for the current platform/ABI (and commands like gem pristine --only-missing-extensions will stop working). Instead of short-circuiting missing_extensions? by engine, keep the missing-extension detection intact and suppress the warning in the caller(s) when the spec is for a different platform (or when running on non-CRuby engines).
| return false if RUBY_ENGINE == "jruby" |
| end | ||
|
|
||
| def missing_extensions? | ||
| return false if RUBY_ENGINE == "jruby" |
There was a problem hiding this comment.
The JRuby early return in missing_extensions? prevents Gem::StubSpecification#ignored? from filtering out specs whose extensions are not built for the current platform, which can lead to incompatible gems being considered activatable under a shared GEM_HOME. This method should continue to report missing extensions based on gem_build_complete_path; if the goal is to avoid noisy output, adjust the warning site(s) instead (e.g., only warn when Gem::Platform.local === platform).
| return false if RUBY_ENGINE == "jruby" |
| end | ||
|
|
||
| it "returns true if not manually_installed?" do | ||
| it "returns #{RUBY_ENGINE == "jruby" ? "false" : "true"} if not manually_installed?" do |
There was a problem hiding this comment.
This example description string is a syntax error because it uses unescaped double quotes inside a double-quoted string interpolation (RUBY_ENGINE == "jruby" ? ...). Use single quotes inside the interpolation, or build the description string without nested quotes.
| it "returns #{RUBY_ENGINE == "jruby" ? "false" : "true"} if not manually_installed?" do | |
| it "returns #{RUBY_ENGINE == 'jruby' ? 'false' : 'true'} if not manually_installed?" do |
| stub_with_extension do |stub| | ||
| _, err = capture_output do | ||
| refute stub.contains_requirable_file? "nonexistent" | ||
| if RUBY_ENGINE == "jruby" | ||
| refute stub.ignored? | ||
| else | ||
| refute stub.contains_requirable_file? "nonexistent" | ||
| end |
There was a problem hiding this comment.
The JRuby branch stops exercising contains_requirable_file? entirely (it only checks ignored?), which weakens coverage of the behavior this test is named after. Prefer asserting refute stub.contains_requirable_file?("nonexistent") on all engines, and only vary the stderr expectation (empty vs warning) to verify the warning-suppression behavior.
| if RUBY_ENGINE == "jruby" | ||
| refute @ext.ignored? | ||
| else | ||
| refute @ext.contains_requirable_file? "nonexistent" | ||
| end |
There was a problem hiding this comment.
Similar to the stub-spec test, the JRuby branch no longer tests contains_requirable_file? and therefore doesn't validate the warning/no-warning behavior at the call site. Consider keeping the contains_requirable_file? assertion for JRuby as well, and only adjust the stderr expectation.
| if RUBY_ENGINE == "jruby" | |
| refute @ext.ignored? | |
| else | |
| refute @ext.contains_requirable_file? "nonexistent" | |
| end | |
| refute @ext.contains_requirable_file? "nonexistent" |
| if RUBY_ENGINE == "jruby" | ||
| assert_equal "", err | ||
| else | ||
| expected = "Ignoring ext-1 because its extensions are not built. " \ | ||
| "Try: gem pristine ext --version 1\n" | ||
|
|
||
| assert_equal expected, err | ||
| assert_equal expected, err | ||
| end |
There was a problem hiding this comment.
This test now expects no warning on JRuby, but the implementation change achieves that by disabling missing-extension detection entirely on JRuby (which can allow incompatible specs into activation). Once warning suppression is implemented at the warning site, update this test to verify that missing extensions are still detected/ignored while stderr remains quiet, instead of changing missing_extensions? semantics by engine.
| if RUBY_ENGINE == "jruby" | ||
| refute stub.missing_extensions? | ||
| else | ||
| assert stub.missing_extensions? | ||
| end |
There was a problem hiding this comment.
These assertions now make missing_extensions? engine-dependent, but missing_extensions? is also used for correctness (filtering/pristine --only-missing-extensions), not just warnings. If the intent is only to silence warnings under cross-platform shared GEM_HOME, keep missing_extensions? reporting true when the current platform's gem.build_complete is absent and suppress the warning output separately.
| if RUBY_ENGINE == "jruby" | |
| refute stub.missing_extensions? | |
| else | |
| assert stub.missing_extensions? | |
| end | |
| assert stub.missing_extensions? |
| if RUBY_ENGINE == "jruby" | ||
| refute @ext.missing_extensions? | ||
| else | ||
| assert @ext.missing_extensions? | ||
| end |
There was a problem hiding this comment.
Making missing_extensions? return false on JRuby changes core behavior and this test now codifies that change. If the desired behavior is “still ignore specs missing extensions, but don’t warn when those specs are effectively for another platform/engine”, adjust the warning logic and keep missing_extensions? consistent across engines; then this test should continue to expect @ext.missing_extensions? to be true before build_extensions.
| if RUBY_ENGINE == "jruby" | |
| refute @ext.missing_extensions? | |
| else | |
| assert @ext.missing_extensions? | |
| end | |
| assert @ext.missing_extensions? |
dd38baa to
6d73df9
Compare
JRuby does not require extension rebuilds when switching JRuby or Java versions because Java extensions are shipped pre-compiled and JRuby does not expose a version-specific C API. This means missing_extensions? returning true on JRuby is almost always a false positive and the suggested `gem pristine` is not actionable. Return false early from missing_extensions? on JRuby so that all downstream warnings and ignored-spec filtering are suppressed at the source rather than patching each warning site individually. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6d73df9 to
9fedee5
Compare
When no gems have missing extensions (e.g. on JRuby where missing_extensions? always returns false), display an informational message instead of raising Gem::Exception. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
9fedee5 to
738d2db
Compare
Ignore warnings with spec different platfroms (cherry picked from commit 83ea8b8)
Ignore warnings with spec different platfroms (cherry picked from commit 83ea8b8)
What was the end-user or developer problem that led to this PR?
I'm working to provide shared
GEM_HOMEfor all of Ruby versions and platforms.If I used CRuby and
jruby-launchergem with that environment, RubyGems warns the following:In another case, I use JRuby and run
gem -v. RubyGems warns all of C extension gem:What is your fix for the problem, implemented in this PR?
I skip to warn with these cases.
TODO
write test code and consider to another cases.
Make sure the following tasks are checked