SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

オープンソースApache Tuscanyで楽しむSOA

オープンソースApache Tuscanyで楽しむSOA
第7回「JRubyをサービス化しましょう」

CalcChargeをJavaからJRubyに書き換え

  • X ポスト
  • このエントリーをはてなブックマークに追加

ダウンロード サンプルコード (18.9 KB)

JavaからJRubyへの置き換え手順

 CalcChargeImplをJavaからJRubyに置き換える手順は次のとおりです。

  • JRubyでCalcChargeインターフェースを満たすコードを実装する
  • コンポジットファイルを修正する

 たったこれだけ? と思われた方も多いでしょう。筆者もこの簡単さを皆さんに紹介したくて記事を書きました。

JRubyでCalcChargeのインターフェースを満たすコードを実装する

 冒頭でも言ったとおり、筆者はJRubyを書いたことが一度もありませんでした。図1が最初に書いたCalcChargeImpl.rbの抜粋です。特に複雑なことを行っていないので非常に楽でした。

図1.最初のJRuby
図1.最初のJRuby

 ただし、実行しても送料と合計が表示されません。retValuesの値も実行ログ(図2)を見るときちんと計算されています。

図2.実行ログその1
図2.実行ログその1

 こういう場合は正攻法が1番です。BasketImplにブレークポイントを置きデバッグです。図3のように104行目のcalcCharge.getChargeの戻り値をint型の配列に代入する箇所、105行目の戻り値を返す箇所の2か所に置きました。

図3.BasketImpl#getTotalのブレークポイント
図3.BasketImpl#getTotalのブレークポイント

 104行目までは進むのですが、105行目まで進まず、処理が終わります。図2できちんと値を返していると思っているのが間違いである可能性が大きいです。例外が発生していれば、例外を補足していないため落ちるはずです。ただ、ここはJRubyからの戻り値を扱っているため何か起きていても不思議ではありません。考え付くのは例外以外はありません。図4のようにtry catchブロックで処理を囲みました。

図4.chargeCalc#getChargeをtryブロックに入れる
図4.chargeCalc#getChargeをtryブロックに入れる

 やはり図5のようにClassCastExceptionが発生していました。ClassCastExceptionはRuntimeExceptionを継承したクラス、つまりチェック例外で、発生したメソッド内で例外を補足しなくてもエラーで落ちることはありません。しかも、戻り値として期待していた単なるint型の配列ではなく、org.jruby.RubyArrayでした。この後はJRubyを知っている方には当たり前なのかもしれませんが、筆者は苦労しました。org.jruby.RubygetArrayというメソッドを持っており、JavaのArrayListを返してくれます。しかし、ここで行き詰ってしまうのです。JRubyにはJavaのプリミティブに相当する概念がありません。仕方なく当初の目的を捨て、CalcChargeImpl#getChargeの戻り値をArrayListに変え、ArrayListから1つずつ値を取り出し、int型に変換し、配列に格納するという非常に不格好なコードができてしまいました。

図5.戻り値はorg.jruby.RubyArray
図5.戻り値はorg.jruby.RubyArray

 ただし、これでは言語を変えるたびにインターフェースも変えなくてはならないことを意味しています。幸いこの場合、CalcChargeのサービスをコンポジットの外部に公開していないからいいのですが、公開している場合であれば、それを利用している他のコンポジットあるいはドメインにまで影響を与えます。ネットで粘って探した結果、JRubyのreturn文の中で、戻り値をretValues.to_java(:int)とするだけなのです。これだけでorg.jruby.RubyArrayがJavaのint型の配列に変換されます。言語間のインターフェイスはできるだけシンプルなものがいいということが言われますが、配列は要注意です。

 これでBasketImplの実装やCalcCharge#getChargeの戻り値も変えることなく、当初の目標をクリアできました。CalcChargeImpl.rbの詳細は、ページトップにサンプルコードがあるので、ダウンロードして参照していただければと思います。

コンポジットファイルを修正する

 JavaからJRubyへの置き換え手順として、「JRubyでCalcChargeインターフェースを満たすコードを実装する」方法を説明しましたが、当然、コンポジットファイルも修正しないと動作しません。同時に説明すると混乱するためあえて別の節として取り上げています。

 コンポジットファイルの修正も至って簡単です。図6のように指定するだけです。2点注意すべき点があります。1点目はCalcChargeのt:implementation.script要素のscript属性の値は、図7のようなフォルダ構成の場合、「jp/kawakubo/wine/CalcChargeImpl.rb」のようにパス指定になります。JRubyをここに置く必要はまったくありません。srcの下にscriptsというフォルダを作り、その下に置く場合は「scripts/CalcChargeImpl.rb」のように指定します。2点目は、既にお気づきかとは思いますが、component要素の子要素はimplementation.scriptではなく、頭にt:が付くことです。JRubyはSCAに準拠しているわけではなく、Tuscanyの実装だからです。composite要素の属性としてxmlns:t="http://tuscany.apache.org/xmlns/sca/1.0"を指定していることからお分かりいただけると思います。

図6.コンポジットファイルの指定
図6.コンポジットファイルの指定
図7.フォルダ構成
図7.フォルダ構成

忘れ物

 チェックの厳しい方はお気づきかもしれません。タイムセールスのメソッドに渡すためのproperty要素をまだ記述していないのです。いろいろな文献やサイトを調べても欲しい情報が得られず、組み合わせ表を作り調査すること4時間、たどりついたのが以下の結果です。

プロパティの注入の仕方
  • コンポジットファイルのルート要素の属性に「xmlns:xsd="http://www.w3.org/2001/XMLSchema"」を追加(図8)
  • 注入したいコンポーネントのproperty要素にtype属性を追加(図9)
  • JRubyでプロパティを受け取るために属性名の頭に$を付ける(図10)
図8.XML Schemaを使用できるようにする
図8.XML Schemaを使用できるようにする
図9.property要素にtype属性を追加する
図9.property要素にtype属性を追加する
図10.JRubyでの受け取り方
図10.JRubyでの受け取り方

 これで、CalcChargeImplをJavaからJRubyに置き換えることができました。他のプログラムに一切手を加えていないことは非常に驚きです。コンポジットファイルを少し修正するだけで済みました。Groovyが得意な人、Pythonが得意な人はぜひ、CalcChargeImplをそれらの言語で置き換えてみてください。

 次回は、Javaで書いたコードをGroovyへも簡単に置き換えられることを説明します。

修正履歴

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
オープンソースApache Tuscanyで楽しむSOA連載記事一覧

もっと読む

この記事の著者

川久保 智晴(カワクボ トモハル)

haruプログラミング教室(https://haru-idea.jp/)主宰。COBOL、FORTRANで13年、Javaを中心としたWeb開発で11年。3つしか言語知らないのかというとそうでもなく、sed/awk、Perl、Python, PHP,  C#, JavaScriptなども一時期は業...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/4633 2009/12/18 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング