Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using JRuby class supplied in a gem from Clojure

I am a fairly simple need to use a Ruby class from within Clojure. The complicating factors are that the class is supplied in a gem. The optimal approach would be to setup my Leiningein project file along the lines of:

(project foo ""
  ...
  :dependencies [[clojure ...]
                 [jruby ...  ]])

Likewise I would prefer to simply check the gem and its dependencies into the local repo directory. Therefore, from my ideal usage would then be:

(ns bar.baz
  (require [jruby.something :as jruby])

(def obj (jruby/CreateAnInstance "TheGemClass"))

(def result (jruby/CallAMethod obj "method_name" some args))

Thanks.

like image 484
fogus Avatar asked Aug 22 '12 13:08

fogus


1 Answers

Here's a short list of steps to get the hello-world gem running using JRuby and Clojure and a few references. In fact, the steps compose just a short sketch of how the material from the references might come together (with some project.clj entries). The first reference, Haml on Clojure Web App on Yoko Harada's (@yokolet's) blog, uses a slightly different way actually to call into JRuby, but includes the key remark on how to write require("...") lines for use with JRuby and gems on the classpath.

  1. Add [org.jruby/jruby-complete "1.6.7.2"] to your :dependencies and have Leiningen fetch the dependencies.

  2. Create a gems directory in the project root and add it to :resource-paths in your project.clj This requires Leiningen 2. See the Leiningen source for the correct format.

  3. Say

    # see reference 4
    GEM_HOME=gems GEM_PATH=gems java -jar ~/.m2/repository/org/jruby/jruby-complete/1.6.7.2/jruby-complete-1.6.7.2.jar -S gem install hello-world
    

    in the project root.

  4. Start up the REPL service of your choice with GEM_HOME and GEM_PATH set as above. (I tested this with lein2 swank.)

  5. Say the following at the REPL:

    ;;; see reference 2, first snippet
    (let [runtime (JavaEmbedUtils/initialize (list))
          evaler  (JavaEmbedUtils/newRuntimeAdapter)]
      (doseq [ruby-expr ["require('rubygems')"
                         "require('gems/hello-world-1.2.0/lib/hello-world')"]]
        (.eval evaler runtime ruby-expr)))
    
  6. Behold the nil return value, as well as a couple of lines printed out to the terminal the REPL service has been started from.

References:

  1. Haml on Clojure Web App on Yoko Harada's (@yokolet's) blog
  2. JRuby 1.1.6: Gems-in-a-jar on Nick Sieger's blog
  3. DirectJRubyEmbedding on the JRuby Wiki at Project Kenai
  4. consuming gems from jruby-complete here on SO (note the comments)
like image 66
Michał Marczyk Avatar answered Nov 15 '22 20:11

Michał Marczyk