JRuby, Rails, and Jetty – Where Are my Assets?

Recently, I was spinning up an extremely simple Rails 4 project, which was to serve as a portal to several other applications deployed on the same Jetty instance. This was not my first JRuby on Rails rodeo, so I was expecting a smooth deployment.

When I deployed the WAR into a Jetty instance on my local machine, neither the CSS nor images were being served correctly. The application server was giving me a 200 return code with the correct content length header, and then giving me a zero-byte response. Having never encountered this issue before, I talked to my pair on the project, who was standing up a separate Rails 4 app for the same application server. He was seeing it too. We compared notes. Heads were scratched. Read more on JRuby, Rails, and Jetty – Where Are my Assets?…

Using OpenSAML from JRuby

We’ve had a lot of luck using JRuby on various different projects. One of the great advantages of JRuby is that you have the whole library of existing Java utilities at your disposal, plus all of the existing Ruby gems. I recently was able to integrate OpenSAML into a Ruby on Rails app. This was a great win because we needed functionality that wasn’t implemented in any of the Ruby SAML libraries.

However, what really struck me about it was that, even conflating the styles and conventions of both Ruby and Java together, the resulting code was more clean, readable, and terse than the original Java (in my opinion, at least.)

Below an example of creating a SAML message in Ruby using OpenSAML.

Read more on Using OpenSAML from JRuby…

Using Bundler with JRuby Complete

I am currently working on a project using JRuby for a server-side component. One of the team’s deployment goals has been to avoid relying on the production environment having JRuby installed in it (either globally or with RVM). Instead we have been using the jruby-complete.jar to bundle the entire JRuby runtime with our application. This post that argues for using jruby-complete still does a good job of explaining why this is a good thing (even if it is a few years old).

When starting this project, I already had a pretty good blueprint on how to run a Ruby application with jruby-complete. However, in the time since that post was written Bundler has become the defacto way of managing gem dependencies. In this post, I want to share how we are using jruby-complete with Bundler in our development and production environments.

Read more on Using Bundler with JRuby Complete…

Experimenting with Clojure’s PersistentHashMap in JRuby

Over the last few months, I have written two blog posts that mention using Hamster (Efficient, Immutable, Thread-Safe Collection) classes in JRuby: Preventing JRuby Concurrency Errors with Hamster and Making Refs in Ruby Using Celluloid Actors.

The latter post was commented on by Mike Busch he mentioned his evaluation of Hamster and comparing it to using Clojure’s persistent data structures in JRuby. He even linked to a simple benchmark for select he had done comparing the two.

Intrigued, I decided to to do some of my own experimentation and ended up extending Hamsterdam so it could use either Hamster Hashes or Clojure Maps internally. The results were mixed. The Clojure Map did turn out to be faster, but there are some (potentially annoying and confusing) side effects of using a Java collection as a primary data structure in JRuby.

Read more on Experimenting with Clojure’s PersistentHashMap in JRuby…

JRuby and vlcj – A Simple Full-Screen Media Player

I recently spent some time writing a simple program to play a movie file full screen on a Linux machine. I wrote the program in JRuby using the vlcj framework, which wraps the VLC media player library libVLC.

There are a number of vlcj fullscreen examples around, including an example that comes with the vlcj source code. I had not done much JRuby/Java interop work, so it still took some work for me to get this working in JRuby. To save someone else from the same problems, I thought I would share my work here.

Read more on JRuby and vlcj – A Simple Full-Screen Media Player…

JrSerialPort: Connect to a Serial Port in JRuby via RXTX

When porting some Ruby code over to JRuby for a prototype I’ve been working on recently, I ran into a small hiccup that I should have seen coming but wasn’t originally very worried about: my app talks over a serial port via ruby-serialport. The serialport gem is built with native code, as Bundler was kind enough to remind me; I couldn’t use its convenient interface in my new JRuby app.

So I hit Google, thinking surely — by now — someone has published a nice JRuby serial library. This is apparently not the case; while I did find an older (abandoned?) project called dgn110-jruby, there was a lot of code I knew I wouldn’t need, and the tests looked incomplete, so I kept looking.

Happily, Ian Dees wrote a neat PragPub article about testing Arduino code using JRuby and included example code for a nice little adapter to bridge Ruby code to the RXTX library. While Ian wasn’t attempting to make a fully-compliant replacement for serialport’s interface, it sure looked good enough for my needs, and easy to read and modify. I copied his code, tweaked the read/write methods to better suit my project, and I was back in business without any major modifications to the original prototype code.  Read more on JrSerialPort: Connect to a Serial Port in JRuby via RXTX…

Preventing JRuby Concurrency Errors with Hamster

I was recently working on a small proof-of-concept application with a back-end server written in JRuby. In this proof-of-concept, multiple clients connect to the server to poll for status changes and to request actions be performed as the result of user interactions.

The quickest way to keep the server responsive was to just fire up some threads to handle its various responsibilities. The bulk of the effort that went into the proof-of-concept was in the domain-specific technologies we were working with, not the ability of a server component to handle multiple clients in parallel. In other words, thread-safety was an afterthought.

But, as always seems to be the case when working with threads, I started running into trouble. Occasionally a request would fail and the following error could be found in the logs:

Detected invalid hash contents due to unsynchronized modifications with concurrent users

Read more on Preventing JRuby Concurrency Errors with Hamster…

Migrating Your JRuby Rails App Using warbler-exec

Deploying a JRuby on Rails application should be pretty easy thanks to Warbler. Simply package up your Rails app into a WAR file, place the .war file on the server, and you’re done.

Unfortunately, it’s not really quite that easy if you have any database migrations to perform. Thankfully, we can use the .war file itself to run the migrations, without needing to transfer another copy of the rails app specifically for this purpose. We’ll accomplish this using warbler-exec. Read more on Migrating Your JRuby Rails App Using warbler-exec…

Be Aware of jruby.launch.inproc

Heads up for those not aware: it’s not hard to get burned when you’re executing other Ruby processes from within a JRuby process.

Suppose you satisfy these conditions:

  • You’re running a Ruby program via JRuby.
  • Your program needs to execute another program via something like system or backticks.
  • The command for the new program looks like another Ruby program. Examples1:
    • `ruby -e 'puts "hi"'`
    • `jruby -e 'puts "hi"'`

Under these conditions JRuby will execute your program in a new JRuby instance within the running JVM process. This has the upside of reduced startup time for the new Ruby program. It has the downside of the occasional surprise—your program may assume it has its own process and not run correctly when sharing its process with other JRuby instances.

Read more on Be Aware of jruby.launch.inproc…

Bundle Your Torquebox Gems for Production

We recently decided to try Torquebox for a JRuby on Rails app we’re working on. We chose Torquebox for the same reason we chose JRuby: reduce external platform dependencies to maximize ease of deployment in heterogeneous environments. Getting it up and running in development was pretty straight forward. However, when we tried to get a production environment together we ran into some Bundler woes.

Read more on Bundle Your Torquebox Gems for Production…