Nick Sieger: JRuby 1.1.6: Gems-in-a-jar tag:blog.nicksieger.com,2005:Typo Typo 2009-01-12T20:58:33+00:00 Nick urn:uuid:9d08015d-55b9-4438-918d-4aa9902ad694 2009-01-12T20:58:33+00:00 2009-01-12T20:58:33+00:00 Comment on JRuby 1.1.6: Gems-in-a-jar by Nick <p>Jay: I haven&#8217;t personally tried running a lot of gems out of a jar file yet&#46; JRuby is not yet fully consistent with all its file APIs in knowing how to manipulate file:// urls&#46; For example, the common practice of <code>require File.dirname(__FILE__) + '/../relpath'</code> is probably not going to work&#46; If you try stuff, please file bugs!</p> <p>As for deploying Adhearsion apps in an &#46;ear, that probably deserves a larger discussion in #jruby&#46; You need to tell me what kind of services and interfaces Adhearsion needs and provides, and we can figure out whether it should be in an &#46;ear, a &#46;war, or possibly just a standalone application (something like the last example)&#46;</p> Jay Phillips urn:uuid:df97c658-57ec-4cfa-9cf8-f5b5c0bc0c07 2009-01-11T18:59:39+00:00 2009-01-11T18:59:39+00:00 Comment on JRuby 1.1.6: Gems-in-a-jar by Jay Phillips <p>This is awesome, Nick! A few questions:</p> <ul> <li>How well does ActiveRecord play when running in a &#46;jar? I heard that the ActiveRecord&#8217;s model reloading logic broke down at one point due to the JAR filesystem using URIs for its files&#46;</li> <li>How different is the &#46;ear format from &#46;jar and&#46;&#46;&#46;</li> <li>&#46;&#46;&#46;does this now mean I can deploy Adhearsion apps as an &#46;ear file into a JEE container? :)</li> </ul> Andy Shen urn:uuid:8931bd77-3352-411e-adc2-760a27339542 2009-01-11T08:49:36+00:00 2009-01-11T08:49:36+00:00 Comment on JRuby 1.1.6: Gems-in-a-jar by Andy Shen <p>I started to try to make use of activerecord&#8217;s schema migration in Java projects &#46; Before this post I had to require users to set GEM_PATH but now I modified the jruby&#45;complete jar as you suggested and that should make deploying the tool much easier :)</p> <p>Thanks Nick&#46;</p> James Britt urn:uuid:7e590af2-bd44-4fda-b015-22e1b490654e 2009-01-10T22:16:13+00:00 2009-01-10T22:16:13+00:00 Comment on JRuby 1.1.6: Gems-in-a-jar by James Britt <p>This seriously rules&#46; Thanks!</p> Nick Sieger urn:uuid:924637a6-a799-47c7-be6c-986b51b86402 2009-01-10T20:04:00+00:00 2009-01-10T20:09:01+00:00 JRuby 1.1.6: Gems-in-a-jar <p>As a result of some fruitful hacking at RubyConf 2008, I was able to modify JRuby so that gems can be loaded and used without having to unpack them&#46; The feature became generally available with the <a href="http://docs.codehaus.org/display/JRUBY/2008/12/17/JRuby+1.1.6+Released">1&#46;1&#46;6 release last month</a>&#46; Gems in a jar!</p> <p><a href="http://flickr.com/photos/splorp/36991739/" title="Gem Jar"> <img src="http://farm1.static.flickr.com/26/36991739_48ab6e8fb7.jpg" alt="gemjar"/> </a></p> <div style="clear:both"></div> <p><span style="font-size:75%">by <a href="http://flickr.com/photos/splorp">splorp on flickr</a></span></p> <p>This opens up a couple new possibilities for running, packaging and deploying JRuby&#45;based applications&#46; Here are some ideas:</p> <h2>Run Gem&#45;based applications with <code>jruby-complete.jar</code></h2> <p>JRuby has <a href="http://jira.codehaus.org/browse/JRUBY-969">bundled Rake and RSpec since version 1&#46;0</a>&#46; As of JRuby 1&#46;1&#46;6 the versions we bundle are Rake 0&#46;8&#46;3 and RSpec 1&#46;1&#46;11&#46; With <a href="http://repository.codehaus.org/org/jruby/jruby-complete/1.1.6/jruby-complete-1.1.6.jar"><code>jruby-complete-1.1.6.jar</code></a> you can easily run these with <code>java -jar</code>:</p> <div class="typocode"><pre><code class="typocode_default ">$ java -jar jruby-complete-1.1.6.jar -S rake --help rake [-f rakefile] {options} targets... Options are ... $ java -jar jruby-complete-1.1.6.jar -S spec --help Usage: spec (FILE|DIRECTORY|GLOB)+ [options] -p, --pattern [PATTERN] ...</code></pre></div> <h2>Package gem collections into reusable jar files</h2> <p>One of the features I added was to enhance RubyGems to search for directories named <code>specifications</code> on the classpath and add them to the <code>Gem.path</code> automatically&#46; This means you can package up a whole gem repository into a jar file for easy reuse and sharing of commonly used gems&#46; There isn&#8217;t a tool for this yet, but the process is pretty straightforward&#46; (If someone plays with this and can come up with a patch to build this into JRuby, we&#8217;ll gladly accept one&#46;)</p> <p>First, create a gem repository by installing the gems you want into it&#46; Let&#8217;s say you want to package the natural language date/time parser <code>chronic</code>:</p> <div class="typocode"><pre><code class="typocode_default ">$ java -jar jruby-complete-1.1.6.jar -S gem install -i ./chronic chronic --no-rdoc --no-ri Successfully installed rubyforge-1.0.2 Successfully installed rake-0.8.3 Successfully installed hoe-1.8.2 Successfully installed chronic-0.2.3 4 gems installed</code></pre></div> <p>With this command, RubyGems created <code>chronic/bin</code>, <code>chronic/cache</code>, <code>chronic/gems</code>, and <code>chronic/specifications</code> directories and installed <code>chronic</code> and its dependencies into it&#46; Now, simply package those directories into a jar file:</p> <div class="typocode"><pre><code class="typocode_default ">$ jar cf chronic.jar -C chronic .</code></pre></div> <p>When you inspect the contents of the jar, you&#8217;ll see the gem repository structure in the root of the jar file:</p> <div class="typocode"><pre><code class="typocode_default ">$ jar tf chronic.jar | head META-INF/ META-INF/MANIFEST.MF bin/ bin/rake bin/rubyforge bin/sow cache/ cache/chronic-0.2.3.gem cache/hoe-1.8.2.gem cache/rake-0.8.3.gem</code></pre></div> <p>Chronic is now a re&#45;useable jar library that can be easily loaded, either by requiring the jar in ruby code or adding to the classpath:</p> <div class="typocode"><pre><code class="typocode_default ">$ # Without chronic.jar $ java -jar jruby-complete-1.1.6.jar -S gem list *** LOCAL GEMS *** rake (0.8.3) rspec (1.1.11) sources (0.0.1) $ # With chronic.jar $ java -jar jruby-complete-1.1.6.jar -rchronic.jar -S gem list *** LOCAL GEMS *** chronic (0.2.3) hoe (1.8.2) rake (0.8.3) rspec (1.1.11) rubyforge (1.0.2) sources (0.0.1)</code></pre></div> <p><strong>Note</strong>: Unfortunately this technique does not yet work with gems that include Java code in embedded jar files (e&#46;g&#46;, hpricot, mongrel, jruby&#45;openssl)&#46; See <a href="http://jira.codehaus.org/browse/JRUBY-3299">JRUBY&#45;3299</a>&#46; (We&#8217;d like to get this fixed for 1&#46;1&#46;7, but could use your help&#46;)</p> <h2>Bundle pure&#45;Ruby gem applications into an uber&#45;jar</h2> <p>Taking a cue from the previous techniques, we can stuff the gem directories into a copy of <code>jruby-complete-1.1.6.jar</code> rather than creating a new jar, and distribute an entire gem&#45;based application in a single file&#46; Imagine something like:</p> <div class="typocode"><pre><code class="typocode_default ">$ java -jar jruby-complete-1.1.6.jar -S gem install -i ./mycoolapp mycoolapp $ jar uf jruby-complete-1.1.6.jar -C mycoolapp . $ mv jruby-complete-1.1.6.jar mycoolapp.jar $ java -jar mycoolapp.jar -S mycoolapp</code></pre></div> <p>Bonus points to the enterprising individual who provides a patch to make this a one&#45;step process, including creating a mechanism to provide a default <code>-S</code> script so that <code>java -jar mycoolapp</code> is all that&#8217;s needed to run the application&#46;</p> <p>I hope you find interesting uses for this new feature&#46; Let us know what you make with it!</p>