2013年5月30日

インスタンス生成時にコレクションに詰める

前回の記事で、ArrayListのインスタンスを生成するときに、要素を詰めた状態でnewしていました。

例えばこんな感じです。
List<String> list = new ArrayList<String>() {
    {
        add("element1");
        add("element2");
        add("element3");
    }
};

for (String s : list) System.out.println(s);

Map<String, String> map = new HashMap<String, String>() {
    {
        put("key1", "value1");
        put("key2", "value2");
    }
};

for (Map.Entry<String, String> entry : map.entrySet())
    System.out.println(entry.getKey() + ":" + entry.getValue());

実行結果はこの通り。しっかりと要素が追加されています。
element1
element2
element3
key2:value2
key1:value1

実は前述の記事の参考にしたページにのっていたのですが、長年Javaをやっていましたが、こんな記法を出来るとは知りませんでした。

そこで調べたところ、このクラス、Innerという名前でつくっていたのですが、2つの無名インナークラスが作られていました。
Inner.class
Inner$1.class
Inner$2.class

そしてよくよく調べてみると、初期化ブロックという記法がありました。(http://java.keicode.com/lang/initialize-initialization-block.php)
staticの記法は使った事があったのですが、こんな書き方もあったのですね。

ということで、今回の件は初期化ブロックを定義した無名インナークラスを生成していただけ、ということでした。
わざわざ無名インナークラスにする意味はいまのところ見いだせてないですね。。。

過去に見たコーディングルールでは、

ひとつのソースファイルからクラスファイルが2個以上生成されるのは、1対1にならないからインナークラスは使ってはいけない。

といったよくわからないものがあったことを思い出しました。

クラスファイルを検索してクラス情報を抜き出す方法

「ライブラリ更新しました!」
「新しい機能追加しました!」

とライブラリだけ渡されたのですが、どんな更新がされたのか分からず困り果てました。

「クラス情報からとればいいんじゃね?」

というアイディアが。

指定パッケージ内のクラス一覧を取得するサンプル
上記を参考にJavaFileManagerを使うことで、指定パッケージのクラス一覧とそのメソッドを出力することができました。
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
JavaFileManager fm = compiler.getStandardFileManager(
        new DiagnosticCollector<JavaFileObject>(), null, null);

Set<JavaFileObject.Kind> kind = new HashSet<JavaFileObject.Kind>(){{
    add(JavaFileObject.Kind.CLASS);
}};

List<String> searchPackage = new ArrayList<String>(){{
    add("net.spy.memcached"); // 検索したいパッケージ
}};

for (String packageName : searchPackage){
    for (JavaFileObject f : fm.list(
            StandardLocation.CLASS_PATH, packageName, kind, false)) {
        Class<?> clazz = Class.forName(packageName + "."
                + f.getName().replaceAll("\\.class$", ""));
        System.out.println(clazz.getName());
        for (Method method : clazz.getMethods()) {
            System.out.println("\t" + method);
        }
    }
}

前後のdiffをとることで、増えたクラスやメソッドを簡単に見つける事が出来ました。
便利になったものです。

dig dug

digコマンドで見つからなかったときにどう出るのか試したくて、適当なドメイン名を検索してみました。
(この結果はhttp://www.cman.jp/network/support/nslookup.htmlの結果を貼っています)

dig hoge.com と・・
; <<>> DiG 9.3.6-P1-RedHat-9.3.6-16.P1.el5_7.1 <<>> ANY @監視ServerDnsN hoge.com
; (1 server found)
;; global options: printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63167
;; flags: qr rd ra; QUERY: 1, ANSWER: 8, AUTHORITY: 2, ADDITIONAL: 0
 
;; QUESTION SECTION:
;hoge.com.  IN ANY
 
;; ANSWER SECTION:
hoge.com.  14400 IN MX 100 smx.hoge.com.redcondor.net.
hoge.com.  14400 IN MX 10 vmx.hoge.com.redcondor.net.
hoge.com.  14400 IN MX 20 amx.hoge.com.redcondor.net.
hoge.com.  14400 IN MX 50 bmx.hoge.com.redcondor.net.
hoge.com.  14400 IN SOA ns1.nktelco.net. dns-admin.nktelco.net. 2008041101 10800 3600 604800 300
hoge.com.  14399 IN A 74.52.65.138
hoge.com.  14400 IN NS ns1.nktelco.net.
hoge.com.  14400 IN NS ns2.nktelco.net.
 
;; AUTHORITY SECTION:
hoge.com.  14400 IN NS ns1.nktelco.net.
hoge.com.  14400 IN NS ns2.nktelco.net.
 
;; Query time: 189 msec
;; SERVER: 監視ServerDnsN#53(監視ServerDnsN)
;; WHEN: Thu Mar 7 23:02:34 2013
;; MSG SIZE rcvd: 262
A レコードが帰ってきてしまいました。。。。 じゃあ、fuga.com、と。。。
;; Truncated, retrying in TCP mode.
 
; <<>> DiG 9.3.6-P1-RedHat-9.3.6-16.P1.el5_7.1 <<>> ANY @監視ServerDnsN fuga.com
; (1 server found)
;; global options: printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 10159
;; flags: qr rd ra; QUERY: 1, ANSWER: 13, AUTHORITY: 4, ADDITIONAL: 0
 
;; QUESTION SECTION:
;fuga.com.  IN ANY
 
;; ANSWER SECTION:
fuga.com.  14400 IN TXT "v=spf1 ip4:178.237.33.96/26 ip4:178.237.33.184/29 ip4:212.121.100.221 include:_spf.google.com include:spf-considered-harmful.xs4all.nl include:support.zendesk.com ~all"
fuga.com.  14400 IN TXT "google-site-verification=18RJdogudILUSxJZee3nZztO4eJDNQOk0P5MSWjtI30"
fuga.com.  14400 IN MX 20 ALT2.ASPMX.L.GOOGLE.com.
fuga.com.  14400 IN MX 30 ASPMX2.GOOGLEMAIL.com.
fuga.com.  14400 IN MX 30 ASPMX3.GOOGLEMAIL.com.
fuga.com.  14400 IN MX 10 ASPMX.L.GOOGLE.com.
fuga.com.  14400 IN MX 20 ALT1.ASPMX.L.GOOGLE.com.
fuga.com.  14400 IN SOA ns1.p08.dynect.net. hostmaster.fuga.com. 3 3600 600 604800 60
fuga.com.  14400 IN A 178.237.33.103
fuga.com.  86400 IN NS ns2.p08.dynect.net.
fuga.com.  86400 IN NS ns3.p08.dynect.net.
fuga.com.  86400 IN NS ns1.p08.dynect.net.
fuga.com.  86400 IN NS ns4.p08.dynect.net.
 
;; AUTHORITY SECTION:
fuga.com.  86400 IN NS ns2.p08.dynect.net.
fuga.com.  86400 IN NS ns3.p08.dynect.net.
fuga.com.  86400 IN NS ns1.p08.dynect.net.
fuga.com.  86400 IN NS ns4.p08.dynect.net.
 
;; Query time: 0 msec
;; SERVER: 監視ServerDnsN#53(監視ServerDnsN)
;; WHEN: Thu Mar 7 23:03:04 2013
;; MSG SIZE rcvd: 622
また A レコードがかえってきてしまいました。。。 もう、テキトウなのでいいです。teketou.com、と。。。
; <<>> DiG 9.3.6-P1-RedHat-9.3.6-16.P1.el5_7.1 <<>> ANY @監視ServerDnsN teketou.com
; (1 server found)
;; global options: printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 39118
;; flags: qr rd ra; QUERY: 1, ANSWER: 9, AUTHORITY: 4, ADDITIONAL: 0
 
;; QUESTION SECTION:
;teketou.com.  IN ANY
 
;; ANSWER SECTION:
teketou.com.  3600 IN MX 300 mx2.firstserver.ne.jp.
teketou.com.  3600 IN MX 100 mail.teketou.com.
teketou.com.  3600 IN MX 200 mx1.firstserver.ne.jp.
teketou.com.  3600 IN SOA ns1.firstserver.ne.jp. hostmaster.teketou.com. 2011090200 172800 3600 604800 3600
teketou.com.  3600 IN A 164.46.103.49
teketou.com.  3600 IN NS ns2.firstserver.ne.jp.
teketou.com.  3600 IN NS ns3.firstserver.ne.jp.
teketou.com.  3600 IN NS ns4.firstserver.ne.jp.
teketou.com.  3600 IN NS ns1.firstserver.ne.jp.
 
;; AUTHORITY SECTION:
teketou.com.  3600 IN NS ns4.firstserver.ne.jp.
teketou.com.  3600 IN NS ns2.firstserver.ne.jp.
teketou.com.  3600 IN NS ns1.firstserver.ne.jp.
teketou.com.  3600 IN NS ns3.firstserver.ne.jp.
 
;; Query time: 8 msec
;; SERVER: 監視ServerDnsN#53(監視ServerDnsN)
;; WHEN: Thu Mar 7 23:09:26 2013
;; MSG SIZE rcvd: 298

teketouまであるのですか・・・
もう、何指定しても出てくる気がします。
使ってないドメインを探すのは大変ですね。。。
(.comを使わなければ、もっと楽に使ってないドメインを探せるみたいでした)

EC2でaws-sdk-rubyを使う為のメモ

Java屋さんだったので、Rubyをみたことすらなかったのですが、ちょっとaws-sdk-rubyで試してみる必要があったのでEC2から作ろうとしました。

[http://aws.amazon.com/jp/sdkforruby/:title=AWS SDKのドキュメント]にしたがって、インストールです。

Ruby 用 AWS SDK には、Ruby1.8.7 以降が必要です。ゲム(Gem)をインストールするには、単に以下を入力します:
gem install aws-sdk

はい。動きません。
ってか、gemすらはいってないのですよ、EC2の初期状態は。
そんなわけでメモです。

Google先生に聞く

先人の知恵(http://kazuki-u.hatenablog.com/entry/2013/02/26/224832)をお借りして、必要そうなものをインストールします。
$ sudo yum -y update
$ sudo yum -y groupinstall "Development tools"
$ sudo yum -y install libxml2-devel libxslt-devel libffi-devel
$ sudo yum -y install git rubygems ruby-devel
$ sudo gem install bundler

これで準備は整いました。
ようやくSDKのインストールです。
$ sudo gem install aws-sdk
今度は成功するはずです。

実行時にエラー

とりあえず実行してみると。。。
$ ruby -r rubygems -r aws-sdk -e 'AWS::S3.new'
ruby: no such file to load -- aws-sdk (LoadError)
エラーとなってしまいます。

要するにaws-sdkがみつからないってことですが。。。Rubyは初心者に優しくありません。。。
JavaでいうCLASSPATHの設定がちゃんとできていないのだと思いますが、AWSのドキュメントはウソツキです。

$ ruby -e 'puts $:'
この実行結果にawsなんてでてこないのでやっぱり読みこめて無いだけなのでしょう。

そんなわけで、.bashrcに以下を追加します。(パスはls -Rで探しました)
RUBYLIB=/usr/lib/ruby/gems/1.8/gems/aws-sdk-1.8.3.1/lib/
export RUBYLIB

これでOK!