Wednesday, August 8, 2007

Geeky Fatherhood Moment

Some dads live for moments like when their son can beat them at basketball or throw a touchdown pass at a high school football game. Since my family seems to share my, ahem, lack of athletic prowess, I mostly get my "dad pride" fixes in different ways. For example, today my 10 yr old son asked me a question that nearly brought a tear to his old man's eye:

"Dad is there a job you can have when you grow up where you use Gimp?"

:)

Thursday, August 2, 2007

Spring Rails Plugin 0.1

Well, I finally checked in my code for a Spring Rails plugin. Consider it pre-alpha at this point. It's unit tested, and I made a simple example app to prove that it works. But that's about it. So if you find it useful, try it out and let me know so I can decide where to go with it next.

To install the plugin:

script/plugin install svn://rubyforge.org/var/svn/jruby-extras/trunk/rails-integration/plugins/spring


You'll need to get a basic Rails application working with the goldspike plugin in order for the Spring plugin to be of use. Currently it loads the Spring ApplicationContext by getting it from the ServletContext (which assumes you are using the Spring context listener to put it there). So if you're not running Rails in a servlet engine it doesn't work. If there is real interest in having the plugin be able to get an app context from somewhere else I'll look at supporting that down the road.

For an example of how to use it in a controller, see my previous post.

Why you shouldn't use it

If you're a Java programmer new to (J)Ruby and are thinking: "Awesome, I'll use Spring in all my Rails apps because Spring is awesome!" you need to hold up a second. Spring is awesome -- when you are developing Java applications. But in Ruby, dependency injection turns out to be unnecessary a whole lot of the time. This is because the Ruby language allows you to change things in a more straightforward way. And even if there were cases where you needed DI in Ruby there are probably better choices. I see the Spring plugin being useful where you have existing J2EE code wired together with Spring and want to front end it in JRuby on Rails. So use this plugin if you need it, but if you don't, then don't.

Don't take my word for DI and Ruby, my friend Jim had this blog post about it after our IM conversation. See the comments where other Ruby heavyweights weigh in on the subject.

Saturday, July 28, 2007

eRubyCon was awesome

Just wanted to get in a blog, albeit a week and a half late, about eRubyCon. It was an awesome conference; I felt honored being involved as a speaker doing a presentation on JRuby. Being among such incredible speakers as Jim Weirich, Glen Vandenburg, Stuart Holloway, and many others made me a little like the scene in Wayne's World where Wayne and Garth meet Alice Cooper: I'm not worthy!

As far as I know, this is the first conference specifically devoted to Ruby in the Enterprise. If all you've gotten is the 30 second soundbytes about Ruby and Rails this may sound like an oxymoron, but it's not. The other speakers, particularly Glen in his "Enterprise Schmenterprise" keynote made this point eloquently. Ruby, because of it's excellence at producing easily understood and therefore much more maintainable code, is the perfect language to develop the kind of applications thought of as "enterprisey". Glen: "Enterprises aren't ready for Ruby, they're desperate for it".

Stuart made a point in his blog about this too. His series on Ruby vs Java myths made the point that Ruby is actually better for large applications than for small ones. Definitely worth a read.

Finally a big Thanks! to Joe at Edgecase for putting this together. Joe, I know it was a lot of effort time and finance wise but I hope the community can grow enough to make this a viable yearly conference: the word about Ruby really needs to get out in the enterprise development area. For their sake and ours.

Thursday, June 21, 2007

include Spring

I've gotten a little farther with my JRuby on Rails Spring integration code. I think I have what may make the beginning of a Spring plugin for JRuby on Rails. Here's the code for the Spring module. This is my first foray into metaprogramming in Ruby, I'd welcome any feedback.

# spring.rb
# June 20, 2007
#


module Spring
include Java
import javax.servlet.ServletContext
import org.springframework.web.context.WebApplicationContext
import org.springframework.web.context.support.WebApplicationContextUtils

def spring_bean (bean)
class_eval "def #{bean.to_s}; application_context.get_bean(\"#{bean.to_s}\"); end;"
end

# dunno if there is a better way to do this. I need the spring_bean method
# to become a class method on the includee, but application_context needs to be
# a normal instance method
def self.append_features(includee)
includee.extend(Spring)
includee.class_eval do
def application_context
WebApplicationContextUtils.getWebApplicationContext($servlet_context)
end
end
end
end

This gives you a handy spring_bean method in any class where you've included Spring. The spring_bean method will then dynamically add an accessor to the class you use it in. This is what it looks like in a controller:

class TestSpringController < ApplicationController
include Spring
spring_bean :descriptor1
def showcontext
render_text descriptor1.displayName
end

end


Obviously to have this working you need several things. You need to have the goldspike plugin (from SVN trunk as per my earlier post). You also need to have Spring and its dependent jars in your WEB-INF/lib. I just copied em in for playing around purposes, with a little tweaking of my conf/war.rb file I could probably make goldspike fetch them. And lastly, it assumes you have an applicationContext.xml in WEB-INF, and that you have the Spring ContextLoaderListener declared in your web.xml.

Wow, that's a lot of trouble, why the heck would I want to do all that? What's this all for anyways? First of all, if you need this you probably don't need to ask, you know who you are. No, I'm not even trying to suggest using Spring for greenfield JRuby on Rails applications. But if you need to do heavy Java integration or you have an existing Spring application you want to front end in Rails, this kind of thing could end up being quite handy. This is my situation: I have a pretty large Spring/Hibernate/Tapestry app and I'd like to make moving to JRuby on Rails a viable option. Rather than replace everything whole hog, I'd like to be able to leverage working Spring services easily from Rails. As you can see, doing this should be a piece of cake.

