This project is archived and is in readonly mode.

#4031 ✓wontfix
Hongli Lai

Having Rails 2.3pre or Rack 1.1 installed breaks Rails 2.x

Reported by Hongli Lai | February 22nd, 2010 @ 09:43 AM

Rails 2.x and earlier currently specifies 'rack ~> 1.0.0' as gem dependency. This can cause problems in the following environment:

  • Thin is installed with RubyGems.
  • Rails 2.x is installed with RubyGems.
  • Rails 3.0pre is installed with RubyGems (which pulls in Rack 1.1).

Thin has a dependency on 'rack', no specific version. However if Rack 1.1 is installed then starting Thin will automatically activate the latest version of Rack, 1.1. Rails's environment.rb tries to activate the Rails gems, but this fails at activating Rack 1.0.x because 1.1 is already activated.

Furthermore, boot.rb mistakenly thinks that this error means Rails isn't installed, so you get a console output like this:

[hongli@Minato foobar.test]$ thin start -S `pwd`/thin.sock -e production
 >> Using rails adapter
Missing the Rails 2.3.5 gem. Please `gem install -v=2.3.5 rails`,
update your RAILS_GEM_VERSION setting in config/environment.rb for the
Rails version you do have installed, or comment out RAILS_GEM_VERSION to
use the latest version installed.

The offending code is in boot.rb's load_rails_gem:

def load_rails_gem
  if version = self.class.gem_version
    gem 'rails', version
  else
    gem 'rails'
  end
rescue Gem::LoadError => load_error
  $stderr.puts %(Missing the Rails #{version} gem. Please `gem install -v=#{version} rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.)
  exit 1
end

If we put a 'puts load_error' in the rescue block then we'll see that the actual error is something along the lines of:
can't activate rack (~> 1.0.0, runtime) for ["actionpack-2.3.5", "rails-2.3.5"], already activated rack-1.1.0 for ["thin-1.2.5"]

Phusion Passenger is suffering from the same problem since it specifies Rack as a gem dependency too.

This problem can be solved by changing Rails's Rack dependency to "rack >= 1.0.0".

Comments and changes to this ticket

  • Maximilian Schulz

    Maximilian Schulz February 22nd, 2010 @ 10:23 AM

    I am not sure about the way thin is handling the problem, but I had the same with Passenger. I use the past tense, as the problem can be solved by removing the config.ru file from your application root. As specified in the passenger 2.2.9 release notes, the default behavior was changed. Specifically, passenger's rails adapter priority is now lower than the default rack adapter's. But be removing the config.ru file, the rails adapter will kick in and will load rack 1.0.1 and your rails 2.3.5 apps will load fine again.

    Passenger Configuration:

    • 2.3.5 apps: remove config.ru
    • 3.0.0 apps: keep config.ru
  • Hongli Lai

    Hongli Lai February 22nd, 2010 @ 11:33 AM

    After speaking to Yehuda (http://groups.google.com/group/rubyonrails-core/browse_thread/threa...) and giving it more thought I think the fix should be in RubyGems, not in Rack or in Rails.

    I've considered the possibility of splitting the Rack library into two portions, one that only the web server uses and one that only the web app uses. However this would make it impossible for the web server to modify the app's behavior. For example Thin inserts a middleware that utilizes Rack::Request in order to generate various statistics.

    Phusion Passenger happens to accidentally work around the issue by executing its spawn server without the RubyGems wrapper binary, so it doesn't activate Rack when loading regular Rails apps.

    I think RubyGems should not pre-activate dependencies for which no version specification is given. This would allow Thin to implement an option to tell it which Rack version to load.

  • Hongli Lai
  • Saimon Moore

    Saimon Moore April 20th, 2010 @ 12:02 PM

    Is there any other workaround apart from physically modifying rails/actionpack/lib/action_controller.rb?

  • Hongli Lai

    Hongli Lai April 21st, 2010 @ 08:50 AM

    You can modify the Mongrel/Thin/etc startup script to explicitly require Rack 1.0. Phusion Passenger does not need modification and isn't affected by the issue.

  • Saimon Moore

    Saimon Moore April 21st, 2010 @ 09:23 AM

    Hongli, I think I know what happened. I'm using rvm to handle my
    rubies. I have 1.9.1-p378 installed. I also use a gemset for each
    application. Recently I upgraded rvm and had to reinstall all my gems.
    I first installed passenger under 1.9.1 (without a gemset so that
    further minor updates to 1.9.1 wouldn't require updating passenger
    too). Since passenger has a dependency on rack (> 0), it installed
    rack 1.1.0 in the 1.9.1 gemset (which is automatically added to the
    gem path for any sub gem sets. In my application's gemset, I then
    reinstalled rack 1.0.1 not realizing that rack 1.1.0 had been
    installed in the 1.9.1 gemset. You can guess the rest. I've now
    removed rack 1.1.0 gem and it's working fine..

    Thanks...

    It's a pain though all of this. Someone needs to find a decent solution.

  • raggi

    raggi August 21st, 2010 @ 08:03 PM

    Hongli sorry, but there's issues with your RubyGems suggestion, specifically, activation is actually different from require, as activation specifies a specific gem from the gem namespace, whereas require picks arbitrarily from the filesystem space within all gems (ordered by alpha and version). There's no better way for us to do that, and as such not activating at the appropriate time could lead to require loading something unrelated. This would therefore be introducing a bug into RubyGems.

    The correct way to solve this issue is to make point releases with appropriate dependency sets.

  • Ryan Bigg

    Ryan Bigg October 9th, 2010 @ 10:00 PM

    • Tag cleared.
    • Importance changed from “” to “Low”

    Automatic cleanup of spam.

  • David Trasbo

    David Trasbo October 10th, 2010 @ 03:10 PM

    • State changed from “new” to “wontfix”

    As for the issue of telling users that the Rails gem is missing, when it might not actually be the case, I committed a fix a while back: http://github.com/rails/rails/commit/d0d10f51d7b2edea94a00291d79cad...

    As for the other issue: That was actually the main reason Bundler was created. It's a fundamental architectural flaw that will definitely not be fixed in 2.3. You have three options:

    1. Use RVM to isolate gems for each of your applications, thus preventing the need of having multiple versions of the same gem.
    2. Use Bundler which, as mentioned, was created to solve this specific problem.
    3. Or: Upgrade to Rails 3, which uses Bundler by default.
  • bingbing

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

<h2 style="font-size: 14px">Tickets have moved to Github</h2>

The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>

Pages