Modify a Rails 5 project to run on both MRI and JRuby

It’s 2018 and running Rails on Windows is still as painful as many years ago. Probably because all the Ruby people love and use a Mac. JRuby is a good alternative to MRI and does not require building native extensions. This is a quick note on how to modify a Rails 5 project so that it runs on both MRI and JRuby.

Adding JRuby support, an iterative process

Throughout this guide we will be going through this process repeatedly.

  1. Run bundle install
  2. Hit an error because a gem that_mri_only_gem does not work on JVM and is trying to build native extension
  3. Modify Gemfile so that that_mri_only_gem is only included in mri platform
  4. If required, find a jvm compatible gem to replace it.

The pg gem

Most likely you are running a Rails project that uses PostgreSQL for data persistence. Modify Gemfile so that pg is only included with mri platform and use activerecord-jdbcpostgresql-adapter for jruby platform. At the time this article is written, support for activerecord 5.1.0 on activerecord-jdbcpostgresql-adapter is not yet released. We are using the latest code from master branch. This is not ideal, but works as a temporal workaround.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Index: Gemfile
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- Gemfile (revision 1d1022682e7a1bc3e15c9fa5f69b0e55a41fb860)
+++ Gemfile (date 1517590237009)
@@ -4,7 +4,8 @@
"https://github.com/#{repo_name}.git"
end
gem 'rails', '~> 5.1.4'
-gem 'pg', '~> 0.21.0'
+gem 'pg', '~> 0.21.0', platforms: [:mri, :mingw, :x64_mingw]
+gem 'activerecord-jdbcpostgresql-adapter', github: 'jruby/activerecord-jdbc-adapter', platforms: [:jruby]
gem 'puma', '~> 3.7'
gem 'jbuilder', '~> 2.5'
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

Other Rack servers

Rails 5 defaults to Puma web server, but you may have other web servers installed. Modify Gemfile to limit those to mri only.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Index: Gemfile
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- Gemfile (revision 1d1022682e7a1bc3e15c9fa5f69b0e55a41fb860)
+++ Gemfile (date 1517590237009)
@@ -32,7 +33,6 @@
gem 'unf'
gem 'twilio-ruby'
gem 'whenever', :require => false
-gem 'unicorn'
+gem 'unicorn', platforms: [:mri, :mingw, :x64_mingw]
source "https://gems.contribsys.com/" do
gem 'sidekiq-pro'
end

Debugging tools

If you are using byebug or pry, they don’t run on jvm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Index: Gemfile
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- Gemfile (revision 1d1022682e7a1bc3e15c9fa5f69b0e55a41fb860)
+++ Gemfile (date 1517590237009)
@@ -63,7 +63,8 @@
gem "mustache", "~> 1.0"
group :development, :test do
- gem 'pry-byebug'
+ gem 'pry-byebug', platforms: [:mri, :mingw, :x64_mingw]
+
end

Now your Rails project should be able to run on both MRI and JRuby, if it still doesn’t. Follow the iterative process and fix incompatiblity with replacement gems.