Monday, June 18, 2007

Spring + JRuby on Rails

I've only been threatening to do this for a year, but I finally added the necessary stuff to have JRuby on Rails talking to Spring. There's a lot more to come here, but this controller code demonstrates being able to get ahold of a Spring WebApplicationContext in a Ruby on Rails controller.

class TestservletController < ApplicationController
include Java
import javax.servlet.ServletContext
import org.springframework.web.context.WebApplicationContext
import org.springframework.web.context.support.WebApplicationContextUtils

def showcontext
app_context = WebApplicationContextUtils.getWebApplicationContext($servlet_context)
render_text app_context.display_name
end
end


In order for this to work, you'll have to use the very latest goldspike-snapshot plugin from SVN trunk. I just checked in the code to expose $servlet_context earlier today. Obviously this code will only work using a servlet container, and you'll need to have Spring and necessary deps in WEB-INF/lib and have the Spring context loader listener in your web.xml. From here, my next step is some metaprogramming to allow you to add spring bean accessors into your controllers.

Sunday, April 22, 2007

API unickifying with JRuby


So I've been putting together some code examples for RubyCodeCamp in Columbus in a couple weeks. Quite awhile back I ran into a situation where I wanted to read an Excel spreadsheet from Ruby. At the time, there was no good way to do it in Ruby (MRI) and so I used Java and the nifty POI library. I thought this might be make for a nice example in JRuby. So I fired up jirb and started coding. In a few minutes I was reading data from a spreadsheet:


require 'java'

require '/home/ccnelson/java/poi/poi-2.5.1-final-20040804.jar'

include_class 'org.apache.poi.poifs.filesystem.POIFSFileSystem'

include_class 'org.apache.poi.hssf.usermodel.HSSFWorkbook'
include_class 'org.jruby.util.IOInputStream'

File.open("/home/ccnelson/documents/Invoice15.xls") do |f|
workbook = HSSFWorkbook.new(IOInputStream.new(f))
puts "cell 0,0: #{workbook.getSheetAt(0).getRow(0).getCell(0).getStringCellValue}"

end


There's some nice stuff going on. I really like being able to just include a jar and start using it. Still, using the POI API in Ruby looks rather icky -- (actually, it started even worse than this, but Charles Nutter was on #jruby and was kind enough to tell me about IOInputStream). After looking at this code for a minute I started thinking and it came to me: "Hey this is Ruby. We can do anything we want!"

I started with that ugly getStringCellValue at the end. It would be nice if we could give cell a to_s and do away with that. Well, guess what, since this is Ruby, I can just open HSSFCell and do it:



require 'java'

require '/home/ccnelson/java/poi/poi-2.5.1-final-20040804.jar'

include_class 'org.apache.poi.poifs.filesystem.POIFSFileSystem'
include_class 'org.apache.poi.hssf.usermodel.HSSFWorkbook'
include_class 'org.jruby.util.IOInputStream'

include_class 'org.apache.poi.hssf.usermodel.HSSFCell'

class HSSFCell
def to_s
getStringCellValue
end
end

File.open("/home/ccnelson/documents/Invoice15.xls") do |f|
workbook = HSSFWorkbook.new(IOInputStream.new(f))
puts "cell 0,0: #{workbook.getSheetAt(0).getRow(0).getCell(0)}"

end




Cool! Even though HSSFCell is a java class, because I am using it from JRuby I can open it up and stick methods on it. This got me excited. What do I really want this API to look like? I think I'd really rather be able to access my spreadsheet cells using a simple 2 dimenional array. I mean, that's really what they are for my purposes. And guess what? In Ruby, the [] operator, like everything else in Ruby, is just a method. And if it's just a method, well I can abuse... err.. bend it to my own nefarious purposes. Bwah ha ha hah ha hah ha ha..

Oops, got a little carried away there. Ruby coding will do that sometimes. Back to the task at hand:



require 'java'

require '/home/ccnelson/java/poi/poi-2.5.1-final-20040804.jar'

include_class 'org.apache.poi.poifs.filesystem.POIFSFileSystem'
include_class 'org.apache.poi.hssf.usermodel.HSSFWorkbook'
include_class 'org.jruby.util.IOInputStream'

include_class 'org.apache.poi.hssf.usermodel.HSSFCell'

include_class 'org.apache.poi.hssf.usermodel.HSSFRow'
include_class 'org.apache.poi.hssf.usermodel.HSSFSheet'

class HSSFCell
def to_s
getStringCellValue
end

end

class HSSFSheet
def [] (index)
getRow index
end
end

class HSSFRow

def [] (index)
getCell index
end
end
File.open("/home/ccnelson/documents/Invoice15.xls") do |f|
workbook = HSSFWorkbook.new(IOInputStream.new(f))
spreadsheet = workbook.getSheetAt(0)
puts "cell 0,0: #{spreadsheet[0][0]}"

end



Nice! This for me is one of the killer features of JRuby. A lot of scripting languages will let you access the Java APIs in a more light weight language. But because of the features of the Ruby language, it becomes so easy to modify APIs to suit your needs, desires, and insane urges.

Welcome to my new blog

I was getting kind of tired of JRoller, so I decided to move. Welcome to my new digs!


class InventoryController
end