«

»

Mar 02

Rails & JRuby in a Jar

For political reasons, I needed to ship a single jar file.  I didn’t want to have the overhead of a war & an appserver, so I set out to embed my rails app within a single jar file.  I needed to make some changes in order to get it to work.

This assumes Rails 2.3.5 and JRuby 1.4.0.

First, you need to create your rails app.   Freeze rails and any gems required.

Next download jruby-complete.  Once you’ve done so, unzip it.  I’m assuming you’ve unzipped it to complete.

Note: When you repackage the jar file, DO NOT use jar.  Use zip.  This is very important.  If you don’t, you’ll trash your jruby instance.

Copy your rails instance to complete/META-INF/jruby.home. I assume it will be complete/META-INF/jruby.home/rails.

Next create complete/META-INF/jruby.home/bin/server with the following content:

The RAILS_ROOT needs to be set in order to have the proper paths within the jar file.

Next, edit complete/META-INF/jruby.home/rails/vendor/rails/railties/lib/initializer.rb In the set_root_path method, edit it so it looks like this:

This is related to paths within the jar file.

Additionally, you need to change the initialize_logger method. (this might not be needed, see below). Change

to

The idea is to change it to something definitely outside the jar. The reason I did this, and didn’t change the config in environment.rb was that the changes in environment.rb were not getting picked up. I’ve since come to the belief that this is due to an issue with the Rack LogTailer detailed at https://rails.lighthouseapp.com/projects/8994/tickets/2350-logtailer-ignores-configlog_path. So complete/META-INF/jruby.home/rails/vendor/rails/railties/lib/rails/rack/log_tailer.rb needs to be edited. Edit the EnvironmentLog assignment to match the file we’d specified. (You may be able to substitute RAILS_DEFAULT_LOGGER but I have not tested that)

That’s pretty much it. Zip up your exploded jar from the complete directory: zip -r ../complete.zip *. Then you can run it via java -jar complete.jar -S server.

Enjoy!

7 comments

Skip to comment form

  1. Alexander Shvets

    Try to use warbler gem

  2. Matt Williams

    I am familiar with warbler.

    However, in this case, I didn’t want to create a war. I needed to deliver a single jar for political reasons and didn’t want the overhead of jboss or tomcat. Nor did I want to have to maintain the installation. Ergo, the exercise to create a single jar.

  3. Ale McHale

    Hey Matt! It’s funny that I would run into this today, as I was currently working on the same thing. I have basically the same thing running that you do … except I’m not quite done yet. I need to run multiple mongrels within the same process, as well as some other task threads running next to the mongrels.

    Anyhow, no need to reply. It was just cool to run into this the week I was working on the same thing :-).

  4. Alex McHale

    Wow, I just realized I misspelled my own name on that last post. Yikes.

  5. eyelash grower

    Thats a definitely good submit with essential Data. Many thanks for your assist.

  6. Prasanna

    Hi, I am currently working on integrating Java application General Architecture For Text Engineering (GATE) with Rails application using Jruby architecture. When we worked on integrating Jruby with log4j, I am getting following error :

    0 [main] DEBUG Main.class – Hello world gate/Gate.java:80:in ‘: java.lang.NoClassDefFoundError: org/apache/log4 j/Logger (NativeException) from gateapp/Main.java:86:inmain’ from test.rb:12

    test.rb is the name of ruby program.

    I tried importing all the log4j apache library, included the class file also in the test.rb file.

    When I run the java program alone its running fine. But when I generate the jar file and include them in ruby file (test.rb) , I am getting error that

    java.lang.NoClassDefFoundError: org/apache/log4j/Logger (NativeException) problem is occuring. How to deal with this problem ?

    Can anyone help me out over this issue ?

  7. Matt Williams

    I’d suggest taking a look at torquebox — it’s a jboss (hence log4j) with rails integration. You can find it at http://torquebox.org.

    Barring that, is log4j in your classpath?

Leave a Reply