Archive for 1月, 2011
ある方から、このような質問をちらほらとうけるようになってきた。
それも、つい最近立て続けてだ。
私自身、そもそも使えないと思っていたので、使えるかどうかなど意識せずに、AIR用として作ってきた。
だから、そのような質問に対して満足な答えを持っていない。
なので、どうしてそう思うのか教えてくれ?と聞いたところ、
ある方から、
http://www.adobe.com/devnet/flashplayer/articles/socket_policy_files.html
のような情報をいただいた。
確かに、Socketは使えそうだ。
なので、技術レベルの仕様ではなんとかなりそうだ。
でも、任意のimapなり、pop3なり、smtpのサーバにこのようなポリシー要求をうけ入れるサービスなんてあるのだろうか?
せっかくなので、もうちょっと調べるのは価値がありそうだが、
airxmailはブラウザ上でのswfアプリでは使えるか?よりも、このようなポリシーを受け入れるメールサーバがありそうか?
のほうがどうやら障壁は高そうな気がする。
まあ、踏み台サーバがあればいいのかもしれないが・・・・
そういう意味では、私が今作り始めている、Java版のAIRとの接続するローカルサーバ(別にローカルである必要はないのだが)はある意味では、
踏み台サーバになるのだが・・・・
関係ないが、AIRも、PortableAppのようにインストールなしに使えればいいのだが・・・・・とおもっているのは少ないのでしょうか?
突然ですが、掃除機ねた。
というのも、かなりびっくりしたからです。
機能掃除機を買ってきました。
きっかけは、今まで使ってきた掃除機が単に壊れたからです。約10年前の製品からの買い換えです。
それで、ちょっとびっくりしたことがありました。
最近はやりの「サイクロン」掃除機のコーナーがあるわけです。
もちろん、いくら白物家電にそれほど詳しくないからと言って、それなりにはわかります。
まあ、サイクロン掃除機も安い物は2万円くらいからあるし、それにしようとしたわけです。
それで電気屋に行きました。
店員>「紙パックでないものをお探しですか?」
私>「まあ、ちょっとこれなんかお手頃で」
と、東芝のサイクロン掃除機(約2万円)を見せてもらいます。
で、もって、ゴミ捨ての部分を説明してもらい・・・
私>「あれ、これってどこで遠心分離が行われるのですか?」
と質問。
なぜなら、どう見ても紙パックがないだけの構造にしか見えず、サイクロンって???
店員>「あー、そういう意味ですね。そういう意味では、サイクロンではありません。今では紙パックでないものを一般的にサイクロンと呼んでいます」
店員>「まあ、それでしたらダイソンとかのような高いレベルでないとないですね。あとはシャープですね。」
えー、サイクロンって遠心分離でゴミを分離するからいいところがあるんじゃないんですか?
よいところのイメージでサイクロンを売って・・・
というわけで
にしました。
まあ、10年前の製品に比べたらどれでもいいんじゃないんですか?
ということで、ハイパワーだの、細かい機能にはそれほどこだわりませんでした。
それで値段が跳ね上がるのはいやですし・・・
サイクロン。
確かに、フィルタ掃除が大変そうですが、
家のフィルタ(24H自動排気がありますから)の掃除も1ヶ月毎にしなければならないので、
まあ、いいかと。
でも、家電業界で「サイクロン」が「紙パックなし」という意味とは信じられないです。
確かに、最初に店員が
「サイクロン掃除機をお探しですか?」
ではなく、
「紙パックがないのをお探しですか?」
と聞いてきたのをみるとなんだか、関係があったのかもと・・・・
前回、Javaで定期的な処理を動かしたい(1)で、
1)cronでJavaを起動し、このJavaVM上で処理を行う。
2)デーモンプロセス(としてのJavaVM)上でスケジューリングして、そのVM上で処理を行う。
3)cronでJavaを起動し、処理を行っているデーモンプロセス(としてのJavaVM)上で処理を行う。
という3つの方法を示した。
そして、今回は順番がちぐはぐになってしまったが、リストの(3)の処理を考える。
前提条件として、JDK6を使っています。
JMXのサーバ側の処理を作る。
JMXServerSampleMXBean
package com.coltware.java.samples.jmx;
public interface JMXServerSampleMXBean {
public static final String SERVICE_ADDRESS = "service:jmx:rmi:///jndi/rmi://localhost/jmx_sample";
public static final String OBJECT_NAME = "com.coltware.java.sample.jmx:Type=JmxServer";
public int batchTask1();
}
JMXServerSample
このクラスが、JMXのサーバになり、また、処理を実行するためのクラスである。
実際に処理をするクラスは別にした方がいいだろうが、ここでは例を短くするためにも1つにしている。
また、実際に処理を実行するメソッドは、batchTask1()というメソッドである。
(特にサンプルの為に何もしないメソッドではある。)
package com.coltware.java.samples.jmx;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.net.MalformedURLException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import javax.management.InstanceAlreadyExistsException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
/**
*
* @author coltware@gmail.com
*/
public class JMXServerSample implements JMXServerSampleMXBean{
/**
* JMXで使うポートです。1099以外ではだめなのか不明です。
* ただ、JMXはマネジメントツールですから・・
*/
private static final int JMX_PORT = 1099;
private int execCnt = 0;
/**
* @param args
*/
public static void main(String[] args) throws Exception{
JMXServerSample instance = new JMXServerSample();
// start jmx server
instance.startJmxServer();
System.out.println("start jmx sample server");
// 今回はサンプルの為、単なる時間稼ぎ処理
Thread.sleep(1000*100);
System.out.println("end jmx sample server");
}
/**
* JMXのサーバをスタートする処理
*
* @throws RemoteException
* @throws MalformedObjectNameException
* @throws InstanceAlreadyExistsException
* @throws MBeanRegistrationException
* @throws NotCompliantMBeanException
* @throws MalformedURLException
* @throws IOException
*/
protected void startJmxServer() throws
RemoteException, // (1)
MalformedObjectNameException, // (2)
InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException, // (3)
MalformedURLException, // (4)
IOException // (5)
{
LocateRegistry.createRegistry(JMX_PORT); // (1)
MBeanServer mbserver = ManagementFactory.getPlatformMBeanServer();
ObjectName obj = new ObjectName(JMXServerSampleMXBean.OBJECT_NAME); // (2)
mbserver.registerMBean(this,obj); // (3)
JMXServiceURL url = new JMXServiceURL(JMXServerSampleMXBean.SERVICE_ADDRESS);
JMXConnectorServer jxmServer = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbserver); // (5)
jxmServer.start();
}
public int batchTask1(){
//
// ここで何らかのバッチ処理をすればよい
//
// 今回は、実行回数を返しているが、任意の結果を返してやればよい
//
return ++execCnt;
}
}
JMXClientSample
JMXのクライアント側の実装であり、処理を起動するためのクラスである。
このプログラムをcronで動かせばよいわけである。
package com.coltware.java.samples.jmx;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
public class JMXClientSample {
/**
* @param args
*/
public static void main(String[] args) throws Exception{
JMXServiceURL url = new JMXServiceURL(JMXServerSampleMXBean.SERVICE_ADDRESS);
JMXConnector connector = JMXConnectorFactory.connect(url);
MBeanServerConnection conn = connector.getMBeanServerConnection();
ObjectName oname = new ObjectName(JMXServerSampleMXBean.OBJECT_NAME);
System.out.println("result is [" + conn.invoke(oname, "batchTask1",null,null) + "]");
}
}
実際に、JMXのサーバ側(JMXServerSample)を起動するときには、
-Dcom.sun.management.jmxremote
という、JVMの引数をつける必要がある。
(これを見てもわかるように、このJDKの実装は元Sunの実装であり、そのほかのJDKではどうすればよいかはわかりません。)
次は、JMXのクライアント側(JMXClientSample)をcronなりで実行します。
このプログラムを使わなくても、もし、手動で起動したい場合には、jconsoleなどを使うこともできます。
ちなみに、このサンプルではリモートからの起動を想定はしていませんが、
JMXを使っていますので、ちょっとした対応の追加でリモートからの起動もできると思います。
ですので、crontabを指定するサーバを1つにして、複数のサーバに対してスケジューリングをしていくことも可能になるわけです。
Android SDKのコマンドを使うのにどうしても、Windowsからのコマンド操作に違和感があるので、
Linuxから接続することにしました。
といっても、Linux on Windows VMWare Workstationからの接続です。
これで、
[root@vaioz android-sdk-linux_86]# ./platform-tools/adb devices List of devices attached SSHEKxxxxxx device
みたいに表示されました。
なので、
adb shell
でログイン可能です。
でもって、次に、bashとbusyboxを入れていきます。
それで、下の図がbusybox topを実行したときの結果。
ただ、よく使うコマンドはalias機能がないので毎回busybox whichみたいにたたくのも面倒だし、bashの補完もきかないので、
#!/system/bin/sh /data/local/busybox which $1
みたいにshellでラップしてやる。
これで、だいぶ開発環境として使いやすくなった。
表題のとおり、Javaでカレンダー的なスケジューリングした処理を動かしたいと思った。
つまり、毎週月曜日の・・・とか、毎時AM4時の・・・とかといった具合だ。
ここで、私が考える方法は以下の3つ。
1)cronでJavaを起動し、このJavaVM上で処理を行う。
2)デーモンプロセス(としてのJavaVM)上でスケジューリングして、そのVM上で処理を行う。
3)cronでJavaを起動し、処理を行っているデーモンプロセス(としてのJavaVM)上で処理を行う。
1)は、最も単純で最も簡素なつくりであるが、毎回JavaVMが起動することはもちろん、
単体で動いてしまうので処理の状態や結果、情報をメモリ上に保存し、それを引き継ぐことができない。
なので、私の中でこの方法はまず却下。
どうしてもこれでよいならば、perlなどのスクリプト言語でちょちょいとやれる範囲だけにする。
2)が一番、Java環境としてはスマートそうだ。
この方法として、quartzというオープンソースがある。
これは、Java側からcronのようなタスク処理ができる。
まあ、あえてLinuxでこれと同じような機能は crontab + crond + atd だろう。
なので、Jobの追加や更新などもプログラムでしやすく、そのJavaVMだけに閉じている(閉じないこともできると思うが・・・)
ので、他からの影響を受けにくい。
よくcronでやると、人が記述してしまった記述を変更しないように、自分の管理している部分だけを書き換えるということが求められるので、
それはそれで厳しい。
そして、これ以外に私は使えそうなJavaのライブラリを知らない。
Javaの標準ライブラリでもある程度のことはできそうな感じがするが、ある時間単位での繰り返しならば何とかなりそうだが、
毎月月初(1日)みたいなカレンダー的なイベントがトリガーになるとちょっと厳しそう。
そういうわけで、quartzというライブラリがベター。
マニュアルも英語だし、情報も日本にたまっていないが、
外部環境(つまり、cronとか)にできるだけ依存したくないならば、一番よいと思う。
3)は、デーモンプロセス側のJavaVMに何らかの仕掛けが必要である。
しかし、通常デーモンとして生きているからには何らかの情報取得の仕掛けが必要なわけで、
その方法として私はJMXを組みん込んでしまう。(Servletエンジンを積んでいるのならばそれでもいいだろう。)
これならば、手動起動はjconsoleなどのプログラムでもできるし、
要はこの処理をcronで動かせば1のデメリットをできるだけ軽減し、
さらにJava上にスケジューリングする処理を記述しなくてもよい。
自社サービスで自社運用ならば、断然この3が自分はいいと思う。
ということで、2と3の方法を模索していく。
(といっても、これを書いている時点ではある程度模索は終了しているのですが・・・)
去年の今頃はgoogle app engine をやろうと思っていたのだが結果的にアカウントを作成しただけだった。
その上で動くもののイメージができなかったのと、思ったよりいろいろなものに手を出してしまいそちらに手が回らなかった
ということで今年は昨年手を出して中途半端になってしまったものをもうちょっと突っ込んでやろうかなと思う。
ただまったく新しいものがないのもつまらないのでこちらはandroid アプリだろう。
これらを絡み合わせてなにかつくりたいなと
ただAIR関連は当面今の延長線だけにしようかなと
AMFでローカルPCと連携するサービスの構築が中途半端なのでこれをもうちょっと作り込みたいし、実はブログには一切書いてないがjqueryも去年はかなり使い込んだので、やはりAMFにこだわらずwebsocket にまで広げたいと思ってなす。
もう去年の夏ぐらいからほったらかしな、
javaとflash(AMF)とのブリッジについて
だ。これをもうちょっとまじめに取り組むということだ。
あとは、androidの方はまずはちょっとしたアプリになると思い出すがこちらもPCと連携したいと思ってる。
でもってbluetoothをつかって接続したいとおもってます。
それで手もとにあるデバイスの連携ができたらいいなと
まずは、自分が使う機能を作ることが一番モチベーションも保てるだろうと思い、
Android上でbluetoothの汎用通信サーバを作ってみたいなと。
それで、PC上にはそのためのAgentを組み込み、ネットに接続と・・・・
なぜbluetoothかといえば、
1つは、ネットに接続できない環境でも連携が可能である。
2つは、USBなどのコネクタを必要としない(これは、単に私のノートPCに必ずbluetoothを組み込んでいるからだけかもしれませんが。。。)
という私が使うときに、主にネックとなるこの問題を克服したいからだ。
これができれば、そのほかの応用も広がってくる。
それに、これから本格的にクラウドで常にネットに接続できる時代がきつつあるなか、
あえてインターネットではなく地理的なローカルなネットもいいなかと
個人が趣味レベルでやるにはメジャーよりもマイナーなほうが価値もあると思いますし・・・
ということで要は今年はJAVA とC言語を中心にマルチデバイス関連の連携をと思っています。



