Ruby to Java 変換
JRubyからJava呼び出しの際にどんなオブジェクトが渡るかテスト
public class Convert { public static void print(Object obj){ System.out.println(obj.getClass() +":"+ obj); } }
include Java def conv obj Java::Convert.print obj end conv 1 conv 1.1 conv "a" conv true conv 1 << 128 conv :a conv [4,5,6] conv({:a=>1, "b"=>0.1}) puts conv 1..4 conv /.*/ conv proc{} require 'set'; conv Set.new [] conv 1.class conv Java begin 1.java_class rescue => e conv e end puts conv Dir.new "." conv (f=File.new("conv.rb")); f.close conv [9,8].to_java conv [9,8].to_java :int
- 結果
class java.lang.Long:1 class java.lang.Double:1.1 class java.lang.String:a class java.lang.Boolean:true class java.math.BigInteger:340282366920938463463374607431768211456 class org.jruby.RubySymbol:a class org.jruby.RubyArray:456 class org.jruby.RubyHash:a1b0.1 class org.jruby.RubyRange:1..4 class org.jruby.RubyRegexp:(?-mix:.*) class org.jruby.RubyProc:#<Proc:0x257807a@conv.rb:19> class org.jruby.RubyObject:#<Set:0x176f5261> class org.jruby.RubyClass:Fixnum class org.jruby.RubyModule:Java class org.jruby.RubyNoMethodError:undefined method `java_class' for 1:Fixnum class org.jruby.RubyDir:#<Dir:0x552a66ea> class org.jruby.RubyFile:RubyFile(conv.rb, 1, 4) class [Ljava.lang.Object;:[Ljava.lang.Object;@174323d5 class [I:[I@637050f5
JRubyからJavaにclassオブジェクトを渡す
JRubyからJavaにclassオブジェクトを渡すとどの型になるのか試してみた。
Javaのコードは単純にclass文字列表現をprint
public class ClassSample{ public static void print(Class clazz){ System.out.println(clazz.toString()); } }
JRubyではJavaのビルトインクラスとJRubyで定義したクラス(継承ありなし)のclassオブジェクトをJavaに渡す
include Java Java::ClassSample.print java.util.Date.class Java::ClassSample.print java.util.Date.java_class class ClassA; end Java::ClassSample.print ClassA.class begin Java::ClassSample.print ClassA.java_class rescue => e p e end java_import 'java.util.HashMap' class ClassB < HashMap ; end Java::ClassSample.print ClassB.class Java::ClassSample.print ClassB.java_class
その結果
class org.jruby.RubyClass class java.util.Date class org.jruby.RubyClass #<NoMethodError: undefined method `java_class' for ClassA:Class> class org.jruby.RubyClass class java.util.HashMap
ClassBがHashMapになるのが意外
Ruby to Java 変換表
JRubyからJavaのメソッドを呼ぶ場合、メソッドの引数は自動で型変換される。
Javaのメソッドの引数を具体的な型で定義したとき、Rubyのどの型を受け入れられるか調べた。
(以下のようなメソッドをJRubyから引数に様々なものを入れて呼び出してみた)
public static void i(int i){ System.out.println(i); }
プリミティブ型
Java引数型 | Ruby -> Java |
---|---|
boolean | nil/false -> false, true -> true |
char | nil -> '\0', Fixnum/Float -> char |
byte | nil -> 0, Fixnum/Float -> byte |
short | nil -> 0, Fixnum/Float -> short |
int | nil -> 0, Fixnum/Float -> int |
long | nil -> 0, Fixnum/Float -> long |
float | nil -> 0.0, Fixnum/Bignum/Float -> float |
double | nil -> 0.0, Fixnum/Bignum/Float -> double |
Wrapperクラスもnil -> nullになるほかは同じだった。
BigIntegerとString
Java引数型 | Ruby -> Java |
---|---|
BigInteger | Fixnum/Bignum/Float -> BigInteger |
String | String/Symbol -> String |
Number型、BigDecimal型は型変換されずダメだった。(nilのみ受け入れ)
Collection
Java引数型 | Ruby -> Java |
---|---|
List | Array -> org.jruby.RubyArray(implements List) |
Collection | Array -> org.jruby.RubyArray(implements Collection) |
Iterable | Array -> org.jruby.RubyArray(implements Iterable) |
Map | Hash -> org.jruby.RubyHash(implements Map) |
RubyArrayはList,Collection,Iterableを実装している。
ArrayList, HashMapなどの具象クラスは型変換されない。
(RubyArrayはArrayListではないので当然か)
Set, HashSetはダメだった。
Servlet 3.0のアノテーション
@WebServletアノテーションを使うとweb.xmlいらないということで試してみた。
Tomcat 7.0.2で実験
以下のコードをwebapps/sample/WEB-INF/classes/sampleに置いてコンパイル
package sample; import javax.servlet.annotation.*; import javax.servlet.http.*; @WebServlet("/app/*") public class SampleServlet extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) throws java.io.IOException{ res.getWriter().print("testtest"); } }
これでhttp://localhost:8080/sample/app/a にアクセスでうまくいった〜
HttpServletの継承が必要なのはちょっとめんどいかも。
このコードをJRubyで書いてjrubyc --javaでJavaコードに変換できるかなあと思ったけど無理だった。
JRubyのJavaインテグレーションにあらためて限界を感じた・・・
自動的に閉じるJavaファイルストリーム
JRubyで外部のJavaライブラリと連携とかするとき、RubyのFileクラスのopenのように自動的に閉じるFileInputStream、FileOutputStreamがほしいので作ってみた。
わりと簡単に作れる
include Java class FileInput def self.open(file, &block) raise "no block given" unless block_given? begin input = java.io.FileInputStream.new(file) yield input ensure input.close unless input.nil? end end end class FileOutput def self.open(file, &block) raise "no block given" unless block_given? begin output = java.io.FileOutputStream.new(file) yield output ensure output.close unless output.nil? end end end
つかうときはFileOutput.open("filepath"){|out| ... }みたいな感じで
シーケンス図のリバース
シーケンス図をソースコードからリバースして作成するツールでいいのがないか探してみたけど、SoyatecのeUML2ってのがなかなかよさそう。
http://www.soyatec.com/euml2/
JavaでのExcel操作ライブラリ
POI以外にもExcellaというExcel操作ライブラリがあるらしい
http://excella-core.sourceforge.jp/
POIは正直使うの面度すぎなので、こういうのがあると楽できそう