2010年12月14日火曜日

JAVAとAIRの連携について

現在開発中のアプリケーションには大容量のファイルを圧縮する、という処理をAIRで行わなければならない。

調べてみるとAirでZIPを作成するライブラリがあるのだが、正直遅い。
おまけに200を超えたあたりでエラーで落ちる…。

これでは物にならないので考えたのが、じゃあJAVAに振ってしまえと。
JAVAならクロスプラットフォームを維持できる。

じゃあどうやってAIRからJAVAを動かそうか、という話になって浮かんだ可能性が2つ

・ソケット通信にてAIRとJAVAを連携

・NativeProcessにてJAVAを起動

前者のは既に以前行っており、ある程度動くことは想定された。
ただ、ソケット通信をするためにはAIRがソケット接続を行いに行った際にサーバー側であるJAVAが動いていないと駄目。

更にAIRからJAVAを動かすことができないからソケット通信なんていうものを行おうとしているのに、これでは本末転倒である。
で、発想を逆転させてJAVAからAIRを動かそうぜ、と。

つまりJAVA起動 > AIR起動 > ソケット接続(AIR) > ソケット送信(AIR) > ソケット受信(JAVA) > プロセス起動(JAVA)

になる。

はっきり言って動作的には問題ない。

が、いくつかの問題点がある。

1.JAVAがサーバー状態になるのでプロセスに常時残る。
2.AIRインストール時、別個起動ショートカットをJAVAにしておく必要がある
3.AIRからJAVAが生きているかどうか判断ができない
4.JAVAからAIRに何かしらイベントを送ることができない

まず1がMacで見るとタスクに出てしまうのでカッコ悪い…。
windowsならありなんだが。

2についてはつまり、毎回新規インストール時にこちらが面倒を見なければならない。
かといって、クライアントに作業してもらうには少々微妙な内容。

3は結構致命的。何らかの理由でJAVAが死んだ際にもうお手上げ。

4も連携を取るのが出来ないわけではないにしろカッコ悪い。
例えばとあるテキストファイルをAir側で監視しておいて、そこにjavaが書きこんだら~で出来なくはない…。

では続いて後者へ
まあこっちもこっちで問題があって、まずbatファイルは起動できない。
いやまあ、javaで使用してるライブラリが全部標準ライブラリなら問題ないんだけれど、そうもいかないので。

あー、でもどうなのかな。クラスパス通ってなかったら動かないのかな?

という問題を解決するために思い至ったのがjarのexe化。
結構画期的だと思ったんですけどね…。

当初はJSmoothというツールを使ってexe化してたんですが、これでexe化するとAir側でハンドルするプロセスの終了イベントの発生タイミングがおかしい。
とりあえず最後にメッセージボックスを表示すれば何とか逃げられたのでこれで逃げてたのがこの前までのお話。

でもほら、カッコ悪いじゃない。

最後に明らかにデザイン?がおかしいメッセージが出てくるなんて。
おまけにそのZIPをアップロードしたり、そのあとにデータを書き込んだりすることを考えると、中間のタイミングでメッセージ出るなんて正気の沙汰じゃない。

というわけで昨日夕方から時間が空いたので取りこんだのが今回のお話。

そのあと奮戦してexewrapとか使ってみたりしても駄目。

じゃあまあ、原点に帰ろうぜということで
AirからNativeProcessを利用してJAVAを動かしたい、と考えるのは俺だけじゃないはずだ!!

というわけでggったらこんなのが

http://irpart.blogspot.com/2010/01/adobe-air2-nativeprocess.html

まさに俺がしたかったことじゃないか!!

つまりコマンドプロンプトで「java ~~~~」と書く所の先頭のJAVA.exeに引数を与えてJAVAの正規実行にしてしまおうと。

なんて王道。

邪道ばっかり歩いてきた誰かとは発想が違う。

で、ここからは今度はJAVAのスキル不足が露呈。
クラスパスの設定だとかが分からなくて苦戦苦戦…。
絶対パスの考え方の問題なんですよねぇ…。

メインメソッドが見つかりませんとかもう見飽きました!!
で、まあ何とかできました!

  private var _process:NativeProcess;
  _process = new NativeProcess();
 
  var _info:NativeProcessStartupInfo = new NativeProcessStartupInfo();
  var _file:File;
 
  _file = new File("C:/Program Files/Java/jdk1.6.0_20/bin/java.exe");
 
  var args:Vector.<String> = new Vector.<String>;
  args.push("-cp");
  args.push('"C:/Flex Builder 3/ZIPSample/bin-debug/;C:/Flex Builder 3/ZIPSample/bin-debug/ant.jar;C:/Flex Builder 3/ZIPSample/bin-debug//ZipComp.jar"');
  args.push("ZipComp");//実行するクラス
  args.push("圧縮するファイル");
 
  _info.executable = _file;
  _info.arguments = args;
 
  _process.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA,RunProcsSTD_OutHandler);
  _process.addEventListener(ProgressEvent.STANDARD_ERROR_DATA,RunProcsSTD_ErrHandler);
  _process.addEventListener(NativeProcessExitEvent.EXIT,RunProcsExit);
 
  _process.start(_info);


ちなみにjavaはもちろんjar化しておきます。
インスコ後にコンパイルしてもらうわけにはいかないので

C:/Flex Builder 3/ZIPSample/bin-debug/
っていうのはもちろんアプリの実行されているパスですね。

で、これも一個だけ問題が。
Macはjava.exeのパスが固定?っぽいんだけど、windowsはちょくちょく更新がかかるせいで
jdk1.6.0_20 とか jdk1.6.0_16 とか jdk1.6.0_15 とかあるわけなんですよねぇ…

まあ初回起動時にどれ使うって選択させる必要があるのかな。
うちの○○とかがそんな選択画面を見たら分からん分からんって大騒ぎしそうだけど

ちょっと話が逸れるけど、人が一生懸命1から10まで隙がないように努力して書いた説明見ないんだぜ?
ついでになるべく簡潔にまとまるように考えて書いてるんだぜ?

抜けてたら揚げ足取る癖にろくに見ないんだぜ?
見ないなら見ないでいいけど、わからなかろーがなんだろうが何も聞くなっての。


ここまで書いて、今後似たようなことあって、ここ見ろって言っても絶対最後まで読まないんだろうなぁ…。
まあ、ここでの文章は色々抜けがあるからいいっちゃいいけどさ。

そういえば1から10を話さず10だけ話す人がいるんだ。
ことわざで1を聞いて10を知る、というのがあるけどそれはまだ出来なくはないと思うんだ。
だって、1を聞いて2を予想し、3に繋げて・・・内容次第では出来ると思うんだ。
でもさ、10だけ聞いて分かる人っていないと思うんだ。

例えば数学で答えは「10」と言われたとしよう。
それで全貌を把握なんてできないと思うんだ。
足し算なのか引き算なのか、掛け算なのか割り算なのかさえ分からないんだぜ…?
絶対無理。
誰か通訳plz

0 件のコメント:

コメントを投稿