Problem with unpacked gems and Kernel#gem

Hi all,

I have searched and searched for this, to no avail. Maybe someone here can give me a hand.

In my environment.rb, I added "config.gem" lines for a few gems that my app requires. Then, I went ahead and called "rake gems:unpack" and tried to deploy my app.

Problem is, if Kernel#gem is called to activate one of the gems I unpacked, it fails. I know that you aren't supposed to need to call Kernel#gem after using config.gem, but third party libraries use Kernel#gem all the time.

Needless to say this is a problem for me, because my app pretty much fails to start.

For now, I've worked around this by patching the libraries that call Kernel#gem, but for obvious reasons this isn't an optimal solution.

Any ideas? Any help would be SUPER appreciated. Hope this makes sense.

Thanks, Taylor

After looking into this more (tracing the call chains all the way through rubygems and rails), it's clear to me that this is actually the expected behavior.

In short, unpacked gems cannot be loaded using Kernel#gem. It's just the way it is. If you want to load an unpacked gem, you have to load it using config.gem (which is Rails::Configuration#gem) in environment.rb.

The obvious problem with this is when one of your unpacked gems has a dependency on another gem, and thus calls Kernel#gem directly. This is the case in my situation. So I config.gem the gem I want. But when the gem is loaded, it in turn calls Kernel#gem, which produces an error.

Has anyone else had a problem with this? Does anyone have a workaround that's better than patching the gem(s) causing the problem?

To me, this seems like something that could use attention in rails core. I am happy to try to work on this, but someone else may be more qualified in terms of experience with the code base (this would be my first foray into rails core development).

I think there are a couple of options. One would be to replace Kernel#gem with a method that can test for gems loaded via config.gem; if no gems are found, then it defers to the original Kernel#gem. Another option would be to modify Rails::GemDependency#add_load_paths to tell rubygems that it has loaded the gem in question. This is done, for example, when you have frozen rails into vendor/rails (see Rails::Initializer#install_gem_spec_stubs).

At this point I'm rambling. I think I'm going to go ahead and tackle this, using the latter strategy for now. I'll write back if I find anything more.

Taylor

Final message from me on this. It appears some other folks have noticed this and are working on it as we speak. Turns out I was on the wrong list! (Should've been on rails-core - apologies, I am new to digging into the details of rails).

In case someone else is looking for similar answers, see: http://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/1128

Thanks for listening. Taylor