Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Applicazioni Rails con JRuby

Integrare e riutilizzare codice Java nelle applicazioni Rails
Integrare e riutilizzare codice Java nelle applicazioni Rails
Link copiato negli appunti

Che esistano diverse implementazioni di Ruby è cosa nota e in questo articolo ci occupiamo di una delle più conosciute, quella basata su Java: JRuby. Ma perché occuparsene? Non abbiamo già un ottima implementazione nativa?

Con JRuby siamo in grado di utilizzare il nostro codice Java all'interno dei progetti Ruby e, considerando che abbiamo molto codice Java (legacy?) all'interno delle nostre organizzazioni, una buona strategia potrebbe essere quella di continuare ad utilizzare tale codice nei nuovi progetti (ruby/rails), e nel frattempo
iniziare un processo di migrazione e reingegnerizzazione del vecchio codice ("vecchio" ma stabile!).

In questo articolo vogliamo mostrare come:

  • installare JRuby e testarlo
  • iniziare un nuovo progetto Rails con JRuby
  • utilizzare classi Java esistenti all'interno del progetto Rails

Per il nostro esempio abbiamo utilizzato questa configurazione basata su Mac OS X:

  • Mac OS X 10.5.6
  • Java 1.5.0-16
  • Rails 2.2.2
  • JRuby 1.1.3 (ruby 1.8.6 patchlevel 114)

ma non si dovrebbero incontrare problemi insormontabili con altri sistemi operativi.

Installazione

Anzitutto occorre installare JRuby:

$ su
# port install jruby

Ora verifichiamo che funzioni correttamente:

# jruby -v
jruby 1.1.3 (ruby 1.8.6 patchlevel 114) (2008-12-23 rev 6586) [i386-java]

Quindi scarichiamo l'ultima versione di rubygems dal sito ufficiale, estraiamo il contenuto del pacchetto e la installiamo:

$ wget http://rubyforge.org/frs/download.php/45905/rubygems-1.3.1.tgz
$ tar -zxvf rubygems-1.3.1.tgz
$ cd rubygems-1.3.1
$ jruby -S ./setup.rb

Infine, possiamo installare le gem necessarie:

# jruby -S gem install rails
# jruby -S gem install mongrel jdbc-mysql activerecord-jdbcmysql-adapter

Notiamo che queste gem vengono installate sotto un path diverso da quello di ruby "nativo", quindi vengono tenute ben separate. Per altre piattaforme possiamo fare riferimento al wiki ufficiale di JRuby.

Come regola generale è utile notare che è sufficiente utilizzare lo switch -S seguito dal comando ruby.

Costruire l'applicazione Rails

Ora, a scopo puramente dimostrativo, creiamo un semplice blog ("YAB": yet another blog):

$ jruby -S rails yab
$ cd yab

Accertiamoci che tutto funzioni correttamente:

$ jruby -S rake -T
$ jruby -S script/server

Puntando il nostro browser su http://localhost:3000 vedremo la familiare schermata di benvenuto.

Figura 1. Schermata di benvenuto di Rails
Schermata di benvenuto di Rails

Ottimo, tutto funziona, ma attualmente ong>JRuby non supporta le estensioni native>: non possiamo installare la gem mysql (come neppure sqlite). Dobbiamo scaricare ed installare il connettore MySQL per Java (un driver JDBC) da qui:

$ wget http://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.0.8.tar.gz
$ tar -zxvf mysql-connector-java-5.0.8.tar.gz
$ sudo cp mysql-connector-java-5.0.8/mysql-connector-java-5.0.8-bin.jar /opt/local/share/java/jruby/lib

Ci sono altre gem che varrebbe la pena provare, come activerecord-jdbcmysql-adapter. Per ora concentriamoci sulla creazione del database:

$ echo "create database yad_development" | mysql -u root -p

dobbiamo modificare opportunamente il file config/database.yml inserendo le seguenti linee:

development:
  adapter: jdbc
  driver: com.mysql.jdbc.Driver
  url: jdbc:mysql://localhost/yad_development
  username: root
  password: NotSoSecretPassword

Creato il db, possiamo continuare lanciando la generazione della risorsa post:

$ jruby -S script/generate scaffold Post title:string content:text
    exists  app/models/
    ...
    <cut>
    ...
    create  app/controllers/posts_controller.rb
    create  test/functional/posts_controller_test.rb
    create  app/helpers/posts_helper.rb
    route  map.resources :posts

Lanciamo la migration:

$ jruby -S rake db:migrate
    ==  CreatePosts: migrating ====================================================
    -- create_table(:posts)
       -> 0.0448s
       -> 0 rows
    ==  CreatePosts: migrated (0.0458s) ===========================================

Possiamo vedere le consuete schermate dell'applicazione rails prodotto dallo scaffolding sulla risorsa post:

Figura 2. La lista dei post
La lista dei post

Proviamo ad inserire un nuovo post:

Figura 3. Inserimento di un nuovo post
Inserimento di un nuovo post

e vediamo che (ancora) tutto funziona come ci aspettiamo:

Figura 4. Visualizzazione del post
Visualizzazione del post

Utilizzare classi Java nei controller Rails

Finalmente possiamo utilizzare una classe Java esistente all'interno di un nuovo controller nella nostra applicazione Rails.

Supponiamo di avere una classe Java responsabile della "politica di pubblicazione" dei post sul blog, e per semplicità tale politica è basata esclusivamente sul contenuto del titolo del post:

package myenterprise;

public class BlogPolicy
{
  public static boolean is_valid(String postTitle)
  {
    /* politica di pubblicazione molto "permissiva"... */
    return true;
  }
}

Supponiamo, inoltre, di avere questa classe all'interno di un package più generico (myenterprise), contenuto in un jar file (myenterprise.jar).

Prima di tutto dobbiamo istruire Rails su come includere i file jar di nostro interesse. Per far ciò è sufficiente aggiungere il seguente codice in coda al file config/environment.rb:

Dir["#{RAILS_ROOT}/lib/**/*.jar"].each do |jarfile| 
  require jarfile 
end

quindi possiamo inserire i file jar necessari all'interno della directory lib (partendo dalla directory radice del nostro progetto - "yab")

Finalmente possiamo usare la classe Java all'interno dei nostri controller:

class PostsController < ApplicationController
  include Java
  import 'myenterprise.BlogPolicy'
  
  # GET /posts/1
  # GET /posts/1.xml
  def show
    @post = Post.find(params[:id])
    
    # Applichiamo la "politica di pubblicazione" sui post
    # NOTARE l'uso della classe Java
    unless BlogPolicy.is_valid(@post.title)
      redirect_to(@post)
    end
    
    respond_to do |format|
      format.html # show.html.erb
      format.xml  { render :xml => @post }
    end
  end
  ...
end

Come possiamo notare, dopo aver incluso il mixin Java ed importato l'opportuna classe, siamo in grado di utilizzarla facilmente senza bisogno di particolari costrutti sintattici:

unless BlogPolicy.is_valid(@post.title)
  redirect_to(@post)
end

Ti consigliamo anche