arton(a Tajima) JAVA から RUBY へ
クールな Java 1995 年頃 Sun 仮想マシン バイトコード GC 移動コード ( セキュリティ機構 )
Java? 現代のCOBOL 業務アプリケーション 型があるから安全 コンパイルするからバグが見つかる Eclipseがあるから簡単 オブジェクト指向言語 private interface
Java! Reflection Annotation Bytecode Modification Language Reference Java Native Interface
Java Platform SE6 http://java.sun.com/javase/ja/6/docs/ja/api/ たくさんのクラス たくさんのメソッド
Java public class Hello { public static void Main( String[] args) { System.out.println( hello world! ); } }
Ruby #!/usr/local/bin/ruby puts hello world!
仲良きことは美しき哉 軽量の人は 繊細な人を兼ねる 参考 http://www.slideshare.net/takahashim/dili gent-people-lightweight-people/
Ruby Java Bridge Java の型システムと Ruby の型システムの相互変換 Java の Class を Ruby の Klass にマップ Java の Object を Ruby の Object にマップ ( という感じ ) Ruby のオブジェクトを Java の interface にマップ Java は静的に型が決まらなければコンパイルできない Java5 以降 http://rubyforge.org/projects/rjb/
Rjb を利用するには インストール 環境セットアップ 型変換ルール メソッドオーバーロード 利用するクラスのAPI
Java SE http://java.sun.com/javase/downloads/index.j sp JDK 6u1 javaコマンド ( ローンチャ ) javac バイトコードコンパイラ rt.jar クラスライブラリ プラットフォーム win32/64, Solaris x86/x64/sparc, Linux x86/x64
インストール Windows 編 ASR をインストールする Sun の JDK をインストールする コントロールパネル / システム / 詳細設定で JAVA_HOME 環境変数を設定する
インストール Windows 以外 JAVA_HOME 環境変数 rjb の make 時に jni.h を参照するために必須
インストール OS X ADC サイトからダウンロード Java for Mac OS X 10.4, Release 5 (Universal) http://developer.apple.com/java/download/ export JAVA_HOME=/Library/Java/Home gem install rjb JAVA_HOME の設定は実行時には不要
インストール Debian 編 /etc/apt/sources.list deb http://ftp.debian.org/debian/ unstable nonfree sudo apt-get install sun-java6-jdk export JAVA_HOME=/usr/lib/jvm/java-6-sun gem install rjb
JVM のロード RJB::load( クラス, JVM 引数 ) JavaSE 以外のライブラリ利用時 Rjb::load( #{RAILS_ROOT}/lib/poi-.jar ) 暗黙に呼ばせた場合 JavaSE に制限される
Java プリミティブ Javaの数値はすべて符号付き byte -127~127 char Unicode 4.0 short 16ビット符号付き整数 int 32ビット符号付き整数 long 64ビット符号付き整数 float 単精度浮動小数点数 double 倍精度浮動小数点数 boolean true/false
Java プリミティブから Ruby byte Fixnum char Fixnum short Fixnum int Integer long Integer float Float double Float boolean TrueClass/FalseClass
Java オブジェクトから Ruby Klass = Rjb::import( 完全修飾名 ) instance = Klass.new( ) 例 ) JString = Rjb::import( java.lang.string ) s = JString.new( Hello World! ) puts s.tolowercase
文字列変換ルール $KCODE e s euc-jp utf-8 Shift_JIS utf-8 CP932 utf-8 (Windows) n/u - iconv contributed by Kuwashima
文字列とバイト配列のルール 引数変換 (Ruby Java) String は String Array は配列 ( 丸めあり ) 戻り値変換 (Java Ruby) StringはString バイト配列はString それ以外の配列はArray
オーバーロード Java.lang.String public String(byte[] bytes) public String(byte[] bytes, Charset charset) public String(byte[] bytes, int offset, int length); public String(String original);
例 String = Rjb::import( java.lang.string ) instance = String.new( AAA ) AAA : String or [ 0x41, 0x41, 0x41 ] : Array
変換方法の指定 コンストラクタ new_with_sig メソッド _invoke
例 String = Rjb::import( java.lang.string ) instance = String.new_with_sig( [B, AAA ) [ 0x41, 0x41, 0x41 ] : Array
型指定 Java の型名エンコーディングを利用 http://java.sun.com/javase/ja/6/docs/ja/api/java /lang/class.html#getname()
エンコードルール プリミティブ - boolean Z byte B char C double D float F int I long J short S
エンコードルール オブジェクト - 配列は入れ子の深さにつき [ を重ねる クラスは L に続けて完全修飾したクラス名を記述し ; で終わらせる
例 new_with_sig key = secretkeyspec.new_with_sig( [BLjava.lang.String;, pass, AES ); [B pass : バイト配列 Ljava.lang.String; AES : 文字列
例 _invoke result = c._invoke( dofinal, [B, data) dofinal [B バイト配列 メソッド名
サンプル rjbdemo/script/cipher.rb AESによる暗号化例 javax.crypto.cipher Java Cryptography API 注 ) iv は固定値 パスフレーズは先頭 16 バイトのみ利用
step1 Klass の生成 Cipher = Rjb::import( javax. ) SecretKeySpec = Rjb::import(.) AlgorithmParameters = Rjb::import
step2 オブジェクトの操作 key = SecretKeySpec.new_with_sig c = Cipher.getInstance( AES/CBC/PKCSPadding ) iv = Array.new(18, 127) iv[0] = OCTET iv[1] = 16 # データの長さ ap = AlgorithmParameters.getInstance( AES ) ap.init(iv)
Rails と Rjb environment.rb で JVM の初期化 environment.rb でクラスを import 後は必要に応じて
Jakarta Apache Foundation の Java ライブラリ http://jakarta.apache.org/ Tomcat HTTP Server (Java Servlet Container) http://tomcat.apache.org Ant Build Tool (Java の Rake) http://ant.apache.org
POI 構造化記憶ファイル ファイル内に階層構造 OLE Excel Wordの旧フォーマット http://jakarta.apache.org/poi/index.html API http://jakarta.apache.org/poi/apidocs/index.html
POI で Excel Excel97 フォーマット HSSFWorkbook
Java 2D API AWT Swing BufferedImage メモリー上のイメージ Graphics 抽象化された描画オブジェクト ImageIO イメージ ファイル
サンプルについて 東京都総務局の資料を利用 (db ディレクトリ ) http://www.toukei.metro.tokyo.jp/jsuikei/jsindex.htm 東京都 23 区の男女別および総人口情報のみを抽出して表示するアプリケーション 応用例 指定された年度 / 月に該当する xls を open-uri で取得して表示 xls のサマリを Web 上で表示
サンプルの読み方 (1) config/environment.rb rjb と JVM の初期化 Rjb::load("#{RAILS_ROOT}/lib/poi-2.5.1-final- 20040804.jar") lib に配置した POI の JAR(Java のクラスライブラリアーカイブ ) の読み込みを指定 利用するクラスの import
サンプルの読み方 (2) app/controllers/population_controller.rb table 指定された xls をテーブル表示 graph 指定された xls をグラフ表示 populationbook 指定された xls の内容から新たな xls の生成 attachment としてブラウザの外側で Excel などで開く
サンプルの読み方 (3) app/models/jinsui.rb 名前は元々利用するつもりだったxlsファイルの名前に由来 ( 気にしないで ) Jinsuiクラス POIを利用して指定されたxlsをラップ Graphクラスと協調してグラフ出力や 23 区人口のみのxls を出力 PopulationItem クラス 元のシートの行から利用するセルの情報のみを抽出した値オブジェクト DistrictPopulation クラス Jinusui クラスのヘルパ 23 区の人口情報の行のみを抽出して PopulationItem を生成する コレクションとして振舞う
サンプルの読み方 (4) app/models/graph.rb Jinsui クラスのヘルパ 各区の人口を棒グラフとして出力する BufferedImage( メモリ上のビットマップ ) にグラフを生成 png メソッド BufferedImage オブジェクトの内容を png のバイト配列 (Ruby では文字列 ) として出力
まとめ Java のクラスライブラリの利用 Windows Linux で同じライブラリを利用できる 開発は Windows 運用は Linux など Java で Ruby 拡張ライブラリの開発 ほとんどの人にとって C より簡単に高速実行 メソッドオーバーロードは避ける スレッドをまたがるコールバックはだめ