Combining Ruby (or Groovy/BeanShell) and Java with Spring Framework.
To combine Ruby and Java might seem like a challenge, but it’s actually quite easy using the Spring Framework. Feel free to follow along with my simple step by step instructions. I make programming FUN! These examples are collected from Spring In Action - Second Edition and uses Spring Framework 2.0.8.
1: Define a regular java interface.
public interface Lime { void limeIsNoCrime(); }
2: Then we define a ruby class with a matching method:
class Lime def limeIsNoCrime puts "To put lime in your drink is no crime" end end Lime.new
It’s important to notice the “Lime.new” at the end, this means that we will return a new lime object from this piece of code.
3: Add all needed dependencies to your build path.
I needed these:
- jruby.jar
- cglib*.jar in some version.
- commons-logging.jar
- spring.jar
If you download the spring framework with dependencies package, you should be able to find all these in there, somewhere.
4: Put this “magic” code in your applicationContext.xml:
<lang:jruby id="lime" script-interfaces="path.to.the.right.package.Lime" script-source="classpath:path/to/the/right/package/Lime.rb" />;The “script-interfaces” attribute should link to the interface we created in step 1, the script-source should link to the ruby source code we created in step 2.
If you want to use groovy or beanshell scripts instead, you just change lang:jruby to lang:groovy or lang:bsh.
Here’s an example of a very clean applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:lang="http://www.springframework.org/schema/lang" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.0.xsd"> <lang:jruby id="lime" script-interfaces="Lime" script-source="classpath:Lime.rb" /> </beans>
This is how it would be if you don’t use packages. Which you should.
5: Now, lets test this thing. Make a regular java class like this, and run it:
import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); Lime lime = (Lime) ctx.getBean("lime"); lime.limeIsNoCrime(); } }
Run the program and it should write “To put lime in your drink is no crime” to the console. We did it! There’s also a fairly good build in conversion of types, so if you change the return type to “List”, and return a ruby-list which will be a List in your Java-application. Nice!
The JSR 223 scripting API stuff is quite cool indeed since you can swap out languages while keeping the Java code intact. Clojure is moving towards supporting JSR 223 as well, I’m not sure what the Scala guys are up to though
Thank you for the great introduction. Great care should be taken to use only the jruby.jar included in the chosen spring
distribution since jruby 1.1 onwards is only compatible with spring 3.0 as reported in this issue on the spring jira:
https://jira.springframework.org/browse/SPR-4743