One of the biggest pains of using jruby is the slow startup time.
For a trivial rails application, the startup is really painful:
1 2 3 4 5
Compare to the same project running MRI:
1 2 3 4 5
MRI is more than 20 times faster!
If You Can’t Ditch jRuby…
Because of deployment constraints and a small portion of the application depending on java classes, ditching jRuby altogether is not an option. However, having a fast TDD loop is essential, which is hard to do with startup times of more than 20 seconds. What if we could run individual specs in MRI and our integration specs and server in jRuby?
Platform specific gems in Bundler
Bundler supports specifying a platform when defining a gem, which allows to write a
1 2 3 4 5 6 7 8 9 10 11 12 13 14
This syntax allows us to run
bundle install on each platform and generate a
Gemfile.lock file. For simple projects, this approach is sufficient and one can switch rubies with no adverse effects.
However, for more complex projects the generated
Gemfile.lock for each platform is not the same, due to the fact that there are some platform specific gems being installed. In general, if you intend to add your
Gemfile.lock file (and you should in a Rails application), then this will cause your repo to be dirty constantly and endlessly having to delete the existing Gemfile.lock when changing rubies. Hardly ideal.
Multiple Gemfiles, But Not Really
Bundler also has support for using an environment variable
BUNDLE_GEMFILE for determining which Gemfile to use. In combination with some hackery, it make it possible to use the same
Gemfile but have platform specific lock files.
In order to start using mri for our project (jruby is the default):
Now, that shell is ready to roar and there is no interference in the
The difference between the lock files locks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24