+ All Categories
Home > Technology > Ugo Cei Presentation

Ugo Cei Presentation

Date post: 15-May-2015
Category:
Upload: rubyonrailsdude
View: 2,904 times
Download: 0 times
Share this document with a friend
Popular Tags:
36
Ruby for Java programmers Ugo Cei Sourcesense [email protected]
Transcript
Page 2: Ugo Cei Presentation

• Java programmers wishing to know how to include Ruby code in Java programs or vice-versa.•Ruby programmers wishing for the same.

Who should attend this talk

Who should NOT attend this talk• Java programmers wishing to learn more about the Ruby

programming language.•This is not a talk about the differences between Java and

Ruby.

Ugo Cei: “Ruby for Java Programmers”

Page 3: Ugo Cei Presentation

•Why?•How?•Bridges• JRuby•XML-RPC•SOAP•Demos

Agenda

Ugo Cei: “Ruby for Java Programmers”

Page 4: Ugo Cei Presentation

What’s in it for me?

Ugo Cei: “Ruby for Java Programmers”Ugo Cei: “Ruby for Java Programmers”

Page 5: Ugo Cei Presentation

Shameless Plug: The Open Source Zone

http://oszone.org

Ugo Cei: “Ruby for Java Programmers”

Page 6: Ugo Cei Presentation

Shameless Plug: The Open Source Zone

http://oszone.org

Ugo Cei: “Ruby for Java Programmers”

Page 7: Ugo Cei Presentation

Shameless Plug: Evil or Not?

http://evilornot.info

Ugo Cei: “Ruby for Java Programmers”

Page 8: Ugo Cei Presentation

Shameless Plug: Evil or Not?

http://evilornot.info

if /<title>(.+)<\/title>/ ... Search?

Ugo Cei: “Ruby for Java Programmers”

Page 9: Ugo Cei Presentation
Page 10: Ugo Cei Presentation

“The era of islands is over for most development scenarios. You don't have to make one definitive choice. Instead, you get to hog all the productivity you can for the common cases, then outsource the bottlenecks to existing packages in faster languages or build your own tiny extension when it's needed.”

David Heinemeier Hansson, Sep 13, 2006

Ugo Cei: “Ruby for Java Programmers”

Page 11: Ugo Cei Presentation

How?

Ugo Cei: “Ruby for Java Programmers”

Page 12: Ugo Cei Presentation

• http://arton.no-ip.info/collabo/backyard/?RubyJavaBridge•Follow the instructions in readme.txt and on the website

and it should work (even on Intel Macs).•Encapsulate you Java code in high-level methods and

classes to hide 3rd party libraries and Java idiosyncrasies from Ruby as much as possible.

RubyJavaBridge

Ugo Cei: “Ruby for Java Programmers”

Page 13: Ugo Cei Presentation

