Description
Given a file in lib/
named thing.rb
which required within application.rb
like this:
require_relative "boot"
require "rails/all"
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
require "thing"
module Rails611LibRequireSpringBug
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 6.1
# Configuration for the application, engines, and railties goes here.
#
# These settings can be overridden in specific environments using the files
# in config/environments, which are processed later.
#
# config.time_zone = "Central Time (US & Canada)"
# config.eager_load_paths << Rails.root.join("lib")
# NOTE: my intent was to use the following code below:
# config.middleware.use Thing
end
end
When rails server
is launched, I was surprised to see this Spring-related error. I doubt it's truly related to Spring, but I felt like I should at least document this behavior since it may be surprising to some people.
$ rails s
You've tried to invoke Spring when it's already loaded (i.e. the Spring constant is defined).
This is probably because you generated binstubs with Spring 1.0, and you now have a Spring version > 1.0 on your system. To solve this, upgrade your bundle to the latest Spring version and then run `bundle exec spring binstub --all` to regenerate your binstubs. This is a one-time step necessary to upgrade from 1.0 to 1.1.
Here's the backtrace:
/Users/olivierlacan/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bootsnap-1.7.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:59:in `load'
/Users/olivierlacan/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/bootsnap-1.7.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:59:in `load'
/Users/olivierlacan/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/activesupport-6.1.1/lib/active_support/dependencies.rb:326:in `block in load'
/Users/olivierlacan/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/activesupport-6.1.1/lib/active_support/dependencies.rb:299:in `load_dependency'
/Users/olivierlacan/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/activesupport-6.1.1/lib/active_support/dependencies.rb:326:in `load'
/Users/olivierlacan/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/spring-2.1.1/lib/spring/binstub.rb:11:in `<main>'
/Users/olivierlacan/.rbenv/versions/2.7.2/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:92:in `require'
/Users/olivierlacan/.rbenv/versions/2.7.2/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:92:in `require'
/Users/olivierlacan/dev/sandbox/rails-6-1-1-lib-require-spring-bug/bin/spring:10:in `block in <top (required)>'
/Users/olivierlacan/dev/sandbox/rails-6-1-1-lib-require-spring-bug/bin/spring:7:in `tap'
/Users/olivierlacan/dev/sandbox/rails-6-1-1-lib-require-spring-bug/bin/spring:7:in `<top (required)>'
bin/rails:2:in `load'
bin/rails:2:in `<main>'
The only way I avoid it is by moving the require
call within the Application
class definition, which I had to do in the case where Thing
is a Rack middleware I wanted to insert. Although I don't have huge qualms about having to do so, I don't remember specific instructions from the Rails Guides warning against requiring (non reloadable) code outside of the Application
class definition. But I'll admit I might just be tired.
Here's a reproduction app: https://github.com/olivierlacan/rails-6-1-1-lib-require-spring-bug
I did initially follow the instructions to bundle exec spring binstub --all
but I doubt this issue has anything to do with the Spring version since this is a brand new app whose binstubs are Spring 2.1.1 native.
Considering the Stacktrace, this feels more likely to be a Bootsnap bug so I'll gladly move this issue over to that repo if that makes more sense.