ヒマをみつけてWeb開発
その場の思い付きを、ヒマをみつけてWebサイトにしてみるブログ

Javaと.NETのエンディアンの違いでCassandraの互換性崩壊( ̄□  ̄ ||

Friday, 4 June 2010 02:23 by sabro

昨日の件ですが、Javaと.NETでは、数値をバイト配列にした際の順序はやはり逆になるようです。バイト配列の格納方式はエンディアンといって、先頭から素直に並べるビッグエンディアンと、逆順に並べるリトルエンディアンがあります。

Javaの場合は常にビッグエンディアンとなり、.NETの場合は、CPUによって並べ方が変わるようです。x86系のCPUでは、リトルエンディアンになるみたいですね。.NETでは、BitConverterクラスに、IsLittleEndianというフィールドがあるので、それを見て、自前でバイト配列を並べ替えることで対処は出来るみたいです。

で、Cassandraemonで数値を格納するときにどうするか決めないといけないわけです。少なくともLongTypeのカラム名に格納する際は、ソートできるようにビッグエンディアンへの変換が必要ですね。他の場合はどうするか・・・。Thrift側でやってくれたらよかったんだが。

1、すべての数値を格納前にビッグエンディアンへ変換する

とりあえず、数値をToCassandraByte関数などでバイトへ変換するときは、常にビッグエンディアンにしてしまうというやり方がまず考えられます。このやり方だと、カラム名だけでなくカラムの値もビッグエンディアンになります。この方式のいいところは、Javaと相互運用が可能な点です。常にビッグエンディアンが格納されるので、Javaからも問題なく読みだすことができるはず。ただ、完全ではなく、数値を自前で野良バイト変換してCassandraへ格納した場合に、整合性が取れなくなることはありますね。

2、LongTypeのカラム名に格納するときだけビッグエンディアンへ変換

Cassandraemon側で、LongTypeのカラム名登録の場合だけ、自動でバイト配列を逆順にするやり方です。.NETから見た場合の相互運用性が高くなります。他の.NETクライアント、例えばhectorsharpなどから、カラム名以外は違和感なく値の取得ができると思います(そういえば、hectorsharpでは、この問題どうしてんだろ)。

3、自動的な変換はやらない

Cassandraemon側では一切変更を行わず、リトルエンディアン変換関数とかを用意しておき、LongTypeカラム名登録時は各開発者に自分で変換を行ってもらうやり方です。面倒ではありますが、どのカラムにどのエンディアンで格納されているかを開発者側が管理出来ると言うメリットがあります。ただ、値取得時に、このカラムはどのエンディアンかを意識して変換する必要もあるので、大人数での開発などでは混乱も起こるかもしれません。

以上、やり方考えてみましたが、どれにしようかなあ( ̄□  ̄ ) 個人的には1か3を考えてますが、みなさん希望とかありますでしょうか( ̄∇  ̄ )

Tags:   , , , ,
Categories:   .NET | Java
Actions:   Permalink | Comments (58) | Comment RSSRSS comment feed

JavaFX 発表

Monday, 14 May 2007 06:28 by sabro

NY から、こんにちは。

観光気分でやってきた NY の現場は、超修羅場でしたとさ orz
(なぜ、NY にいるのかは、こちらを参照。)

話は、変わりますが、Java One で、JavaFX が発表されましたね。

Silverlight、WPF、Flex、Apollo の台頭にみる今後のソフトウェア開発の方向性のエントリを書いていたとき、この波に乗れなかったら、Java は生き残っていけるのかと考えていました。しかし、このタイミングで、このようなRIAプラットフォームを発表するのは、流石です。

これらの技術のうち、どれを選択していくのか・・・。アーキテクト冥利に尽きる命題ですね。

Tags:  
Categories:   Java
Actions:   Permalink | Comments (47) | Comment RSSRSS comment feed

Propertiesクラスでnative2asciiを実装

Monday, 20 November 2006 00:00 by sabro

Javaでnative2asciiを実装の件ですが、Propertiesクラスを使って実装してみることにしました。

もともとnative2asciiは、Propertyファイルに日本語文字列を格納するためのツールであり、PropertiesクラスはそのPropertyファイルを読み込んだり書き込んだりするわけで、なにかしらの変換手段を持っているはずだからです。

JavaDocを見ると、どうやらgetProperty、setPropertyメソッドを使っているだけではUnicode変換は発生しないようです。storeメソッドでStreamに書き出したり、loadメソッドで読み出したりする際に変換が発生するとのこと。

実際にstoreメソッドで「あいうえお」と保存したとき、以下のように保存されていました。=以下の部分が変換後の文字列です。うまくこの部分を取得できれば変換が出来そうです。

##Sun Nov 19 22:55:25 JST 2006=\u3042\u3044\u3046\u3048\u304A

さらに今回はメモリ内で処理を完結させたいので、StreamにはByteArrayOutputStream、ByteArrayInputStreamを使います。以下ソースです。

Properties p=new Properties();
ByteArrayOutputStream bos=new ByteArrayOutputStream();
p.setProperty("", "変換文字列");p.store(bos, "");
int index=bos.toString().indexOf("=");
return bos.toString().substring(index+1).replaceAll("\\=", "=").replaceAll("\\:",":").replaceAll("\\#", "#").replaceAll("\\!","!").replaceAll("\\\\","\\");

変換する文字列をsetPropertyで格納し、storeメソッドでその内容をByteArrayOutputStreamに保存します。そして=以下の部分をsubstringで取得します。「#、!」はコメントに使われる文字なのでエスケープされています。最後の行でこれをエスケープされてない状態に戻しています。同様にkeyとvalueの区切りに使われる「=、:」、Unicode文字の先頭に使われる「\」もアンエスケープしています。

デコードのソースは以下です。

Properties p=new Properties();
ByteArrayInputStream bis=new ByteArrayInputStream("=".concat("変換文字列").getBytes());
p.load(bis);
return p.getProperty("");

文字列の前に=を連結してByteArrayInputStreamに保存した後、空文字をkeyとしてgetPropertyで取得するとデコードされます。

これで何とかnative2asciiは実装できそうです。ついでにURLエンコードとかも出来るようにしようかと考え中です。

Tags:  
Categories:   Java
Actions:   Permalink | Comments (43) | Comment RSSRSS comment feed

Javaでnative2asciiを実装

Saturday, 18 November 2006 00:09 by sabro

HTMLエンコードツールに、native2ascii機能も追加しようと思っていろいろ調べてみました。

とりあえず検索してみたんだけどライブラリは見つかんない。直接native2ascii.exeを呼び出すのはあんまりやりたくなかったので、native2asciiタスクを持っているAntの実装をパクッて参考にしてみることにしました。

検索してsun.tools.native2ascii.Mainというクラスを使っているところを発見。しかし、なぜかインスタンスを直接生成せずリフレクションを使ってクラスを取得しています。このクラスはtools.jarに含まれているそうなので、とりあえずプロジェクトでtools.jarを参照してみました。

でも、なぜかインテリセンスに上記クラスが現れません。無理矢理宣言してもコンパイルエラーになります。どうやらこういうことらしいです。sunパッケージ以下のクラスは将来的に動作が変更される可能性があるから使わないでくださいとのこと。それで、Antでもリフレクションで呼んでたのか。っていうかAntはこの注意事項を守ってないんですね。ある意味男らしいです。

まずはリフレクションのgetDeclaredMethodsメソッドでsun.tools.native2ascii.Mainが持っているメソッドの一覧を取得してみました。publicなメソッドが3個しかありません。

public static void sun.tools.native2ascii.Main.main(java.lang.String[])
private static java.nio.charset.Charset sun.tools.native2ascii.Main.lookupCharset(java.lang.String)
private void sun.tools.native2ascii.Main.error(java.lang.String)
public synchronized boolean sun.tools.native2ascii.Main.convert(java.lang.String[])
public static boolean sun.tools.native2ascii.Main.canConvert(char)
private java.lang.String sun.tools.native2ascii.Main.formatMsg(java.lang.String,java.lang.String)
private java.io.BufferedReader sun.tools.native2ascii.Main.getA2NInput(java.lang.String) throws java.lang.Exception
private java.io.Writer sun.tools.native2ascii.Main.getA2NOutput(java.lang.String) throws java.lang.Exception
private java.lang.String sun.tools.native2ascii.Main.getMsg(java.lang.String)
private java.io.BufferedReader sun.tools.native2ascii.Main.getN2AInput(java.lang.String) throws java.lang.Exception
private java.io.BufferedWriter sun.tools.native2ascii.Main.getN2AOutput(java.lang.String) throws java.lang.Exception
private static void sun.tools.native2ascii.Main.initializeConverter() throws java.io.UnsupportedEncodingException
private void sun.tools.native2ascii.Main.usage()

convert関数の引数に、入力ファイルパスと出力ファイルパスを渡すことで一応変換は出来ました。以下動作したコードです。

Class n2aMain = Class.forName("sun.tools.native2ascii.Main");
Method convert = n2aMain.getDeclaredMethod("convert",new Class[]{String[].class});
Object o = n2aMain.newInstance();
convert.invoke(o,new Object[]{new String[]{"C:\input.txt","C:\output.txt"}});

ファイル経由以外ではダメみたいでした。しかも、エンコードは出来てもデコードができません。(なんかデコードに使われてそうなprivateメソッドはもってるのに。)

メモリ内で処理完結できて、デコードにも対応する方法がないかもう少し探してみることにします。

Tags:  
Categories:   Java
Actions:   Permalink | Comments (45) | Comment RSSRSS comment feed

JavaでHTMLエンコード(2)

Sunday, 29 October 2006 14:44 by sabro

前回みつけたHTMLエンコード関数を試したのですが、「<、>、&、"」とかの記号だけでなく、2バイト文字までエンコードされてしまいました・・・orz

<あいうえお>
  ↓  変換
&lt;&#12354;&#12356;&#12358;&#12360;&#12362;&gt;

まあ、HTMLに貼り付けたら2バイト部分もデコードされて正しく表示されたので、よしとさせていただきますか(´△`)

Tags:  
Categories:   Java
Actions:   Permalink | Comments (49) | Comment RSSRSS comment feed

JavaでHTMLエンコード

Thursday, 26 October 2006 21:45 by sabro

JSFも大分わかってきたので何か練習で作ろうと思いたつ。

アイデアを絞り出した結果、すでに世の中に腐るほどあるHTMLエンコードツールを空気を読まずに作ってみることにしました。

一から作るのもメンドイので、HTMLエンコード機能を持つクラスをJavaの標準クラスライブラリで探したところ・・・。見つかんない・・・orz

ここはアーキテクトっぽく意地でもライブラリを探して再利用だと意気込んで、Jakarta Commonsを漁る事に。

Commons CodecCommons HttpClientと探したが見つからず、諦めかけていたのですが、Commons LangStringEscapeUtilsというクラスがありました。Encodeじゃなく、Escapeだったのか。

escapeHtmlやescapeJavaScriptなど使いやすそうな静的メソッドがたくさんあり、思わぬ収穫でした。

Tags:  
Categories:   Java
Actions:   Permalink | Comments (51) | Comment RSSRSS comment feed

Javaにします

Sunday, 24 September 2006 14:38 by sabro

言語は結局Javaにすることにしました。しかも、1.4です(フツー)。

Ruby on Railsを勉強したかったので迷っていたのですが、自動生成される4種類のViewが活用できそうになかったので残念ながらやめておきました。なんせDBの更新はバッチで行う予定なんで。実際、Railsがピタリとハマるのは、ある程度単純なWebサイトでないと難しいんじゃないでしょうか。

Categories:   Java
Actions:   Permalink | Comments (36) | Comment RSSRSS comment feed

PebbleのPing送信失敗

Wednesday, 20 September 2006 15:26 by sabro

このブログは、ややマイナーなPebbleというツールで構築しています。PebbleはJavaで書かれているのですが、他のJava製品にありがちな面倒な設定がなく、warファイルを配置するだけで設置完了というお手軽さが特徴です。

このPebbleにPing送信機能がついてたので設定してみたのですが、どうやら失敗していたようで以下のようなログが出ていました。

2006-09-20 01:23:17,306 [Thread-45] ERROR pebble.webservice.UpdateNotificationPingsClient - Exception when calling weblogUpdates.ping at http://ping.cocolog-nifty.com/xmlrpcjava.io.IOException: Invalid character data corresponding to XML entity ヒ        at org.apache.xmlrpc.XmlRpcClient$Worker.execute(XmlRpcClient.java:444)        at org.apache.xmlrpc.XmlRpcClient$Worker.executeAsync(XmlRpcClient.java:363)        at org.apache.xmlrpc.XmlRpcClient$Worker.run(XmlRpcClient.java:349)        at java.lang.Thread.run(Thread.java:534)

仕方ないので「XmlRpcClient Invalid character data corresponding to XML entity」で検索を掛けてみると、以下のページを発見。

Apache XML-RPCではまったこと

なんでもXML-RPCに日本語処理のバグがあるとか。(XML-RPC2.0では直っているらしいです。Pebbleが使っているのは、XML-RPC1.2-b1。)

仕方ないので、ここから、XML-RPCのソースをダウンロードしてXMLWriter.javaを1行修正。

if (c < 0x20 || c > 0xff)      ↓if (c < 0x20)

Antでビルドして、できたxmlrpc-1.2-b1.jarをPebbleが使っているものと置き換えてみました。

これで直っていたらこの記事を送信後、Pingが飛ぶはずです。

Tags:   ,
Categories:   Java
Actions:   Permalink | Comments (36) | Comment RSSRSS comment feed