•Uses ROME (https://rome.dev.java.net).

Sample Java Code

public class Fetcher { public static SyndFeed fetch(String url) throws Exception { URL feedUrl = new URL(url); FeedFetcherCache feedInfoCache = HashMapFeedInfoCache.getInstance(); FeedFetcher fetcher = new HttpURLFeedFetcher(feedInfoCache); SyndFeed feed = fetcher.retrieveFeed(feedUrl); return feed; }}

Ugo Cei: “Ruby for Java Programmers”

Page 14: Ugo Cei Presentation

Client Ruby Coderequire 'rjb'

Rjb::load('.:rome-0.7.jar:rome-fetcher-0.7.jar:jdom.jar:jdom.jar', [])

fetcher = Rjb::import('Fetcher')feed = fetcher.fetch(ARGV[0])print feed.getTitle, “\n”entries = feed.getEntries.iteratorwhile entries.hasNext do entry = entries.next print "#{entry.getPublishedDate.toString} #{entry.getTitle}\n"end

•No mapping from Java iterators to Ruby loops.•No date type conversions.•No support for JavaBean properties.

Ugo Cei: “Ruby for Java Programmers”

Page 16: Ugo Cei Presentation

Client Ruby Coderequire 'yajb/jbridge'include JavaBridge

JBRIDGE_OPTIONS = { :classpath => '.:rome-0.7.jar:rome-fetcher-0.7.jar:jdom.jar:jdom.jar'}

jimport "Fetcher"

feed = :Fetcher.jclass.fetch(ARGV[0])print feed.getTitle, "\n"entries = feed.getEntries.iteratorwhile entries.hasNext do entry = entries.next print "#{entry.getPublishedDate.toString} #{entry.getTitle}\n"end

Ugo Cei: “Ruby for Java Programmers”

Page 17: Ugo Cei Presentation

Making a Simple Java Classrequire 'yajb/jbridge'require 'yajb/jlambda'

include JavaBridge

c = JClassBuilder.new("MyClass")c.add_field("private int num;")c.add_constructor("public AAA(int a) {num = a;}")c.add_method("public int square() { return num * num;}")puts "Simple class: #{c.new_instance(5).square}"

•Uses javassist: http://www.csg.is.titech.ac.jp/~chiba/javassist/index.html

Ugo Cei: “Ruby for Java Programmers”

Page 18: Ugo Cei Presentation

Implementing an Interfacejimport "java.util.*"c = JClassBuilder.new("NumComp")c.add_interface("java.util.Comparator") # must be full qualified class namec.add_method(<<'JAVA')public int compare(Object o1, Object o2) do int i1 = ((Number)o1).intValue(); int i2 = ((Number)o2).intValue(); return i2-i1;endJAVAsample = [9,1,8,2,7,3,6,4,5,0,10]list = :ArrayList.jnewsample.each {|i| list.add( i )}:Collections.jclass.sort(list, c.new_instance)p "Sort:",list.toArray

Ugo Cei: “Ruby for Java Programmers”

Page 19: Ugo Cei Presentation

• http://www.swig.org• Jakarta POI, nifty library for manipulating Microsoft OLE 2

Compound Document formats (Office files) uses SWIG to provide Ruby bindings.•POI compiled using gcj and Ruby bindings generated

using SWIG.• http://jakarta.apache.org/poi/poi-ruby.html

Using SWIG

Ugo Cei: “Ruby for Java Programmers”

Page 20: Ugo Cei Presentation

• http://jruby.sourceforge.net/• http://jruby.codehaus.org/• JRuby is not a bridge between Java and Ruby but a full-

featured Ruby interpreter written in 100% Java.•Gives Ruby code instant access to all Java libraries.•Cannot load Ruby extensions written in C.• “Almost” Mostly able to run RubyGems and Rails.•Quick development pace.•Still slow compared to C Ruby, but quoting Charles O.

Nutter: “I think it's now very reasonable to say we could beat C Ruby performance by the end of the year.”

JRuby

Ugo Cei: “Ruby for Java Programmers”

Page 21: Ugo Cei Presentation

JRuby Client Coderequire 'java'

include_class 'Fetcher'

feed = Fetcher.fetch(ARGV[0])

feed.entries.each do | entry | p "#{entry.publishedDate} #{entry.title}"end

•Can use “each” on Java collections.•Date type conversion.•Full support for JavaBean properties.

Ugo Cei: “Ruby for Java Programmers”

Page 22: Ugo Cei Presentation

• demo1.rb

Calling Ruby Methods

class Demo1 def foo print 'bar' endend

IRuby runtime = Ruby.getDefaultInstance();runtime.loadFile(new File("ruby/demo1.rb"), false);RubyClass rb = runtime.getClass("Demo1");IRubyObject obj = rb.newInstance(new RubyObject[0]);obj.callMethod("foo");

•Demo1.java

Ugo Cei: “Ruby for Java Programmers”

Page 23: Ugo Cei Presentation

Using the Bean Scripting Framework

BSFManager.registerScriptingEngine("ruby", "org.jruby.javasupport.bsf.JRubyEngine", new String[] { "rb" }); BSFManager manager = new BSFManager(); JLabel mylabel = new JLabel(); manager.declareBean("label", mylabel, JLabel.class); manager.exec("ruby", "(java)", 1, 1, "$label.setText(\"This is a test.\")");

•The Bean Scripting Framework, when used with JRuby, will allow you more conveniently to pass your own Java objects to your JRuby script. You can then use these objects in JRuby, and changes will affect your Java program directly.

Ugo Cei: “Ruby for Java Programmers”

Page 24: Ugo Cei Presentation

•This won’t work as it conflicts with Ruby’s String and URI classes.•Solution: use a module.

Name Clashes

Ugo Cei: “Ruby for Java Programmers”

import_class ‘java.lang.String’import_class ‘java.net.URI’

module Javaimport_class ‘java.lang.String’import_class ‘java.net.URI’

end...uri = Java::URI.new(‘http://example.com/’)

•Or remap names:include_class("java.lang.Exception") {|p,n| "J" + n }

Page 25: Ugo Cei Presentation

Running Ruby on Rails

Ugo Cei: “Ruby for Java Programmers”

Page 27: Ugo Cei Presentation

Using the JDBC AR Adapter

jruby $JRUBY_HOME/bin/gem install ActiveRecord-JDBC --no-ri --no-rdoc

•As of 0.2.0 works for:•MySQL•PostgreSQL•Oracle•HSQLDB•Microsoft SQL Server•DB2•Apache Derby•FireBird

Ugo Cei: “Ruby for Java Programmers”

Page 28: Ugo Cei Presentation

Using the JDBC AR Adapter

adapter: jdbc driver: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/dbname username: admin password: secret

Ugo Cei: “Ruby for Java Programmers”

Page 29: Ugo Cei Presentation

•Pro: Established technology.•Pro: No need to use bridge code or special interpreters.•Con: Separate processes => must take network latency

and failures into account.•Con: Overhead of HTTP communication, XML parsing,

marshalling...•Need to convert types to something that XML-RPC is able

to understand, i.e.strings, numbers, dates, Vectors, Hashtables and little else.

XML-RPC

Ugo Cei: “Ruby for Java Programmers”

Page 30: Ugo Cei Presentation

XML-RPC Java Server

public class RPCFetcher {

public static void main(String args[]) throws Exception { WebServer server = new WebServer(8080); server.addHandler("$default", new RPCFetcher()); server.start(); }

// Continued...

•Uses Apache XML-RPC.

Ugo Cei: “Ruby for Java Programmers”

Page 31: Ugo Cei Presentation

public Vector fetch(String url) throws Exception { URL feedUrl = new URL(url); FeedFetcherCache feedInfoCache = HashMapFeedInfoCache.getInstance(); FeedFetcher fetcher = new HttpURLFeedFetcher(feedInfoCache); SyndFeed feed = fetcher.retrieveFeed(feedUrl); Vector items = new Vector(); for (Iterator it = feed.getEntries().iterator() ; it.hasNext() ; ) { SyndEntry entry = (SyndEntry) it.next(); Hashtable map = new Hashtable(); map.put("link", entry.getLink()); map.put("title", entry.getTitle()); map.put("publishedDate", entry.getPublishedDate()); items.add(map); } return items; }

XML-RPC Java Server

Ugo Cei: “Ruby for Java Programmers”

Page 32: Ugo Cei Presentation

XML-RPC Ruby Client

require 'xmlrpc/client'server = XMLRPC::Client.new 'localhost', '/', 8080entries = server.call('fetch', 'http://agylen.com/feed')entries.each do | entry | p "#{entry['publishedDate'].to_time} #{entry['title']}"end

Ugo Cei: “Ruby for Java Programmers”

Page 33: Ugo Cei Presentation

•Complex and heavyweight, but most of the complexity is hidden by tools.•WSDL service description can be automatically generated

from server code.•Ruby’s SOAP library provides what is necessary to read

WSDL documents and create classes and methods on the fly.•Sample Java server code based on XFire samples can be

found here:http://agylen.com/2006/05/06/ruby-for-java-programmers-part-vi/.

SOAP

Ugo Cei: “Ruby for Java Programmers”

Page 34: Ugo Cei Presentation

•Maps service names to service classes:

services.xml

<beans xmlns="http://xfire.codehaus.org/config/1.0"> <service> <name>BookService</name> <namespace>http://sourcesense.com/BookService</namespace> <serviceClass>com.sourcesense.xfire.demo.BookService</serviceClass> </service></beans>

Ugo Cei: “Ruby for Java Programmers”

Page 35: Ugo Cei Presentation

SOAP Ruby Clientrequire 'soap/wsdlDriver'WSDL_URL = 'http://localhost:8080/services/BookService?wsdl'driver = SOAP::WSDLDriverFactory.new(WSDL_URL).create_rpc_driverbooks = driver.getBooks(nil)p books.out.book[0].titlebook = driver.findBook(:isbn => '222')p book.out.title

•The BookService#getBooks method in Java takes no arguments, but if you try to call driver.getBooks without arguments, Ruby complains about a missing argument.•XFire add this extra ‘out’ element to its generated schema.

Ugo Cei: “Ruby for Java Programmers”

Page 36: Ugo Cei Presentation

Thank You!

Slides will be available athttp://agylen.com/

and athttp://www.sourcesense.com/

Ugo Cei: “Ruby for Java Programmers”


Recommended