<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Engine Yard Blog &#187; Thomas Enebo</title>
	<atom:link href="http://www.engineyard.com/blog/author/tomenebo/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.engineyard.com/blog</link>
	<description></description>
	<lastBuildDate>Tue, 07 Feb 2012 01:49:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>JRuby 1.6.6 is Released</title>
		<link>http://www.engineyard.com/blog/2012/jruby-1-6-6-is-released/</link>
		<comments>http://www.engineyard.com/blog/2012/jruby-1-6-6-is-released/#comments</comments>
		<pubDate>Mon, 30 Jan 2012 21:29:59 +0000</pubDate>
		<dc:creator>Thomas Enebo</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=11749</guid>
		<description><![CDATA[<p>The JRuby community is pleased to announce the release of JRuby 1.6.6.</p>
<ul>
<li>Homepage: <a href="http://www.jruby.org/">http://www.jruby.org/</a></li>
<li>Download: <a href="http://www.jruby.org/download">http://www.jruby.org/download</a></li>
</ul>
<p>The primary goal of the 1.6.x series is to round out our 1.9 support by fixing any reported incompatibilities. Of course, as with any JRuby release, we will continue fixing any found incompatibilities and also improve performance. All users of 1.6.5.1 (and lower) are encouraged to upgrade to 1.6.6.</p>
<p>Because master keeps getting further and further away from our 1.6 branch we have decided to make this our last 1.6 release. We largely fulfilled our goal of having reasonable 1.9 support. Follow up fixes for 1.9 support will only be fixed on master from this point forward. JRuby 1.7.0 will be the next release of JRuby.</p>
<h3 id="notable_changes">Notable Changes:</h3>
<ul>
<li>Updated stdlib to match Ruby 1.8.7p357 and 1.9.2p312</li>
<li>Updated RubyGems to 1.8.15</li>
<li>Multiple 1.9-mode yield/splat bugs fixed (pp, rspec 2.8 working again)</li>
<li>Multiple 1.9-mode encoding bugs fixed</li>
<li>Critical fixes in Random and Fiber</li>
<li>Map Scala operator methods to symbolic names ($plus, etc)</li>
</ul>
<h3 id="165_issues_resolved">1.6.5 Issues Resolved:</h3>
<ul>
<li>JRUBY-6386 time.localtime not taking any arguments</li>
<li>JRUBY-6384 yaml broken for last 1.6.6 build?</li>
<li>JRUBY-6383 Scala integration breaks with 1.6.6</li>
<li>JRUBY-6382 1.9: Padrino can’t generate an app</li>
<li>JRUBY-6381 java.util.Collection#each dose not respect to_ary defined by objects that are iteratered</li>
<li>JRUBY-6380 Original array is overwritten when select! is called on a copy</li>
<li>JRUBY-6377 rspec .should include() fails in –1.9 mode</li>
<li>JRUBY-6375 Uninformative YAML parser error</li>
<li>JRUBY-6373 ThreadError: Mutex is not owned by calling thread, when interrupting thread using a Ruby Mutex</li>
<li>JRUBY-6370 Regression in 1.6.6 in –1.9 mode</li>
<li>JRUBY-6367 –pre command line switch not working in 1.9 runtime</li>
<li>JRUBY-6366 More array splatting bugs in 1.9 mode</li>
<li>JRUBY-6361 RbConfig reports wrong OS type on Solaris</li>
<li>JRUBY-6359 Can’t convert nil to String building ActiveSupport RDoc in 1.9 mode</li>
<li>JRUBY-6354 SyntaxError: (RegexpError) invalid multibyte escape in 1.9 mode in the 50th iteration</li>
<li>JRUBY-6338 JRuby does not look for .jrubyrc in home directory on Windows</li>
<li>JRUBY-6324 random seed for srand is not initialized properly</li>
<li>JRUBY-6323 JRuby does not pay attention to either -U or LANG in determining encoding for ARGV (it is always ASCII-8BIT)</li>
<li>JRUBY-6319 ‘binding’ returns wrong binding</li>
<li>JRUBY-6318 Tempfile#open does not return the value of the block given to it</li>
<li>JRUBY-6307 Powering operation of Integer sometimes gets a wrong calculation when 1.9 mode.</li>
<li>JRUBY-6303 Cannot gem install from a remote repository in 1.9 mode</li>
<li>JRUBY-6295 Dir.chdir, $HOME and $LOGDIR behavior</li>
<li>JRUBY-6284 Calls to Kernel#exit result in an exception printed on stderr</li>
<li>JRUBY-6282 Colon is not allowed in a file name on Windows</li>
<li>JRUBY-6281 1.9: Applet does not work in the 1.9 mode</li>
<li>JRUBY-6272 Encoding exception running JRuby 1.6.5 (1.8 mode)</li>
<li>JRUBY-6233 jruby-complete-1.6.5.jar!/META-INF/jruby.home/bin/rake missing</li>
<li>JRUBY-6227 1.9: Struct#members and Struct::members should return an Array of Symbols in 1.9</li>
<li>JRUBY-6224 In MRI 1.9 the flag for Module#const_get also controls lookup of toplevel constants but not in JRuby</li>
<li>JRUBY-6217 Coverage module not working with Rails ActiveRecord associations</li>
<li>JRUBY-6214 Dir#rmdir raises improper exception if directory is not empty.</li>
<li>JRUBY-6212 IO#inspect in 1.9 could be prettier</li>
<li>JRUBY-6209 Hash#rehash does not work under some condition</li>
<li>JRUBY-6208 bad gem file creation using mode –1.9</li>
<li>JRUBY-6206 Incorrect SHA1 on two required packages in Maven Central</li>
<li>JRUBY-6205 ‘Bad file descriptor’ when using IO.popen4 with OpenJDK 7</li>
<li>JRUBY-6204 UTF-8 char in XML hangs in Joni</li>
<li>JRUBY-6202 JIT-ed class names only use method names, causing collisions</li>
<li>JRUBY-6201 File reading performance regression</li>
<li>JRUBY-6200 1.9: Loading some Unicode characters results in non-printable characters on Windows</li>
<li>JRUBY-6199 JRuby is hardcoded to use ‘-mmacos-version-min=10.4’ which is not compatible with ‘-rpath’ being used</li>
<li>JRUBY-6198 When calling dup on file open in binmode the new object does not respect binmode</li>
<li>JRUBY-6192 jruby::Handle declarations use ‘extern “C”’, causing linker symbol mismatches</li>
<li>JRUBY-6182 Marshal.dump yields different value after adding/removing instance variables (and disagrees with MRI)</li>
<li>JRUBY-6176 SecureRandom.uuid is not implemented</li>
<li>JRUBY-6173 pp is broken in –1.9 mode</li>
<li>JRUBY-6172 Requiring a file from a JAR that has a path inside the JAR that coincides with a path on the file system that includes a symlink fails</li>
<li>JRUBY-6171 Enumerable does not splat</li>
<li>JRUBY-6170 Fibers are broken in JRuby 1.6.5</li>
</ul>
<p><a href="http://www.engineyard.com/blog"><img height="98" width="61" title="logo-engineyard" alt="" class="attachment-post-thumbnail wp-post-image" src="http://www.engineyard.com/blog/wp-content/uploads/logo-engineyard.png"/></a></p>
]]></description>
		<wfw:commentRss>http://www.engineyard.com/blog/2012/jruby-1-6-6-is-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Special JRuby Release: 1.6.5.1</title>
		<link>http://www.engineyard.com/blog/2011/special-jruby-release-1-6-5-1/</link>
		<comments>http://www.engineyard.com/blog/2011/special-jruby-release-1-6-5-1/#comments</comments>
		<pubDate>Wed, 28 Dec 2011 19:25:01 +0000</pubDate>
		<dc:creator>Thomas Enebo</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=11453</guid>
		<description><![CDATA[<h2>For the Impatient</h2>
<ol>
<li><a title="Download JRuby" href="http://www.jruby.org/2011/12/27/jruby-1-6-5-1">JRuby 1.6.5.1</a> is a single patch release of JRuby 1.6.5 to fix CERT advisory: <a title="Details of CERT advisory" href="http://www.ocert.org/advisories/ocert-2011-003.html">CERT-201</a><a title="Details of CERT advisory" href="http://www.ocert.org/advisories/ocert-2011-003.html">1-003</a>.  ALL USERS: PLEASE UPGRADE</li>
<li>We talk about plans for the upcoming 1.6.6 release</li>
</ol>
<h2>CERT Details</h2>
<h3>Hashing 101</h3>
<p>(For proper CSci vocabulary and a lot of fun details about hashing also read this <a href="http://en.wikipedia.org/wiki/Hash_table">wikipedia</a> article)</p>
<p>Hash tables apply a math function (hashing function) to the key of a key-value pair. The result of the hashing function is a location to a hash bucket which stores the key/value pair internally:</p>
<pre escaped="true">a[:heh] = 1
hashing_function(:heh) -&gt; store :heh/1 in hash bucket #3
a[:foo] = 2
hashing_function(:foo) -&gt; store :foo/2 in hash bucket #13
a[:bar] = 3
hashing_function(:bar) -&gt; store :bar/3 in hash bucket #1</pre>
<p>Hashes have many buckets and in theory all key/value pairs added to a hash will get spread out evenly across the hashes buckets.  In practice, some number of keys will end up hashing into the same hash bucket (known as a hashing collision).  As you get more key/value pairs stored to the same hash bucket the time to access those particular key/value pairs will slow down.  This is because you need to walk some portion of the entries in the bucket to find the specific one you are looking for (hash structures will often make entries in an individual bucket a simple list structure).</p>
<pre escaped="true">a[:gar] = 4
hashing_function(:gar) -&gt; store gar/4 in hash bucket #3 (same bucket as :heh)</pre>
<p>In this example, accessing a[:gar] and a[:heh] may take longer than the other keys because they are sharing a hash bucket.</p>
<h3>The Attack</h3>
<p>The general application of the attack is for "the bad guys" to figure out a large set of values which will hash to the same hash bucket.  Once they create this list they will send all those values to a server.  The server will store them in a hash (think parameter list in Rack, for example).  The act of storing or accessing any of those values takes longer and longer as the number of entries in a single hash bucket grows.  The result will be a Denial Of Service (DOS) attack if enough values get stored.</p>
<pre escaped="true">hashing_function(:hostname) -&gt; hash bucket #3
hashing_function(:aZ1) -&gt; hash bucket #3
hashing_function(:cvg) -&gt; hash bucket #3
hashing_function(:azr) -&gt; hash bucket #3
... # many elided
hashing_function(:1fr) -&gt; hash bucket #3
hashing_function(:yu3) -&gt; hash bucket #3
hashing_function(:hyX) -&gt; hash bucket #3</pre>
<pre escaped="true">host = params[:hostname] # Uh oh! need to find this amongst many bucket buddies</pre>
<h3>The Fix</h3>
<p>Adding a little bit of randomization to the hashing algorithm ends up making it much, much more difficult to figure out how to generate this type of attack.  <a href="http://www.jruby.org/2011/12/27/jruby-1-6-5-1">JRuby 1.6.5.1</a> (and all later JRuby releases) all have this additional randomization built into the hashing algorithm.  The result should be decent hash bucket distribution that is difficult for attackers to predict.</p>
<h3>More information</h3>
<p>This vulnerability is not exclusively an issue of JRuby.  Other Ruby implementations also have a similar issue (also patched today).  In fact, Java and PHP also appear to be susceptible to this style of attack.  For more information, please see the <a href="http://www.ocert.org/advisories/ocert-2011-003.html">CERT</a> announcement.</p>
<p>Also, consider that language implementations are really only susceptible to this attack via frameworks which allow an external hacker to store arbitrary and/or unbounded key/values into a hash.  Ruby Rack had this vulnerability, but they have fixed things so that the amount of parameters stored is bounded by a size to remove the possibility of a DOS attack.  Rack users should upgrade to the latest version.</p>
<h3>JRuby's First Security Fix-Only Release</h3>
<p>We debated rolling what we have in our 1.6 branch along with the hashing vulnerability fix (mentioned above) and pushing out 1.6.6.  This was unappealing for a couple of reasons:</p>
<ol>
<li>For stable environments deployed using 1.6.5 we would be asking them to evaluate this security fix and any other fix we placed on JRuby 1.6 branch in the last two months.  This seems like it would force more conservative users to perform their own build to manually patch just the security fix.</li>
<li>Of bugs we have fixed so far we felt we were about 10 short of what we wanted to have in JRuby 1.6.6</li>
</ol>
<p>After consideration, we felt it best to give a security fix release now (A single security patch release <a href="http://www.jruby.org/2011/12/27/jruby-1-6-5-1">JRuby 1.6.5.1</a> &lt;--- update to this now please) to satisfy the cautious and to wait until we felt good about the quality of 1.6.6.  As they say, Open Source projects are ready when they are ready...</p>
<h2>Hey! When will you be ready? What is missing?</h2>
<p>It has been about two months since our last release and we suspect we can wrap things up in the next couple of weeks.  We plan on releasing JRuby 1.6.6 in mid-January.</p>
<p>As we have been saying all through the 1.6 series, we are primarily fixing 1.9 compatibility bugs.  Generally speaking, our 1.9 issue fixing has been dominated by encoding errors in Regexps, IO, and String.  Here is a <a title="Fixed for JRuby 1.6.6" href="http://jira.codehaus.org/secure/IssueNavigator.jspa?reset=true&amp;jqlQuery=project+%3D+JRUBY+AND+fixVersion+%3D+%22JRuby+1.6.6%22+AND+status+%3D+Open+ORDER+BY+priority+DESC&amp;mode=hide">list</a> of what we have done so far.  It is also worth mentioned we fixed the regression which regressed Fiber (JRUBY-6170) in JRuby 1.6.5.  Also the dreaded missing 'read_nonblock' has been fixed (JRUBY-5529).</p>
<p>Here is the <a href="http://jira.codehaus.org/secure/IssueNavigator.jspa?reset=true&amp;jqlQuery=project+%3D+JRUBY+AND+fixVersion+%3D+%22JRuby+1.6.6%22+AND+status+%3D+Open+ORDER+BY+priority+DESC&amp;mode=hide">list of issues</a> we are plan on settling for 1.6.6.  A few noteworthy mentions in this list is JRUBY-5657 (new 1.9 splat behavior), JRUBY- (new 1.9 to_ary behavior), and JRUBY-6067 (Windows YAML issue).</p>
<p>If there is some issue we don't have targetted but you think is drop-dead important then please let us know...We are willing to expedite other issues if presented with a reasonable case for why it should be fixed.  Please join the <a href="http://www.jruby.org/#4">discussion</a>.
<p><a href="http://www.engineyard.com/blog"><img height="98" width="61" title="logo-engineyard" alt="" class="attachment-post-thumbnail wp-post-image" src="http://www.engineyard.com/blog/wp-content/uploads/logo-engineyard.png"/></a></p>
]]></description>
		<wfw:commentRss>http://www.engineyard.com/blog/2011/special-jruby-release-1-6-5-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Join us in Baltimore!</title>
		<link>http://www.engineyard.com/blog/2011/join-us-in-baltimore/</link>
		<comments>http://www.engineyard.com/blog/2011/join-us-in-baltimore/#comments</comments>
		<pubDate>Fri, 06 May 2011 22:54:59 +0000</pubDate>
		<dc:creator>Thomas Enebo</dc:creator>
				<category><![CDATA[Events]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[bohconf]]></category>
		<category><![CDATA[eventmachinerubyconf]]></category>
		<category><![CDATA[Hackfest]]></category>
		<category><![CDATA[ignite railsconf]]></category>
		<category><![CDATA[RailsConf]]></category>
		<category><![CDATA[rubinius help desk]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=8759</guid>
		<description><![CDATA[<p>We're getting ready to head to Baltimore May 16-19, 2011 for RailsConf B'more: Round Two. We have some fun events planned. We hope you'll join us if you'll be there too.</p>
<h3>Ignite RailsConf</h3>
<p>Date: Monday, May 16, 2011<br />
Time: 6:00pm<br />
Location: Sheraton Inner Harbor, 300 South Charles St., Baltimore, MD 21201<br />
Expect: awesome 5 minute talks from 15 great speakers</p>
<p><a href="http://igniterailsconf.com/">Ignite RailsConf</a> is back again. <a href="http://igniterailsconf2.eventbrite.com/">Snag an Ignite RailsConf ticket</a> to partake in the fun. Dr. Nic will be doing "Ignite Karaoke" a guaranteed 5 minutes of humor as Nic presents slides he's never seen before. Oh, and don't forget to join us for the after-party at Max's Taphouse. Should be a blast.</p>
<h3>Ignite After-Party</h3>
<p>Date: Monday, May 16, 2011<br />
Time: 9:00pm on<br />
Location: <a href"http://www.maxs.com/index.php">Max's Taphouse</a>, 737 South Broadway, Baltimore, MD 21231<br />
Expect: delicious beer (800+ to choose from) and snacks</p>
<h3>JRuby Hackfest at <a href="http://www.bohconf.com/">BohConf</a><img style="float: right;" src="http://www.slsdev.net/bohconf/wiki_boh.png" alt="" /></h3>
<p>Date: Tuesday, May 17,  2011<br />
Time: 1:50pm-5:15pm<br />
Location: <a title="Bohconf website" href="http://www.bohconf.com/">BohConf</a> at the Baltimore Convention Center<br />
Bring:  questions, code, desire, your laptop<br />
Expect: answers, fun, hacking, beer, and snacks</p>
<p>At RailsConf 2008, in Portland, we had our first <a title="JRuby's Website" href="http://www.jruby.org">JRuby</a> hackfest.  Over 100 people showed up and we had a great time. It was cool to see applications leveraging Java technologies.  We met new users who wanted to try debug some issues running their applications on JRuby. We also had some folks who wanted to help contribute patches to JRuby. Mix in some some snacks, beer, and great people....OMGZ...the event totally rocked.</p>
<p>It is time for history to repeat.</p>
<h3>Rubinius Office Hours</h3>
<p>Brian Ford will be on-deck at RailsConf holding <a href="http://rubini.us/">Rubinius</a> help desk hours. If you have Rubinius questions, or want to share feedback about your experience with Rubinius, holler at <a href="http://twitter.com/#!/brixen">@brixen</a> in Baltimore or swing by the Engine Yard RailsConf booth to find out more Rubinius help desk details.</p>
<h3><a href="http://emrubyconf.com/">EventMachine RubyConf</a></h3>
<p>Last but not least, there's also some planning in the works for EventMachine RubyConf, a half day event that will take place during RailsConf. Time, date and location are being worked out and will be announced shortly. Watch <a href="http://twitter.com/#!/emrubyconf">@emrubyconf</a> for details.</p>
<p>See you at RailsConf, or another event soon!
<p><a href="http://www.engineyard.com/blog"><img height="98" width="61" title="logo-engineyard" alt="" class="attachment-post-thumbnail wp-post-image" src="http://www.engineyard.com/blog/wp-content/uploads/logo-engineyard.png"/></a></p>
]]></description>
		<wfw:commentRss>http://www.engineyard.com/blog/2011/join-us-in-baltimore/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>JRuby 1.6.0.RC2 Released</title>
		<link>http://www.engineyard.com/blog/2011/jruby-1-6-0-rc2-released/</link>
		<comments>http://www.engineyard.com/blog/2011/jruby-1-6-0-rc2-released/#comments</comments>
		<pubDate>Wed, 09 Feb 2011 22:02:58 +0000</pubDate>
		<dc:creator>Thomas Enebo</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[JRuby]]></category>
		<category><![CDATA[JRuby 1.6.0]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=7103</guid>
		<description><![CDATA[<p style="text-align: left;"><a href="http://www.engineyard.com/blog/wp-content/uploads/jruby-logo.png"><img class="alignright size-full wp-image-4623" title="jruby-logo" src="http://www.engineyard.com/blog/wp-content/uploads/jruby-logo.png" alt="" /></a>JRuby 1.6.0.RC2 has been <a title="Release Notes" href="http://www.jruby.org/2011/02/09/jruby-1-6-0-rc2">released</a>.  Here are the more notable things fixed since RC1:</p>
<ul>
<li>Large number of 1.9 compatibility issues addressed
<ul>
<li> Encoding issues (especially involving Regexp)</li>
<li> Fiddle implementation</li>
<li> non-ASCII identifiers</li>
</ul>
</li>
<li>irb (1.8.7, 1.9.2) and command prompt added to Windows installer</li>
<li>Compiler handles all 1.9 syntax now</li>
<li>Fixes for new backtrace accuracy, reliability</li>
<li>Removed all GPL or LGPL-only dependencies</li>
<li>Updated to RubyGems 1.5.0</li>
<li>C extension support prebuilt for OS X, Linux (32/64), Windows (32)</li>
<li>83 issues resolved since RC1</li>
</ul>
<p>Now some of you may be thinking...</p>
<p>RC2 had 83 resolved issues?  Are you sure RC are the proper letters for the last two releases?<span id="more-7103"></span></p>
<p>Hindsight is 20-20.  We knew 1.9 compatibility was not perfect, but during our RC1 release testing we were able to run all the major applications and libraries for a reasonable set of scenarios.   The truly surprising thing we realized after RC1 was released is how many people are ready for 1.9 support in JRuby.   The feedback has been tremendous and we decided it would make sense to spend extra time fixing reported issues.  After all, we want JRuby 1.6.0 to have solid Ruby 1.9.2 support.</p>
<p>Please (or should I say PLEASE) give <a title="Downloads for RC2" href="http://www.jruby.org/download">RC2</a> a spin and help us figure out if RC2 is good enough to become final.   Only people actively using JRuby’s --1.9 flag can help us figure this out (and of course any 1.8.7 bug reports are also welcome).  Your testing will make the difference between a production-ready 1.6.0 and a production-ready 1.6.1.</p>
<p>If you do find an issue you can report the problem on our <a title="JRuby Issue Tracker" href="http://jira.codehaus.org/browse/JRUBY">issue tracker</a>.  If you are a first-time reporter you will need to signup to be able to create an issue (follow tiny ‘sign up’ link underneath the Username field).
<p><a href="http://www.engineyard.com/blog"><img height="98" width="61" title="logo-engineyard" alt="" class="attachment-post-thumbnail wp-post-image" src="http://www.engineyard.com/blog/wp-content/uploads/logo-engineyard.png"/></a></p>
]]></description>
		<wfw:commentRss>http://www.engineyard.com/blog/2011/jruby-1-6-0-rc2-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JRuby on Windows</title>
		<link>http://www.engineyard.com/blog/2011/jruby-on-windows/</link>
		<comments>http://www.engineyard.com/blog/2011/jruby-on-windows/#comments</comments>
		<pubDate>Wed, 12 Jan 2011 19:44:49 +0000</pubDate>
		<dc:creator>Thomas Enebo</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[JRuby]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=5743</guid>
		<description><![CDATA[<p>Did you know that JRuby on Windows had no dependencies?  You don't even need Java installed.  You don't need another Ruby installed.  You can run our <a href="http://jruby.org.s3.amazonaws.com/downloads/1.6.0.RC1/jruby_windowsjre_1_6_0_RC1.exe">installer</a> and be creating Rails applications or Ruby GUI applications immediately.</p>
<p><img src="http://farm6.static.flickr.com/5047/5349616380_c5b60eb2f3.jpg" alt="Installer splash screen" /></p>
<h1>Well Duh!</h1>
<p>Micah Martin created a Windows installer for JRuby that made JRuby much easier to install. A new user can double click on the installer, get their PATH configured, install a JVM if they need one, and have a fully functioning Ruby environment in a matter of seconds. We played with it a bit and decided it was cool beans. The rest is history.  What we didn't count on was how popular Windows was as a platform.  To non-Rubyists this may sound patently stupid, but as Rubyists, we mostly ignore Windows.  Much to our surprise, we discovered that the number of Windows installer <a href="http://www.jruby.org/download">downloads</a> started to match the number of downloads for our generic tar and zip downloads of JRuby.  Cowabunga...people use Windows!?!!?</p>
<p>Seeing so many Windows installer downloads was a "well duh!" moment for us.  Ever since that day, we realized that as Rubyists we need to embrace Windows and make sure the Ruby Windows experience is pleasant.  I am going to talk about what JRuby is doing to make Windows developers happy, but I wanted to first try and make a rally cry to Rubyists everywhere...Please help make Windows a reasonable development platform choice.<span id="more-5743"></span></p>
<h1>Small Plea to Rubyists</h1>
<p>If you have ever been to a Ruby conference and stood at the front of the room you will make one fairly common observation:</p>
<p><img src="http://farm6.static.flickr.com/5289/5316998082_f7996457aa_z.jpg" alt="Pictures of Macs at conference" /></p>
<p>Macs Everywhere</p>
<p>In the public Ruby world, a Mac laptop seems like a prerequisite to membership (full-disclosure: I have been using Mac notebooks for 4-5 years).  Much to Apple's credit they make very nice laptops.  I think the bigger picture is seeing a laptop with 13% of the market share making up 95+% of a Ruby conference indicates a significant problem.  If you are a Mac-using fork()-wielding Rubyist why should you care about Windows users?</p>
<p>The most obvious answer to why you should care is market share.  There are a tremendous number of businesses which do their day-to-day work on a Windows OS.   If these Windows-using companies adopt Ruby then there are more job opportunities for all of us.</p>
<p>A less dog-eat-dog motive is wanting to share something you love.  I love using Ruby and I think any programmer, regardless of OS, should have the opportunity to use Ruby.</p>
<p>"Ruby cares" (faint PSA music in the background)</p>
<p>Okay, stepping off the soap box a little...</p>
<p>If you want to help, what can you do?  Of course you can start using Windows, but odds are, you bought a Mac to avoid using Windows.  ;)</p>
<p>Still, you can do several things:</p>
<ul>
<li>Be helpful to anyone who submits a Windows patch to your library/application.  Ultimately, little bugs here and there will make or break Ruby adoption on Windows.</li>
<li>Look for unix-y Ruby commands like fork() and consider alternatives like <a href="https://github.com/headius/spoon">spoon</a>.  We can blame some of the unix-parentage of Ruby for this, but a little effort to make your code portable will make a big difference.</li>
<li>Of course, some libraries may never run on Windows.  In that case, please mention that on your project's homepage.  Perhaps even put a hook in your code to throw an error when being loaded from Windows.</li>
</ul>
<pre escaped="true">require 'rbconfig'
if RbConfig::CONFIG['host_os'] == "mswin32"
    raise LoadError.new "This library does not work on Windows"
end</pre>
<ul>
<li>Make sure you are using libraries like <a href="http://ruby-doc.org/stdlib/libdoc/pathname/rdoc/index.html">Pathname</a> which should help isolate you from writing Windows-unfriendly things like:</li>
</ul>
<pre escaped="true">def absolute?(filename)
    filename =~ /^\//
end</pre>
<p>You can instead rely on Pathname to do the right thing for you:</p>
<pre escaped="true">require 'pathname'
Pathname.new("c:/").absolute?  # =&gt; true</pre>
<p>If you find yourself making assumptions about files or filesystems, odds are your code will not work on Windows.</p>
<ul>
<li>Test your library on a continuous integration (CI) server running on Windows (a little more on this below).</li>
</ul>
<h1>What we are doing</h1>
<p>We are on a never-ending quest to improve our Windows support for JRuby.  Lately, we have been spending some portion of our development week dog-fooding on Windows.  This has been a boon for finding issues, and we will continue this practice for the foreseeable future.</p>
<p>Beyond dog-fooding, we have recently set up a <a href="http://ci.jruby.org">CI</a> instance running Windows (a long-desired item for us).  We finally have quick feedback when we break something on Windows.</p>
<p><img src="http://farm6.static.flickr.com/5049/5349062657_5583cda6c7.jpg" alt="Windows CI progress" /></p>
<p>If you are interested in making your gem work on Windows, you can contact us and we will let you run your library on our CI box for a while to get it in shape for Windows.  (We would extend the offer forever, but we only have so much processing power.)  This can be a valuable experience in understanding some of the issues in making your code more portable.  Take us up on the offer.</p>
<p>We also wrote a native version of the windows-specific extension win32ole with funding from Audentes Technologies (thanks guys).  For those unfamiliar with win32ole, it is a library which allows you to connect to Windows applications and services and call them progmatically.  For example, in a few lines of Ruby you can connect up to MS Word, load a document, and then save it as an HTML document.   <a href="http://www.engineyard.com/blog/2011/jruby-1-6-0-rc1-released/">JRuby 1.6</a> will bundle win32ole in our windows installer.  It is also released as a gem so you can update to the latest and greatest when fixes come out.</p>
<p>As some level of proof we have been working hard on Windows support, a majority of 1.5.x issues resolved have been Windows-related.  We are going to keep polishing things until we get it right.</p>
<h1>What will we do next?</h1>
<p>We wanted to share some of our future Windows plans in the hopes people will have feedback and suggestions.  Our next big project on Windows will be to make an 'all-in-one' installer. This installer will contain all the necessary stuff needed for a new Windows developer to go from zero to Rails.  We plan on including the following in the new installer:</p>
<ul>
<li>JRuby</li>
<li>JVM</li>
<li><a href="http://redcareditor.com/">Redcar</a> editor (sweet Textmate clone)</li>
<li>Gems: Rails, Rake, RSpec, Rubygems, AR-JDBC</li>
<li>Simple Rails tutorials</li>
<li>Links to common Rails/Ruby websites</li>
</ul>
<p>Our hope is that this will help give a new Windows developer a positive experience.  Hitting lots of little roadblocks is no way to get introduced to a new technology.</p>
<h1>Let's become a big tent</h1>
<p>If you are a Windows person reading this, hopefully you can see that we are trying to make sure you have a top-notch Ruby runtime at your disposal.  You can help form our future by giving us feedback on your experience.  We really appreciate you giving us a try.</p>
<p>If you are not a Windows person, then hopefully you are on-board with the idea that Ruby should run well on Windows.  I believe it is one of our largest potential growth factors, and we have definitely not given an appropriate amount of support on Windows.  (Note: There are some heroic souls like Luis Lavena on the Ruby C impl side who are trying -- my hat goes off to them in fighting the good fight).</p>
<p>Let's make 2011 the year we start seeing more Windows laptops at conferences!
<p><a href="http://www.engineyard.com/blog"><img height="98" width="61" title="logo-engineyard" alt="" class="attachment-post-thumbnail wp-post-image" src="http://www.engineyard.com/blog/wp-content/uploads/logo-engineyard.png"/></a></p>
]]></description>
		<wfw:commentRss>http://www.engineyard.com/blog/2011/jruby-on-windows/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Rake and Ant Together: A Pick It n&#8217; Stick It Approach</title>
		<link>http://www.engineyard.com/blog/2010/rake-and-ant-together-a-pick-it-n-stick-it-approach/</link>
		<comments>http://www.engineyard.com/blog/2010/rake-and-ant-together-a-pick-it-n-stick-it-approach/#comments</comments>
		<pubDate>Fri, 19 Feb 2010 19:00:29 +0000</pubDate>
		<dc:creator>Thomas Enebo</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[ant]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JRuby]]></category>
		<category><![CDATA[Rake]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=3432</guid>
		<description><![CDATA[<p>Recently, I landed a new library for JRuby that will be part of JRuby 1.5. Before I start I want to conjure the image you see below this text: that's Right!  Mr. Potato Head: a role model for us all. Something that delights us for hours (or at least, probably <em>did</em>, at one point in our lives), is flexible, and is not <em>only</em> a toy, but also a starchy food product.</p>
<div style="float: right; width: 400px; overflow: hidden; background: none repeat scroll 0% 0% #cccccc; text-align: center; clear: right; font-size: 75%; color: #666666; padding: 0pt 0pt 10px; margin: 10px 0pt 10px 10px;"><img style="margin: 0;padding: 10px" src="http://farm4.static.flickr.com/3158/2997761212_177aaac05b.jpg" alt="" width="360" height="239" />Mister Potato Head<br />
(Courtesy of Flickr user <a href="hthttp://www.flickr.com/photos/mymollypop/">MyMollyPop</a>)</div>
<p>Bear with me for a second, and excuse what must have just sounded like a wee bit of lunacy. The the truth is, we live in a world where, as programmers, we construct Mr. Potato Heads every day. We're confronted with making software where not <em>only</em> are we required to stick various elements together, but also to arrange them in the most pleasing way possible.  Software design is really just <em>like </em>decorating a potato. The potato of this blog entry will be build software.</p>
<h1>Build Tools</h1>
<p>In the Java world, Ant is the 800 pound potato of build tools.  It's in virtually <em>every</em> Java build environment on the planet.  To date, I have only really known one person who really really liked Ant.</p>
<p>For the most part, I think people respect Ant as a tool which is a bit syntactically gross, but which gets the job done reliably.  It is also lamented for having little support for imperative programming constructs. This seems to have been by design, but it doesn't seem to make very many programmers <em>happy</em>.</p>
<p>In the Ruby world we have Rake. Rake, by contrast, has a much nicer syntax than Ant. It also allows any construct that the Ruby language allows, since Rake is just a DSL-like API for building software running in a Ruby interpreter. On the other hand, if you have the need to perform common tasks in the Java world, then it lacks a bunch of standardized cross-platform tasks that Ant contains. You find yourself breaking out into lots of icky shell commands (`javac -classpath #{my_files}`) and this works great until you try and build something on, gasp, <em>Windows</em>.</p>
<p>A pragmatic (but not so great) reality is that most Java shops may warm to switching to a different build technology, but are unlikely to switch over projects <em>en masse</em>. Even if they were enough in love with Rake to switch, they'd need to hobble together replacements for tasks that they take for granted in Ant. That is... until now.</p>
<h1>Use Cases</h1>
<p>JRuby's Rake and Ant integration handles the following use cases:</p>
<ul>
<li>Call any ant task or type from within Rake</li>
<li>Allow Rake to be invoked from within Ant</li>
<li>Allow Rake tasks to be imported as callable Ant targets</li>
<li>Allow Ant to be invoked from Rake</li>
<li>Allow Ant targets to be called as Rake tasks from within Rake</li>
</ul>
<p>Let's break these down one at a time...</p>
<h2>Call Any Ant Task or Type From Within Rake</h2>
<p>The truth is, Ant is really just a built-in library in JRuby. You could just write a script and not use it in Rake:</p>
<pre>require 'ant'

ant do
  build_dir = "java_build" # Regular Ruby variables interact fine

  # But defining and consuming Ant properties is fine
  property :name =&gt; "src.dir", :value =&gt; "java_src"

  path(:id =&gt; "project.class.path") do
    pathelement :location =&gt; "classes"
  end

  mkdir :dir =&gt; build_dir

  javac(:destdir =&gt; build_dir) do
    classpath :refid =&gt; "project.class.path"
    src { pathelement :location =&gt; "${src.dir}" }
  end

  jar :destfile =&gt; "simple_compile.jar", :basedir =&gt; build_dir
end</pre>
<p>This example constructs an instance of an Ant project, then makes a directory, compiles some Java source, and finally, generates a jar file of the results. All of these are just Ant tasks. They'll work on any platform. Sweet, I say! This does, however, lack dependency management.  So let's use Rake to do it instead:</p>
<pre>require 'ant'

build_dir = "java_build"
file build_dir

task :setup =&gt; build_dir do
  ant.property :name =&gt; "src.dir", :value =&gt; "java_src"
  ant.path(:id =&gt; "project.class.path") do
    pathelement :location =&gt; "classes"
  end
end

task :compile =&gt; :setup do
  ant.javac(:destdir =&gt; build_dir) do
    classpath :refid =&gt; "project.class.path"
    src { pathelement :location =&gt; "${src.dir}" }
  end
end

task :jar =&gt; :compile do
  ant.jar :destfile =&gt; "simple_compile.jar", :basedir =&gt; build_dir
end

task :default =&gt; :jar</pre>
<p>[Quick note: since we can combine the best of both worlds, you don't need to ever set an Ant property if you don't want to. Just use a Ruby variable or constant. Different folks for different strokes...]</p>
<p>This snippet shows how easy it is to consume Ant tasks in a Rakefile. Really, JRuby's Ant library is just a straight-forward set of APIs that map clearly to Ant's original syntax. Looking up how to do something is a very straight-forward task.</p>
<p>The other benefit mentioned above is that Rake can use imperative programming in it. Let's consider a snippet like this in Ant:</p>
<pre>      &lt;java classname="${mainclass}"&gt;
        &lt;arg value="--command"/&gt;
        &lt;arg value="maybe_install_gems"/&gt;
        &lt;arg value="--no-ri"/&gt;
        &lt;arg value="--no-rdoc"/&gt;
        %lt;arg value="--env-shebang"/&gt;
      &lt;/java&gt;</pre>
<p>It can use imperative conveniences:</p>
<pre>command = "--command may_install_gems --no-ri --no-rdoc --env-shebang"
ant.java :classname =&gt; "${mainclass}" do
  command.split(/\s+/).each { |value| arg :value =&gt; value }
end</pre>
<p>So if you're a Rake user already and you need to do Java things, then using this support should be a pretty simple decision. Heck, there are many other optional Ant tasks that may be useful even if you're <em>not</em> doing Java things.</p>
<h2>Allow Rake to be Invoked From <em>Within</em> Ant</h2>
<p>If you have the ability to write the equivalent of an Ant project using Rake, then you may want to make part of your project driven by Rake.  However, if you do this, you may <em>still </em>need to call it from within Ant.  We can do this with the new 'Rake' task.</p>
<p>If we pretend the previous Rakefile existed parallel to a build.xml file we have then in that Ant's build.xml file we could have:</p>
<pre>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;project name="foobar" default="default" basedir="."&gt;
  &lt;description&gt;Builds, tests, and runs the project foobar.&lt;/description&gt;

  &lt;target name="load-rake-task"&gt;
    &lt;taskdef name="rake" classname="org.jruby.ant.Rake"/&gt;
  &lt;/target&gt;

  &lt;target name="default" depends="load-rake-task"&gt;
    &lt;rake task="jar"/&gt;
  &lt;/target&gt;

  ...
&lt;/project&gt;</pre>
<p>This Ant script's 'default' target will load our Rake task and then call Rake (file defaults to 'Rakefile'), and more specifically, call the task 'jar' (task defaults to 'default').  There are a couple of cool scenarios to consider here:</p>
<p><strong>1. Try Rake by only dipping your toes in the water</strong></p>
<p>This strategy is great if you like Rake but are worried you don't have enough influence to get your development team to switch their entire build suite. You can just stick a Rakefile off to the side for some new functionality and let your teammates evaluate how much they like it. If they <em>do</em>, then switch the rest later... or don't. The idea that most Java shops will big-bang change their build software is extremely unlikely. An incremental strategy is your best bet.</p>
<p><strong>2. Easier integration with Java tools</strong></p>
<p>Even if you're totally sold on Rake, you still need to know that software like NetBeans expects to see a build.xml file, so it can interact with your project. Having a small shim like the one above makes you play nice with any tools that<em> expect</em> Ant.</p>
<p>This is the simplest way to call Rake from Ant, but the next option may suit your needs better...</p>
<h2>Allow Rake Tasks to be Imported as Callable Ant Targets</h2>
<p>The big missing feature of the Rake task in the script above is that it's only one-way.  You can call Rake, but then the Rakefile you call has no meaningful interaction with the Ant side of things.  Sure it can <em>call</em> Ant tasks, but it can't see properties or Ant targets that are defined in the calling build.xml file.</p>
<p>To have better interoperability we have another Ant task: RakeImport.  RakeImport will require the specified Rakefile and then register all of its tasks with Ant dependency management system.  Let's look at a simple example:</p>
<pre>&lt;?xml version="1.0" encoding="UTF-8"?&gt;

&lt;project name="foobar" default="top-level" basedir="."&gt;
    &lt;description&gt;Builds, tests, and runs the project foobar.&lt;/description&gt;

    &lt;taskdef name="rakeimport" classname="org.jruby.ant.RakeImport"/&gt;
    &lt;rakeimport/&gt;

    &lt;target name="top-level" depends="its_in_rake" /&gt;

    &lt;target name="its_in_ant"&gt;
      &lt;echo message="ant: its_in_ant"/&gt;
    &lt;/target&gt;
&lt;/project&gt;</pre>
<p>In Ant, we specify that we want to use RakeImport and then immediately call it.  This loads the following Rakefile and registers all of its tasks with Ant:</p>
<pre>task :its_in_rake =&gt; [:setup, :its_in_ant]  do
  puts "it's in Rake"
end

task :setup do
  puts "setup in Rake"
end</pre>
<p>Now let's run 'ant top-level'; we now see the following output:</p>
<pre>Buildfile: build.xml
[rakeimport] (in /Users/enebo/work/akakamiari/samples/rake_import_example2)

setup:
setup in Rake

its_in_ant:
     [echo] ant: its_in_ant

its_in_rake:
it's in Rake

top-level:

BUILD SUCCESSFUL
Total time: 7 seconds</pre>
<p>This output shows that it's executing both Ant targets and Rake tasks in the desired order.  its_in_ant executes as a dependency of its_in_rake which in turn executes because it is a dependency of the Ant target 'top-level'.</p>
<p>The scenarios for this level of integration:</p>
<p><strong>1.  Choosing the best tool</strong></p>
<p>Since Rake gives a full imperative programming environment there are some things that are trivial to do in Rake which are cumbersome (or impossible without writing a custom Ant task) in Ant.  You can move that stuff into Rake, but still continue using Ant for everything else.</p>
<p><strong>2. Toe wet... time to go waist deep</strong></p>
<p>In the previous section we used the Rake task to demonstrate to your development group that Rake is useful.  This allows you to start depending on the capabilities of Rake more by being able to inject Rake tasks into the Ant dependency graph.  Your group is still using Ant as the main build tool, but you're delegating more of the build to Rake.</p>
<h2>Allow Ant to be Invoked From Rake</h2>
<p>Let's look at things from the other side of the coin.  If you're already a Rake user, but you need to interact with existing Ant build files, we've also got solutions for <em>you</em>.  The first method allows you to just call Ant from within Rake:</p>
<pre>task :call_ant do
  ant '-f my_build.xml my_target1'
end</pre>
<p>Alternatively, you can also supply arguments as a list:</p>
<pre>args = ['-f', 'my_build.xml', 'my_target1']
task :call_ant do
  ant args
end</pre>
<p>Believe it or not, this doesn't just execute `ant`; it loads it into your JRuby environment.  This is nice because it doesn't spawn a second JVM to run Ant.</p>
<p>As I mentioned at the beginning of this section, you may want to just call into Ant, but not have any more interaction than that.  That's ok, but if you want more....</p>
<h2>Allow Ant Targets to be Called as Rake Tasks From Within Rake</h2>
<p>'ant_import' beats 'ant' in flexibility because it ends up registering all of Ant's top-level targets with Rake's dependency management system.  Once you import an Ant file into Rake, you can call the Ant tasks as if they were ordinary Rake tasks.  A simple example:</p>
<pre>task :ant_import do
  ant_import
end

task :compile =&gt; [:ant_import, :its_in_ant_setup] do
  # Do some compilation
end</pre>
<p>This example will load ant_import when the compile task is executed which will in turn load the build.xml file in the current directory and load all of its Ant targets. I did not ant_import at the top-level of the Rakefile to show that you may only want to load the Ant targets if you are actually planning on using them.</p>
<h1>Details Details</h1>
<p>This code has just landed in JRuby trunk.  All of the examples listed here should work, but this code is brand new.  It's a work in progress that will firm up by the time JRuby 1.5 is out.  So this means two things for the reader:</p>
<p><strong>1. You can help find problems and help improve the library</strong></p>
<p>In other words, if this interests you, then you can get involved early and help address problems or enhance the library.  Odds are you can make the difference between this integration being <em>great</em> or merely good.</p>
<p>Getting started note: the current practice for running the examples above is to copy jruby-complete.jar into $ANT_HOME/lib. You can manually set your classpath to include jruby-complete.jar as well, but I found it less error prone to just copy the jar.</p>
<p><strong>2. If you don't like unfinished software then wait for 1.5</strong></p>
<p>Some people don't like the hassles or have the time to play with unfinished software.  If you're in this position, then don't worry. We'll get things working nicely for 1.5.  We don't want an early test run to ruin anyone's expectations.</p>
<h1>Conclusion</h1>
<p>Going back to our original Mr. Potato Head theme, I was hoping to show that sometimes combining things together really <em>is</em> the best strategy.  In theory, it's nice to start over and make something pure and wonderfully homogenous.  In practice, there are always pesky real-life details that get in the way.  Why rewrite everything when you can just attach the new technology on the side?  If you do have the long term goal of replacing an older technology, why not do it incrementally?  Every big-bang rewrite project I have ever been in has basically failed in a significant way.  Change things one piece at a time and your chances of success are much higher.</p>
<p>Our new Rake/Ant integration is meant to allow incremental change, or at least to allow the best features of each tool to be used together.  It embodies the reality that both tools may be necessary and that replacing one for the other probably won't be a 100% solution.</p>
<p>As always, questions and comments are welcome!
<p><a href="http://www.engineyard.com/blog"><img height="98" width="61" title="logo-engineyard" alt="" class="attachment-post-thumbnail wp-post-image" src="http://www.engineyard.com/blog/wp-content/uploads/logo-engineyard.png"/></a></p>
]]></description>
		<wfw:commentRss>http://www.engineyard.com/blog/2010/rake-and-ant-together-a-pick-it-n-stick-it-approach/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>J is for JVM: Why the &#8216;J&#8217; in JRuby?</title>
		<link>http://www.engineyard.com/blog/2009/j-is-for-jvm-why-the-j-in-jruby/</link>
		<comments>http://www.engineyard.com/blog/2009/j-is-for-jvm-why-the-j-in-jruby/#comments</comments>
		<pubDate>Mon, 30 Nov 2009 17:00:49 +0000</pubDate>
		<dc:creator>Thomas Enebo</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[JRuby]]></category>
		<category><![CDATA[JVM]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=2943</guid>
		<description><![CDATA[<p>The current JRuby team members are all passionate hackers with intimate knowledge of Ruby, Java, and of course JRuby. That said, none of us were on the team at the project's original inception. I assume the JRuby pioneers thought JRuby would be a good idea—I know <em>I</em> did, when I first heard about it. For a lot of folks though, it's somewhat less obvious. Why is writing JRuby on top of the JVM a good idea, they ask. Are we nuts, evil geniuses, or is using the JVM just a solid <em>pragmatic</em> decision?</p>
<p>When Java first came out it was a nice incremental improvement over languages at the time. Not only was Java a reasonably simple, yet evolutionary language (vs. C or C++) but it was also a virtual machine that ran a fake non-hardware-specific bytecode (e.g. hardware-neutral). It was garbage collected, so memory management and core dumps suddenly became a minor concern. It also had a reasonably comprehensive class library. No new unique features, but a good combination of ideas packaged into something useful.</p>
<p>In an attempt to market Java as a simple single-named entity, though, I think Sun made a long-term marketing mistake. It co-mingled the language and the runtime under the same name. This did a huge injustice to the runtime because the Java Virtual Machine (JVM) is remarkable on its own merits. It has also made it difficult for alternative JVM language projects like Jython or JRuby to explain the virtues of the JVM without confusing it with the Java <em>language</em>.</p>
<p>This post will focus on the good and the bad of the JVM, and by the end of this entry, I'm hoping you'll appreciate all the JVM has to offer.</p>
<p>One final note before I delve further: this will just cover what I know about <em>Sun's</em> JVM. There are a few other JVMs out there and they're all remarkable in their own right. Many of my points no doubt also apply to those VM implementations, but my lack of intimate knowledge of them compels me to disclaim :)</p>
<h2><strong>The Bad</strong></h2>
<p>No technology is perfect. The JVM is certainly no exception. If you work on a non-Java language implementation you realize that you're not quite in Eden. It provides a great base for other languages, but the VM wasn't <em>originally</em> designed with other languages in mind. This forces us to get creative at times.</p>
<p>For example, we maintain our own frame stack as heap-allocated objects. If we had our way, we would manipulate the real frame stack directly and add the additional fields we need to maintain. It's too bad we cannot have better control over the framestack. Bummer.</p>
<p>It's also a bummer that every time we create a Ruby Fixnum value, we're <a href="http://stackoverflow.com/questions/13055/what-is-boxing-and-unboxing-and-why-is-it-bad">boxing</a> those values in a Java object. The C implementations of Ruby are just passing tagged ints. If only we had faster fixnums. Java primitives do not cut it since they will not fit into heterogeneous lists without boxing.</p>
<p>Aside: you may have also noticed that the JVM takes some time to start up :)</p>
<p>People who have to write high-performance code for the JVM will also find themselves frequently frustrated by the black box nature of the VM. Once you load your bytecode, you turn a crank and hope you come up a winner. You're never sure how much of a winner you will be... black boxes, by definition, are a mystery.</p>
<p>With all of that said (and believe me we have a laundry list of features not mentioned that we would like to see), I am super happy that our implementation is on top of the JVM. Why?  Read on...</p>
<h2><strong>The Good</strong></h2>
<h3><em> Hotspot</em></h3>
<p>For starters, I'll say that although Hotspot is a mystery, it does a generally great job at performance. The truth is that dynamic profiling is the path to excellent performance. HotSpot is much more clever than we are. It has the benefit of profile data from the running application to inform itself.</p>
<p>It also has the ability to de-optimize code. As strange as it sounds, this detail ends up being the catalyst to great performance.  When Hotspot does an optimization it puts a cheap guard in front of the optimization to make sure the rationale for the optimization still holds true. If the guard ever fails then it de-optimizes back to a slow path. The reason why this rocks, is that Hotspot can then be super speculative with aggressive optimizations. If the informed bet pays off, it pays off huge. If it doesn't pay off, it gets reset with additional knowledge for a future potential optimization and some extra cost for trying out the not-quite-right optimization.</p>
<p>Here's a demonstration of Hotspot in action:</p>
<p><img src="http://farm3.static.flickr.com/2500/4116632798_bffb4ecaf7_o.png" alt="" width="576" height="432" /></p>
<p>In this graph we're running a mandelbrot generator many times and plotting the amount of time it takes to generate it each time. If you look at JRuby 1.4.0 on the right side JRuby is <em>clearly</em> smoking Ruby 1.8.7 and doing very well against 1.9.2preview2. If you look at the progression as JRuby <em>starts</em>, you can see that we start slower than 1.8.7 but rapidly pick up steam as Hotspot kicks in.</p>
<p>There's one interesting slowdown which occurs in iteration 6; this is actually a Hotspot deoptimization occurring. You'll also notice that performance returns to the same level. Later optimizations end up getting that performance back.</p>
<p>I cannot imagine writing something as good as Hotspot. It has been worked on by a lot of smart folks for close to a decade now. The improvements between Java 4, 5, and 6 are pretty impressive. As JRuby, we not only get Hotspot for free with no work on our part, but we also get improvements every time it's upgraded. This is a pretty nice perk to using the JVM. As I said nothing is perfect, but this really is an easy decision... and we've not even begun to talk about Garbage Collection (GC).</p>
<h2><em>Garbage Collection (GC)</em></h2>
<p>The Java folks have literally spent centuries worth of hours debugging, testing, and improving their VM. Think about a building full of engineers working on just garbage collection for a decade and a half! The JVM ships with multiple garbage collectors, so even in cases where workloads confound one GC in the JVM, the JVM actually allows you to use one of the other garbage collectors. On top of that, you can tune any of the collectors you use. You can tailor the collector for your application.</p>
<p><strong><span id="more-2943"></span></strong></p>
<p>The various collectors also boast many delicious attributes. They are all compacting, so memory fragmentation is not an issue. They're all incremental to reduce the length of GC pauses which can happen. They are also generational, so that short-lived objects can be collected much more quickly.</p>
<p>Some are parallel so that collection work can be spread out over multiple cores. There are even concurrent collectors so that there may be no collection pause at all. Cool stuff which is also battle-tested. JRuby gets all of this for free. Now with Java 7 (and u12 of Java 6) they even have a new 'G1' collector. It just keeps improving.</p>
<p>There are two more neat things about GC and the JVM: both are about getting visualization and information about how well GC is coping. The first is the -J-verbose:gc flag. This option will log all collection events along with when, how much, and how long they take. This is super useful for getting a picture on how good or bad the collector is at handling your workload:</p>
<pre>[GC 16000K-&gt;3727K(82496K), 0.0396636 secs]
[Full GC 13021K-&gt;5802K(82496K), 0.1468975 secs]
[GC 21802K-&gt;9769K(82496K), 0.0292348 secs]
[GC 25769K-&gt;12535K(82496K), 0.0243674 secs]
[GC 28535K-&gt;13136K(82496K), 0.0169928 secs]
[GC 29136K-&gt;15498K(82496K), 0.0213308 secs]
[GC 31498K-&gt;16911K(82496K), 0.0213301 secs]
[GC 32911K-&gt;19413K(82496K), 0.0186457 secs]
[GC 35413K-&gt;20207K(82496K), 0.0146396 secs]</pre>
<p>You can tally these events and figure out total time spent just cleaning up garbage and also figure out if perhaps your workload is overburdening the collector. This may lead you to change your design or perhaps try and tune it out by changing your heap size.</p>
<p>The second is just querying a JVM through jconsole. jconsole has many views into the system, including ways of manipulating aspects of the system, but it has a nice memory tab to show how well GC is working:</p>
<p><img src="http://farm3.static.flickr.com/2494/4115863635_148128d48f_o.png" alt="" /></p>
<p>In the lower right corner you can see green boxes showing how full different generations of memory are.  If, for example, you saw a nearly full survivor generation (the empty third bar above), then that means slow full GC collection times, and it is very unlikely to be a healthy application.<em><br />
</em></p>
<h3><em> Portability</em></h3>
<p>Both GC and Hotspot are available wherever Java is available. This means JRuby will not just <em>work</em> on other platforms, but that it will work <em>well</em> on other platforms. It's really nice to get this support for free.</p>
<p>On top of that, JRuby is working in exotic locations. We get bug reports for JRuby bugs on OpenVMS. People tell us about Rails applications running on JRuby on an IBM mainframe running CP/CMS! I am not making this up. Crazy and cool to think that people have an oasis in JRuby on OSes like this. We can thank the portability of the JVM for this.</p>
<p>In fact, since the open sourcing of Java and the OpenJDK project, we are seeing even more proliferation of the platform.  I think the portability proposition is about as perfect as it can get.</p>
<h3><em>Maturity</em></h3>
<p>The JVM is over 15 years old—maybe even old enough to get into an R-rated movie. At JavaOne the parallel was drawn between a child coming of age and the longevity of Java and the JVM. Over the last decade and a half an impressive amount of engineering effort has been expended to make the JVM stable, fast, and pervasive. Oh yeah... we get that for nothing! Is this sounding familiar?<em><br />
</em></p>
<h3><em> On the Radar</em></h3>
<p>JRuby and other language projects on the JVM have been acknowledged by JVM engineers. A concrete example is the invokedynamic specification (aka JSR292). This JSR is tailored for new languages and the fact that Java method dispatch rules are not the only ones which matter on the JVM. It is nice that the JVM wants to be a better platform for projects like JRuby.</p>
<p>There is also a MLVM (multiple language VM) project which is a clearinghouse for new features which may make it into the JVM. It's at least a place where enterprising developers can try to add features they want to see in the JVM. The JVM engineers themselves interact and make suggestions. This looks like it's becoming a great incubator for new JVM features.</p>
<p>These two developments make me happy that the JVM is expanding its scope and watching what people are using it for.</p>
<h3><em>Time Marches On</em></h3>
<p>The JVM has become a durable part of the technology landscape. The uncertainty of an Oracle/Sun merger and any potential shenanigans makes for salacious technology press, but the truth is mundane. So many behemoth companies (like Oracle and IBM and HP and SAP and.... and...) have invested so much money in writing middleware for the JVM that it's difficult to see their commitment to the JVM changing in the next decade.</p>
<p>What this means for JRuby is additional performance gains and additional opportunities to help influence the market towards a language like Ruby, and Ruby on Rails. We're doing what we can to help Rubyists satisfy their desires in a Ruby runtime. At the same time, we're also showing Java folks that Ruby is a language with lots of advantages over Java for many applications, but one that they don't have to change their platform to use.
<p><a href="http://www.engineyard.com/blog"><img height="98" width="61" title="logo-engineyard" alt="" class="attachment-post-thumbnail wp-post-image" src="http://www.engineyard.com/blog/wp-content/uploads/logo-engineyard.png"/></a></p>
]]></description>
		<wfw:commentRss>http://www.engineyard.com/blog/2009/j-is-for-jvm-why-the-j-in-jruby/feed/</wfw:commentRss>
		<slash:comments>39</slash:comments>
		</item>
		<item>
		<title>3 Ruby Quirks You Have to Love</title>
		<link>http://www.engineyard.com/blog/2009/3-ruby-quirks-you-have-to-love/</link>
		<comments>http://www.engineyard.com/blog/2009/3-ruby-quirks-you-have-to-love/#comments</comments>
		<pubDate>Thu, 15 Oct 2009 19:15:29 +0000</pubDate>
		<dc:creator>Thomas Enebo</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Heredocs]]></category>
		<category><![CDATA[JRuby]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=2559</guid>
		<description><![CDATA[<p>Ruby's a fantastic language; we love it because it's flexible, readable and concise, to name just a few reasons. The Ruby language is also incredibly complex as far as language syntaxes (grammar) are concerned. This sometimes leads to some dark seedy corners... but by examining the stranger aspects of Ruby's syntax, it helps us to better understand the power of Ruby. This entry will show some of the stranger aspects of the language and reflect on how we rarely see these used in real life.</p>
<p><strong>Warning</strong>: Most of the code you see in this post should never be used in real life by actual programmers.  The snippets are meant to provide insight into the power of Ruby, and more obviously, are for entertainment value.</p>
<h2>1. Expressions are Cool</h2>
<p>One of the great things about Ruby is that everything is just executable code. In fact, everything is an expression.  This makes it nice because you can then programmatically build up a set of methods in a class body, like this:</p>
<pre>class Numeric
  MM_SIZE = 0.00025

  [:mm, :cm, :dm, :m, :dam, :hm, :km, :Mm].inject(MM_SIZE) do |size, unit|
    define_method(unit) { self * size }
    size * 10
  end
end</pre>
<p>Ignoring the fact that I just modified <code>Numeric</code>, you have to admit that being able to do stuff like this in Ruby makes it a great language; a language with the flexibility to define methods progammatically because everything is just code and expressions.</p>
<p>Over the years of supporting JRuby, I began to realize that the grammar is a bit <em>too </em>too generous.  At this point you can argue that it's up to programmers to hang themselves with any bizarre language feature. So what's the fuss?</p>
<pre>def foo(a, b=def foo(a); "F"; end)
  a
end

p foo("W", 1) + foo("T") + foo("bar")      # =&gt; "WTF"</pre>
<p>Is there a sane reason to allow a <code>def</code> as the value of an optional argument? Since we have a language where everything is an expression, this is just life in the Ruby lane.  Luckily, <code>def</code> returns <code>nil</code> and not <code>UnboundMethod</code> or something that's considered <em>useful</em>; otherwise there would be some pretty weird code floating around.</p>
<p>Before I go on, I wondered about variable scoping...</p>
<pre>def foo(a, b = self.class.send(:define_method, :foo) {|_| ": I captured #{a}" })
  a
end

p foo("foo") + foo("bar")  #=&gt; foo: I captured foo</pre>
<p>Of course it makes sense that the optional argument value of 'b' evaluates in a scope where it can capture 'a'... but wow! The potential for strange Ruby code is just amazing!</p>
<h2><strong><span id="more-2559"></span></strong>2. It Makes Sense But...</h2>
<p>Other times the grammar has oddities which seem to make sense on the <em>surface</em> but generally confuse you when you start to stray off the path of idiomatic Ruby.  Heredocs are a great example:</p>
<pre>a = &lt;&lt;EOF
hooray
multi-lines
EOF</pre>
<p>This how we normally see them.  The idiomatic example may have us define a heredoc as: when encountering a heredoc statement (&lt;&lt;EOF) take all lines after that statement until we encounter the heredoc marker on a line by itself and use those lines as a multi-line string.  Certainly, that would still work for this example:</p>
<pre>{:skybox =&gt; "/data/skyboxes/mountains/",
 :floors =&gt; [
  {:location =&gt; [0,0,0],:data =&gt; &lt;&lt;EOL, :texture =&gt; "data/texture/wall.jpg"},
........BCB.........
.........P..........
....................
........DDD.........
.......D....D.......
....................
....D.....D....D....
....................
..D....D....D....D..
...BBBBBBBBBBBBBB...
EOL
  {:location =&gt; [0,10,0],:data =&gt; &lt;&lt;EOL, :texture =&gt; "data/texture/wall.jpg"},
# More elided ...
}</pre>
<p>Heredocs in this code are interleaved in the middle of a hash literal... This is <em>odd</em>, but the definition still holds up.  Let's break the definition:</p>
<pre>def foo(a,b)
  p a, b
end

foo(&lt;&lt;ONE, &lt;&lt;TWO)
This is one
ONE
This is two
TWO</pre>
<p>Two heredocs on the same line break the definition.  I think with a little work we could fix the definition to talk about what to do about multiple heredocs on the same line, but then consider this case:</p>
<pre>a = &lt;&lt;ONE
This is one. #{&lt;&lt;TWO}
This is two. #{&lt;&lt;THREE}
This is three.
THREE
TWO
ONE    # =&gt; "This is one. This is two. This is three.\n\n\n"</pre>
<p>Coming up with an easy to read definition is starting to get rough.  Maybe just accepting that you can do weird things with heredoc without actually <em>explaining</em> them in a common definition is the right thing to do.  Do we really want people to use heredocs this way?  Is it cool that we can do stuff like this?</p>
<h2>3. Mystical String Concatenation</h2>
<p>Ruby's grammar is <em>huge</em>.  Super huge, and sometimes you see something in the grammar that makes you wonder how it got there.  For me the one I wonder about the most is what I call the "Mystical String Concatenation" feature:</p>
<pre>string        : string1
              | string string1 {
                  $$ = support.literal_concat(getPosition($1), $1, $2);
              }</pre>
<p>Since string1 must be a type of string literal this translates into the following Ruby syntax:</p>
<pre>a = "foo" "bar"
p a # =&gt; "foobar"</pre>
<p>Is this really useful?  The performance benefit is that the parser will concatenate the string before any execution happens.... but this only works for string literals!  A programmer could just rewrite the string as "foobar". Perhaps someone wanted to inspect strings into an eval statement?</p>
<pre>one = "foo"
two = "bar"
a = eval "#{one.inspect} #{two.inspect}"</pre>
<p>It mystifies me...</p>
<h2>Conclusion</h2>
<p>Ruby is beautiful, powerful, and in some cases, wacky.  I've only just scratched the surface of the weird convoluted things you can do with Ruby's syntax.  What's most interesting to me though is that Ruby programmers rarely touch these strange bits unless they're trying to be cute...</p>
<p>Compared to another language I used to always use (it starts with a P and is four letters, but I seem to have completely forgotten its name...), it's surprising how rarely <em>real</em> Ruby code ventures into the land of the indecipherable.</p>
<p>Both Ruby and the previously mentioned forgotten language are very powerful, and can get a lot of the same things done, but it seems that Ruby code ends up being written in a largely idiomatic way.  Ruby may be a rat's nest for writing a coherent specification of the language, but the Ruby that people write using this underspecified language ends up looking really nice.
<p><a href="http://www.engineyard.com/blog"><img height="98" width="61" title="logo-engineyard" alt="" class="attachment-post-thumbnail wp-post-image" src="http://www.engineyard.com/blog/wp-content/uploads/logo-engineyard.png"/></a></p>
]]></description>
		<wfw:commentRss>http://www.engineyard.com/blog/2009/3-ruby-quirks-you-have-to-love/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>You&#8217;ve Got Java in My Ruby</title>
		<link>http://www.engineyard.com/blog/2009/youve-got-java-in-my-ruby/</link>
		<comments>http://www.engineyard.com/blog/2009/youve-got-java-in-my-ruby/#comments</comments>
		<pubDate>Tue, 08 Sep 2009 17:00:37 +0000</pubDate>
		<dc:creator>Thomas Enebo</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[jme]]></category>
		<category><![CDATA[JRuby]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=2116</guid>
		<description><![CDATA[<p>In <a href="http://www.engineyard.com/blog/2009/scripting-java-libraries-with-jruby/">Charlie Nutter's blog post last week</a> he talked about how easy it was to access Java classes from within JRuby. In this post, I am going to expand on that theme and demonstrate a few things you can do to give Java classes and APIs a Ruby face lift.</p>
<p>There are thousands of useful Java libraries out there that are usable from JRuby, but just importing and consuming them directly is not always very appealing. This is largely in part because these Java APIs do not use any Ruby features. In other words, the API feels like a Java API (duh!). So as you've probably already guessed, the rest of this entry will be about pimping out Java APIs with the workhorse Ruby features we all know and love.</p>
<h2>What You Get by Doing Nothing</h2>
<p>Even if you don't try and make a better API, JRuby does several things to Java classes to help narrow the gap:</p>
<ol>
<li><strong>All methods can be snake-cased:</strong></li>
<p><code>setSize 200, 200</code></p>
<p>can be:</p>
<p><code>set_size 200, 200</code></p>
<li><strong>Getters can omit the get:</strong></li>
<p><code> my_height = frame.getHeight</code></p>
<p>can be:</p>
<p><code>my_height = frame.height</code></p>
<li><strong>Setters can be replaced with assignment:</strong></li>
<p><code> event.source.setText("Yeeeeehaw")</code></p>
<p>can be:</p>
<p><code>event.source.text = "Yeeeeehaw"</code></p>
<li><strong>Last arguments which are interfaces can just be a block instead:</strong><br />
This is much more common in Java APIs than you would think:</li>
<pre>class MyListener
  include java.awt.event.ActionListener
  def actionPerformed(event)
    event.source.text = "HEEEE"
  end
end

instance_of_action_listener = MyListener.new
button.add_action_listener instance_of_action_listener

button.add_action_listener { |event| event.source.text = "HEEEE" }</pre>
<li><strong>Common Java types have been infused with some common sense Ruby behavior:</strong><br />
For example, all Lists and Maps have an each() method and mixes in Enumerable.</li>
</ol>
<p>We try our best to make Java classes not look alien in Ruby, but they're still basically a Java API with a minor face lift. You need to put a little work into Ruby API design to take Java classes to the next level.</p>
<h2>Decoration</h2>
<p>Before I explain decoration, I need to give one detail about how Java classes get imported into JRuby. When a java_import is done:</p>
<p><code>java_import java.util.ArrayList</code></p>
<p>This will construct a Ruby Class in the current namespace called <code>ArrayList</code> or a Ruby Module if we were importing a Java interface. The Ruby class/module defined will have one method per distinct name in the Java class/interface which will dispatch to the appropriate Java method via lots of magic for Java signature overrides and static-type resolution. From this we can say:</p>
<p><em>'Anything imported from Java is actually fronted by a Ruby class/module that can be manipulated like any other Ruby class/module'</em></p>
<p>With this knowledge, decoration is just manipulating these Ruby proxies like any other Ruby class/module. If you want to add a method which has optional parameters, then just open the class and add the method you want. You can do anything you can think of including things like: aliasing, removing methods, adding instance variables, or even add a method_missing.</p>
<p>So let's look at a concrete example. In JRuby source itself, we decided that anyone who uses any class derived from the interface java.util.Map should be Enumerable. We do it with decoration:</p>
<pre>module java::util::Collection
  include Enumerable

  def each(&amp;block)
    iter = iterator
    while iter.has_next
      block.call iter.next
    end
  end

  def &lt;&lt;(a)
    add(a)
    self
  end

# ...
end</pre>
<p>So because of this we can do things like:</p>
<pre>require 'java'
arr = java.util.ArrayList.new
arr &lt;&lt; 1 &lt;&lt; 2 &lt;&lt; 3
arr.inject(0) { |sum, i| sum += i }</pre>
<p>So this makes <code>ArrayList</code> feel just like Ruby's Array sans construction. Decorating is a nice way of bridging the gap with a little bit of Ruby code. It also helps encapsulate the use of Java API code into one place.</p>
<h2>BEEP BEEP BEEP</h2>
<p>The Java people reading this may be excited thinking "oh wow! I can add methods to Java classes." Realize that anything you add will only be seen on the Ruby side of the fence. For Java classes, type signatures are frozen when the class is compiled. No amount of JRuby magic can change this aspect of Java.</p>
<p>Additionally, if you want to change behavior of an existing method and have Java see that change, then you need to extend the Java class (e.g. <code>class MyArray &lt; ArrayList</code>).  In a future blog entry, we'll talk about implementing Java interfaces and extending Java classes within JRuby, so keep an eye out.</p>
<h2>Blocks</h2>
<p>It should be old hat for most Rubyists to make nice APIs using blocks. I just wanted to point out just how helpful they are when trying to change a blockless API to one which uses blocks.</p>
<p>In Java, one of the most hated aspects of coding is large number of try/catch/finally statements. Ruby has the equivalent with begin/rescue/ensure but have you ever noticed how much less we see the Ruby-equivalent constructs in Ruby?  try/catch literally riddle the landscape of Java. Encapsulating these exceptional paths into to a method which accepts a block is a clear winner and should be used when you encounter this in a Java API. This is especially true for APIs which need to demarcate something transactional in nature.</p>
<p>In fact, there is lots of repetitive code in Java which can be DRY'd up with some simple block idioms.</p>
<p>Another problem in Java that festers because of lack of blocks is poor syntax for anonymous classes. It is <em>so</em> verbose that most people will opt to write one-off named classes. This ends up causing lots of extra files or extra lines for inner classes. Blocks make it really easy to kill off one-off classes. Here's a code snippet I used in the JrME library:</p>
<pre>class InputAction
  # Make an action which will invoke the supplied block every time there
  # is an action event:
  #   forward = InputAction.create { |event| node.accelerate event.time }
  def self.create(&amp;block)
    BlockBasedInputAction.new(&amp;block)
  end
end

class BlockBasedInputAction &lt; InputAction
  def initialize(&amp;block)
    super()
    @block = block
  end

  def performAction(event)
    @block.call event
  end
end</pre>
<p>In one small demo game which I ported from Java, I ended up removing three separate application-level classes because I made this one tiny library-level one. It's surprising how nice some Java libraries seem after adding a few strategic block-accepting methods.</p>
<h2>Delegation</h2>
<p>Delegation as a concept is not specific to Ruby, but is worth bringing up. Why decorate a Java class and get all of that Java class's methods exposed when you can hide them behind another Ruby class that only exposes what you want? This is especially powerful when you want to write a common API that works across multiple Ruby implementations (e.g. JRuby, MRI, and Rubinius), but has different native backends.</p>
<h2>Domain Specific Language (DSL)</h2>
<p>Ruby provides the capability to make code <em>soooo</em> much more readable by doing some syntax gymnastics and making a DSL. Java has absolutely no chance in this area. I made a simple DSL in JrME for physics object descriptions which I thought turned out well. In fact, let's look at a before and after...</p>
<p>This abbreviated Java snippet creates a cube that is made of ice with a texture map at a particular location:</p>
<pre>/* Missing try/catches.... */
DynamicPhysicsNode iceQube = getPhysicsSpace().createDynamicNode();
iceQube.attachChild(new Box("Icecube", Vector3f.new, CUBE_SIZE, CUBE_SIZE, CUBE_SIZE));
iceQube.generatePhysicsGeometry();
iceQube.setMaterial(Material.ICE);
TextureState textureState = DisplaySystem.getDisplaySystem().getRenderer().createTextureState();
URL url = System.getResource("data/images/Monkey.jpg");
Texture texture = TextureManager.loadTexture(url, Texture::MinificationFilter:Trilinear, Texture::MagnificationFilter::Bilinear, true);
texture.setWrap(Texture::WrapMode::Repeat);
textureState.setTexture(texture);
setRenderState(textureState);
iceQube.computeMass();
iceQube.getLocalTranslation().set(START_X, START_Y, START_Z);</pre>
<p>Caveat: a good Java programmer would organize this code and make abstractions that make sense for Java. They would not vomit it into one stream like this. However, I just wanted to show how much work the DSL does, so I think it is okay to show it this way.</p>
<p>Here's what this code looks like using the Ruby DSL:</p>
<pre>@icecube = physics_space.create_dynamic do
  geometry Cube("Icecube", CUBE_SIZE)
  made_of Material::ICE
  texture "data/images/Monkey.jpg"
  at *START
end</pre>
<p>DSLs are not for everyone and certainly not for every occasion, but when they fit, nothing can beat them.</p>
<h2>Scratching the Surface</h2>
<p>I've just provided but a few examples of the many ways to Rubify Java APIs. Beyond the explanation of <code>java_import</code>, this was all just basic Ruby programming. If you can write a good Ruby API, then you'll have no problems wrapping a Java API. I prefer to use pure-Ruby libraries when I can, but I cannot ignore all the cool and useful libraries that the Java ecosystem has produced over the last 15 years.</p>
<p>Keep an eye out for more JRuby content in the coming weeks, and feel free to comment with any requests!
<p><a href="http://www.engineyard.com/blog"><img height="98" width="61" title="logo-engineyard" alt="" class="attachment-post-thumbnail wp-post-image" src="http://www.engineyard.com/blog/wp-content/uploads/logo-engineyard.png"/></a></p>
]]></description>
		<wfw:commentRss>http://www.engineyard.com/blog/2009/youve-got-java-in-my-ruby/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>

