# Getting Discourse running on JRuby

**URL:** https://meta.discourse.org/t/getting-discourse-running-on-jruby/81273
**Category:** Development
**Created:** [February 23, 2018, 12:14am UTC](https://meta.discourse.org/t/getting-discourse-running-on-jruby/81273 "2018-02-23T00:14:59Z")
**Posts on this page:** 17
**Page:** 1

<div class="post-metadata">

### Author: ![headius](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/headius/32/120277_2.png) [@headius](https://meta.discourse.org/u/headius)
#### Post date: [February 23, 2018, 12:14am UTC](https://meta.discourse.org/t/getting-discourse-running-on-jruby/81273/1 "2018-02-23T00:14:59Z")

</div>

Hello friends!

I work on the JRuby project, and have recently (a couple times in the past year) attempted to get Discourse running. It would mean you can run a single Discourse process for a whole site, and probably use less memory and CPU at the same time. I think it’s worth getting it to run.

As with most existing Ruby apps, there are a few missing C extensions.

The good news is that most of these extensions appear to have alternatives for JRuby, or they’re trivial enough that it should be easy to just make a JRuby version.

I wanted to start a discussion here so we can talk about some of the exts and possible replacements.

Any interest in Discourse on JRuby?

---

<div class="post-metadata">

### Author: ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)
#### Post date: [February 23, 2018, 12:23am UTC](https://meta.discourse.org/t/getting-discourse-running-on-jruby/81273/2 "2018-02-23T00:23:13Z")

</div>

Yes absolutely.

We really want to work with JRuby, what are the current stumbling blocks?

---

<div class="post-metadata">

### Author: ![headius](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/headius/32/120277_2.png) [@headius](https://meta.discourse.org/u/headius)
#### Post date: [February 23, 2018, 3:01am UTC](https://meta.discourse.org/t/getting-discourse-running-on-jruby/81273/3 "2018-02-23T03:01:37Z")

</div>

Here’s the diff I have at the moment. This is not an exhaustive list of extensions with no JRuby support but it’s most of them.

> <https://gist.github.com/headius/99f7a177b67d635d4783e7f7b164a3c9>

Some replacements I know of:

- fast\_xor has been superceded by xorcist, which has JRuby support.
- pg has a JRuby equivalent in pg\_jruby. It lags behind pg a lot (lack of resources).
- oj may have JRuby support soon; Tom Enebo has a partial port.
- cppjieba\_rb might be extended to support JRuby using the jieba-analysis Java library. I have started a dialog with the author here: [JRuby support using jieba-analysis library for Java · Issue #1 · erickguan/cppjieba\_rb · GitHub](https://github.com/fantasticfears/cppjieba_rb/issues/1)
- fast\_blank (transitive dependency of onebox) was trivial to port to JRuby. My PR is here: [JRuby support by headius · Pull Request #21 · SamSaffron/fast\_blank · GitHub](https://github.com/SamSaffron/fast_blank/pull/21)
- Presumably unicorn can just be replaced with puma. Both are in the Gemfile.

Other exts will have to be discussed.

---

<div class="post-metadata">

### Author: ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)
#### Post date: [February 23, 2018, 4:46am UTC](https://meta.discourse.org/t/getting-discourse-running-on-jruby/81273/4 "2018-02-23T04:46:56Z")

</div>

> [@headius](#):
>
> Presumably unicorn can just be replaced with puma. Both are in the Gemfile.

Yes this is totally safe, puma is supported. If we really want to conserve memory here though it may be interesting to run sidekiq inside puma.

> [@headius](#):
>
> fast\_blank (transitive dependency of onebox)

Oh … fast\_blank should not be a dependency for onebox, I just removed it, next release will not have it.

I think it probably makes sense just to not depend on fast\_blank for jruby and set the `fast_blank` dependency in Discourse to MRI only. `String` `@match?` does matching without needing to set globals so it should in theory be fast enough for jRuby.

> [@headius](#):
>
> oj may have JRuby support soon; Tom Enebo has a partial port.

Happy to make this MRI dependency only for now.

> [@headius](#):
>
> fast\_xor has been superceded by xorcist,

Oh, we should bench this if perf is the same we can move to xorcist

---

<div class="post-metadata">

### Author: ![headius](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/headius/32/120277_2.png) [@headius](https://meta.discourse.org/u/headius)
#### Post date: [February 23, 2018, 7:12pm UTC](https://meta.discourse.org/t/getting-discourse-running-on-jruby/81273/5 "2018-02-23T19:12:51Z")

</div>

> [@sam](#):
>
> Oh, we should bench this if perf is the same we can move to xorcist

The fast\_xor README actually says to use xorcist. I believe the code was simply moved there and expanded to support JRuby.

Here’s the complete list of exts with status as I know it today.

- bootsnap: [JRuby support · Issue #129 · rails/bootsnap · GitHub](https://github.com/Shopify/bootsnap/issues/129)
- fast\_blank: Should no longer be transitive dep of onebox, could be MRI-only in Gemfile, or could support JRuby. [JRuby support by headius · Pull Request #21 · SamSaffron/fast\_blank · GitHub](https://github.com/SamSaffron/fast_blank/pull/21)
- fast\_xor: Switch to xorcist. [GitHub - fny/xorcist: Blazing-fast-cross-platform-monkey-patch-free string XOR · GitHub](https://github.com/fny/xorcist)
- fast\_xs: This would be an easy port, or could possibly be omitted. [JRuby support · Issue #6 · brianmario/fast\_xs · GitHub](https://github.com/brianmario/fast_xs/issues/6)
- cppjieba\_rb: [JRuby support using jieba-analysis library for Java · Issue #1 · fantasticfears/cppjieba\_rb · GitHub](https://github.com/fantasticfears/cppjieba_rb/issues/1)
- libv8: Transitive dependency of mini\_racer. Replace with therubyrhino or the Nashorn equivalent?
- nokogumbo: Transitive dependency of sanitize. Library wrapper for Gumbo HTML5 parser. Probably could use FFI effectively…it’s very small. [JRuby support · Issue #24 · rubys/nokogumbo · GitHub](https://github.com/rubys/nokogumbo/issues/24)
- oj: Get Tom Enebo (or help him) to finish his port: [GitHub - enebo/oj: Optimized JSON · GitHub](https://github.com/enebo/oj)
- pg: Use pg\_jruby and improve it as needed.
- rinku: [JRuby support · Issue #75 · vmg/rinku · GitHub](https://github.com/vmg/rinku/issues/75)
- unicorn: Only needed on MRI.

I updated the gist I linked above, now excluding or replacing all the gems above. With these changes, bundle install completes.

I have no idea if Discourse actually _works_ yet though 🙂

---

<div class="post-metadata">

### Author: ![eviltrout](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/eviltrout/32/5275_2.png) [@eviltrout](https://meta.discourse.org/u/eviltrout)
#### Post date: [February 23, 2018, 7:22pm UTC](https://meta.discourse.org/t/getting-discourse-running-on-jruby/81273/6 "2018-02-23T19:22:00Z")

</div>

![giphy](https://global.discourse-cdn.com/meta/original/3X/4/9/490429371de9d603c77fe6d155445f7d811c449e.gif)

This is so exciting!

---

<div class="post-metadata">

### Author: ![codinghorror](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/codinghorror/32/110067_2.png) [@codinghorror](https://meta.discourse.org/u/codinghorror)
#### Post date: [February 24, 2018, 12:37am UTC](https://meta.discourse.org/t/getting-discourse-running-on-jruby/81273/7 "2018-02-24T00:37:24Z")

</div>

@sam any of the easy / obvious replacements we should do next week just to get more obstacles out of the way of this happening.

---

<div class="post-metadata">

### Author: ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)
#### Post date: [February 25, 2018, 11:37pm UTC](https://meta.discourse.org/t/getting-discourse-running-on-jruby/81273/8 "2018-02-25T23:37:27Z")

</div>

I just did this.

[https://github.com/discourse/discourse/commit/79e0cd7f529c14d482b2c5dc1394bc90d6070d56](https://github.com/discourse/discourse/commit/79e0cd7f529c14d482b2c5dc1394bc90d6070d56)

and

[https://github.com/discourse/discourse/commit/b301c9f6c12f517ee64e15599d7cac6ed2b9d7d8](https://github.com/discourse/discourse/commit/b301c9f6c12f517ee64e15599d7cac6ed2b9d7d8)

and

[https://github.com/discourse/discourse/commit/c234a14f0de458168adb5100cb7fd9d21a362d7d](https://github.com/discourse/discourse/commit/c234a14f0de458168adb5100cb7fd9d21a362d7d)

This leaves, cppjieba, libv8 / mini\_racer, nokogumbo, oj, pg and rinku

Regarding Rhino, you got to make sure the ruby rhino with latest [GitHub - mozilla/rhino: Rhino is an open-source implementation of JavaScript written entirely in Java · GitHub](https://github.com/mozilla/rhino) It looks pretty silent there [Commits · rubyjs/therubyrhino · GitHub](https://github.com/cowboyd/therubyrhino/commits/master) . Ideally I would prefer v8, but at a minimum we would want latest Rhino.

---

<div class="post-metadata">

### Author: ![kares](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/kares/32/120283_2.png) [@kares](https://meta.discourse.org/u/kares)
#### Post date: [February 26, 2018, 7:50am UTC](https://meta.discourse.org/t/getting-discourse-running-on-jruby/81273/9 "2018-02-26T07:50:49Z")

</div>

> [@sam](#):
>
> Regarding Rhino, you got to make sure the ruby rhino with latest GitHub - mozilla/rhino: Rhino is an open-source implementation of JavaScript written entirely in Java It looks pretty silent there Commits · cowboyd/therubyrhino · GitHub . Ideally I would prefer v8, but at a minimum we would want latest Rhino.

_therubyrhino_ should just work, if not there’s a pretty solid attempt to use the engine provided with Java 8,  
which is kind of a (direct) successor of Rhino, `gem 'dienashorner', platform: :jruby` … really depends what the JS engine is used for - if mostly for compiling with the asset pipeline than both are expected to work fine.

have also looked into _xorcist_, managed to run into one issue - not failing properly on frozen strings, but its pretty edge case that is easy to work-around + PR submitted.

---

<div class="post-metadata">

### Author: ![mcwumbly](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/mcwumbly/32/103861_2.png) [@mcwumbly](https://meta.discourse.org/u/mcwumbly)
#### Post date: [February 26, 2018, 2:40pm UTC](https://meta.discourse.org/t/getting-discourse-running-on-jruby/81273/10 "2018-02-26T14:40:05Z")

</div>

> [@sam](#):
>
> We really want to work with JRuby

Aside: can y’all share with those of us on the sidelines a little bit about _why_? Is the notion that JRuby would replace MRI as the default implementation for Discourse in the future if you get this working?

---

<div class="post-metadata">

### Author: ![headius](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/headius/32/120277_2.png) [@headius](https://meta.discourse.org/u/headius)
#### Post date: [February 26, 2018, 3:00pm UTC](https://meta.discourse.org/t/getting-discourse-running-on-jruby/81273/11 "2018-02-26T15:00:16Z")

</div>

That certainly isn’t my goal! JRuby would always be an alternative, and in some cases it may be a better choice than MRI for larger deployments. A single JRuby instance can handle an entire server load, maxing out all cores. If you are getting to the point of running 3 or 4 or 5 MRI instances, there may be a good case to try JRuby.

We also usually perform better, but that may take some tweaking early on.

---

<div class="post-metadata">

### Author: ![headius](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/headius/32/120277_2.png) [@headius](https://meta.discourse.org/u/headius)
#### Post date: [February 26, 2018, 4:12pm UTC](https://meta.discourse.org/t/getting-discourse-running-on-jruby/81273/12 "2018-02-26T16:12:59Z")

</div>

I realize looking at the Rinku README that it’s a drop-in replacement for Rails autolinking, which after 3.1 was pulled out as the rails\_autolink gem. I am looking into doing a port of Rinku, but simply using rails\_autolink works around this one right now.

```markdown
Rinku is a drop-in replacement for Rails 3.1 `auto_link`
----------------------------------------------------

Auto-linking functionality has been removed from Rails 3.1,
and is instead offered as a standalone gem, `rails_autolink`. You can
choose to use Rinku instead.

```

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [February 26, 2018, 4:18pm UTC](https://meta.discourse.org/t/getting-discourse-running-on-jruby/81273/13 "2018-02-26T16:18:52Z")

</div>

> [@kares](#):
>
> really depends what the JS engine is used for - if mostly for compiling with the asset pipeline than both are expected to work fine.

On Discourse, our **main** use for V8 is the markdown cooking.

Since we have a live preview and extensible markdown pipeline, we guarantee the same behavior on the browser and on server side by running the exact same code.

Our markdown library is [GitHub - markdown-it/markdown-it: Markdown parser, done right. 100% CommonMark support, extensions, syntax plugins & high speed · GitHub](https://github.com/markdown-it/markdown-it)

---

<div class="post-metadata">

### Author: ![headius](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/headius/32/120277_2.png) [@headius](https://meta.discourse.org/u/headius)
#### Post date: [February 26, 2018, 5:06pm UTC](https://meta.discourse.org/t/getting-discourse-running-on-jruby/81273/14 "2018-02-26T17:06:24Z")

</div>

I started porting Rinku and quickly realized that 99% of it is just raw C code working with character arrays.

So I started poking around for a Java autolinking library, and I found this: [autolink 0.8.0 javadoc (org.nibor.autolink)](http://javadoc.io/doc/org.nibor.autolink/autolink/0.8.0)

Even better, it accepts CharSequence, which means we should just be able to pass it a Ruby string (or one of our representations of it) and it will function mostly without pre-transcoding everything into Java characters.

I’ll see if I can get some basic API equivalent wrapper around it.

---

<div class="post-metadata">

### Author: ![headius](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/headius/32/120277_2.png) [@headius](https://meta.discourse.org/u/headius)
#### Post date: [February 26, 2018, 6:00pm UTC](https://meta.discourse.org/t/getting-discourse-running-on-jruby/81273/15 "2018-02-26T18:00:57Z")

</div>

I have enlisted the autolink-java author in our efforts: [Adapt autolink-java to replace rinku in JRuby · Issue #20 · robinst/autolink-java · GitHub](https://github.com/robinst/autolink-java/issues/20)

And I have done a proof-of-concept wrapper here: [GitHub - headius/jruby-autolink: A JRuby wrapper around the autolink-java library to provide autolinking like rinku · GitHub](https://github.com/headius/jruby-autolink)

So far…it works. But it does eventually create Java strings, so we may (or may not) want to adapt or fork this library to work with Ruby strings more directly.

---

<div class="post-metadata">

### Author: ![dfabulich](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/dfabulich/32/108716_2.png) [@dfabulich](https://meta.discourse.org/u/dfabulich)
#### Post date: [March 5, 2018, 8:06am UTC](https://meta.discourse.org/t/getting-discourse-running-on-jruby/81273/16 "2018-03-05T08:06:30Z")

</div>

Regarding Nokogumbo, I’d just like to say here that it seems bad that Discourse is using both Nokogiri _and_ Nokogumbo together.

Nokogumbo follows the HTML 5 parsing specification; Nokogiri is built on libxml2’s HTML 4 parser. They differ in behavior in ways that can introduce subtle bugs when handling tricky corner cases worked out during the development of the HTML 5 parser specification.

I recommend Nokogumbo over Nokogiri, because Nokogumbo matches what browsers do, and, more philosophically, because the HTML 5 parser is fully specified, as opposed to HTML 4 which left room for undefined behavior.

(It’s like the difference between kramdown and CommonMark.)

---

<div class="post-metadata">

### Author: ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)
#### Post date: [March 5, 2018, 8:25am UTC](https://meta.discourse.org/t/getting-discourse-running-on-jruby/81273/17 "2018-03-05T08:25:21Z")

</div>

Yeah I am totally for moving to nokogumbo if we can

One big concern though is that `Nokogiri::HTML5.fragment(string)` is considered “experimental” whatever that means.

Also, nokogumbo requires nokogiri, so there is that ;p

> <https://github.com/discourse/discourse/blob/main/Gemfile.lock#L194-L195>
