Tag Archives: Java

Java製の形態素解析器「Kuromoji」なるものがあるらしい

通勤中に、twitter上で突如目に入ってきた情報は、とてもワクワクしました。

Java製形態素解析器「Kuromoji」を試してみる
http://www.mwsoft.jp/programming/lucene/kuromoji.html

これを見る限り、使い方は非常にシンプル。

今までSenのバージョンアップをどれだけ心待ちにしてきたか分かりません。
ひとまず、これも評価して見ようかと思います。

[Java]Solr1.4.1をTomcat6へインストール(Windows版)

以前から興味があった全文検索エンジン「Solr」を触ってみる。
この記事ではWindowsへのインストールのみ解説している。

0.前提
Tomcatは、以下のディレクトリにインストールされているものとする。

C:\Program Files\Apache Software Foundation\Tomcat 6.0

1.ダウンロード
以下のURLからダウンロード先を選択し、apache-solr-1.4.1.zipをダウンロード
http://www.apache.org/dyn/closer.cgi/lucene/solr/
※URLによってはSolr1.4.1が無い場合もあるのでよく探す

2.zip解凍
ダウンロードしてきたapache-solr-1.4.1.zipをzip解凍する

3.アプリケーションをTomcatに設置
以下、指定のwarファイルを指定のTomcatディレクトリへ移動する。
・移動するファイル

apache-solr-1.4.1/example/webapps/solr.war

・移動先のTomcatディレクトリ

C:\Program Files\Apache Software Foundation\Tomcat 6.0\webapps

4.warファイルを解凍し設定ファイル設置
先ほど設置したsolr.warをzip解凍する。

以下2つのフォルダを解凍したフォルダ内に設置する。
移動するフォルダ

apache-solr-1.4.1\example\solr\bin
apache-solr-1.4.1\example\solr\conf

移動先のフォルダ

C:\Program Files\Apache Software Foundation\Tomcat 6.0\webapps\solr

5.Tomcatの設定ファイルを作成
Web画面上からSolrアプリケーションが見れるように、
Tomcatの設定ファイルを作成する。

・作成するファイル

C:\Program Files\Apache Software Foundation\Tomcat 6.0\conf\Catalina\localhost\solr.xml

・ファイルの内容

<Context docBase="solr" debug="0" crossContext="true">
	<Environment name="solr/home" type="java.lang.String"
		value="C:/Program Files/Apache Software Foundation/Tomcat 6.0/webapps/solr"
		override="true" />
</Context>

6.Tomcatを起動
Tomcatを起動し、以下のURLへ接続する。

http://localhost:8080/solr/admin

この間にエラーが出たらなんか間違えてるので、
一から読み直すかあきらめてください。

7.参考URL
http://ymotoba.blogspot.com/2008/10/solr.html
※まんま同じ作業を行ないました

[SAStruts]Webアプリケーション用に作成したプロジェクトでスタンドアローンプログラムが実行できない

EclipseのプラグインDoltengからWebアプリケーションとしてSAStrutsを作成し、
開発を進めていたが、mainで動作するスタンドアローンなプログラムを実行させる機会があった。
従来は、プロジェクトを分けているが小さいプログラムだったので、
Webアプリケーションと同一のプロジェクト内にプログラムを作成した。

そこで、スタンドアローンなプログラムを実行。。。エラー発生。
「SingletonS2ContainerFactory.init()」の時点でエラーが発生していた。

Exception in thread "main" org.seasar.framework.container.ComponentNotFoundRuntimeException: [ESSR0046]コンポーネント(interface javax.servlet.ServletContext)が見つかりません
	at org.seasar.framework.container.impl.S2ContainerBehavior$DefaultProvider.acquireFromGetComponentDef(S2ContainerBehavior.java:165)
	at org.seasar.framework.container.impl.S2ContainerBehavior$DefaultProvider.acquireFromGetComponent(S2ContainerBehavior.java:158)
	at org.seasar.framework.container.impl.S2ContainerBehavior.acquireFromGetComponent(S2ContainerBehavior.java:62)
	at org.seasar.framework.container.impl.S2ContainerImpl.getComponent(S2ContainerImpl.java:124)
	at org.seasar.framework.container.SingletonS2Container.getComponent(SingletonS2Container.java:43)
	at org.seasar.struts.util.ServletContextUtil.getServletContext(ServletContextUtil.java:42)
	at org.seasar.struts.util.S2ModuleConfigUtil.getModuleConfig(S2ModuleConfigUtil.java:38)
	at org.seasar.struts.customizer.ActionCustomizer.customize(ActionCustomizer.java:80)
	...
	(省略)

初期設定時に発生したエラーなので、
設定ファイルの内容を編集しなくてはならないことが早い段階で分かった。

上記で起きた問題を解決したので、忘れないために解説する。

以下、解説。

■概要
Webアプリケーション(SAStruts)でプロジェクトした時に、
そのプロジェクトからスタンドアローン(main)の実行を行なう場合、
src/resources以下の設定ファイルをいくつか編集する必要がある。

これを行なわないと、初期起動時にエラーが発生する。

■原因
「SingletonS2ContainerFactory.init()」を呼びだした際に、
スタンドアローンでは使用しないコンポーネント(?)を無駄に読み込む。
これは、プロジェクト作成時にWebアプリケーション用の設定になっているから。

いくつかWebアプリケーション用に定義された値を除去する必要がある。

■解決
編集すべきファイルは、「creator.dicon」。
ここには、初期起動時に呼びだすいくつかのコンポーネントが定義されている。

編集前のcreator.dicon

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN"
	"http://www.seasar.org/dtd/components24.dtd">
<components>
	<include path="convention.dicon"/>
	<include path="customizer.dicon"/>
	<component class="org.seasar.framework.container.creator.ActionCreator"/>
	<component class="org.seasar.struts.creator.FormCreator"/>
	<component class="org.seasar.framework.container.creator.ServiceCreator"/>
	<component class="org.seasar.framework.container.creator.DtoCreator"/>
	<component class="org.seasar.framework.container.creator.InterceptorCreator"/>
	<component class="org.seasar.framework.container.creator.DaoCreator"/>
</components>

編集後のcreator.dicon

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN"
	"http://www.seasar.org/dtd/components24.dtd">
<components>
	<include path="convention.dicon"/>
	<include path="customizer.dicon"/>
	<!-- データベース接続機能のService系のみ残す -->
	<component class="org.seasar.framework.container.creator.ServiceCreator"/>
</components>

これで実行すれば、正常に動作する。
もっと詳細な原因を知りたければ他で調べてください。

■参考URL
http://ml.seasar.org/archives/seasar-user/2009-April/017325.html

プログラム言語awk、ファイル入出力処理にちょうどいい

ファイルの入出力処理は、日常業務で嫌というほど書いているが、
そのうちのほとんどが簡易的な調査目的として使用する。

また、そもそも私はJava言語をメインとしているため、
どんな時でもJavaでプログラミングすることが当然と思っていた。

それがあるきっかけでプログラム言語「awk(gawk)」を触ることになった。

Javaで書くよりも明らかに効率が上がったので、ここでawkについて紹介する。

■実装内容
・指定したファイルを1行ずつ読み込む。
・3000行に一度の割合で出力

■Javaの場合(class構文など省略)

BufferedReader br =
                new Bufferedreader(new InputSteamReader(
                        new FileInputStream(new File("input.tsv")), "UTF-8"));

BufferedWriter bw =
                new BufferedWriter(new OutputStreamWriter(
                        new FileOutputStream(new File("output.tsv")), "UTF-8"));

final int writeCount = 3000;
int lineCount = 0;

String line;
while((line = br.readLine()) != null) {
     lineCount++;

     if(lineCount == writeCount) {
          bw.write();

          lineCount = 0;
     }
}

br.close();

bw.flush();
bw.close();

■awkの場合

#!/usr/local/bin/gawk
# line_print.awk:
BEGIN {
     writeCount = 3000;
     lineCount = 0;
}

{
     lineCount++;

     if (lineCount == writeCount) {
          print $0;

          lineCount = 0;
     }
}

END {

}

awkは、コンパイルする必要がないので、プログラム実行までの手順も断然早い。
line_print.awkという名前のファイルを作成して、
上記のプログラムを記述。
実行方法は、以下。

# gawk -f line_print.awk input.tsv > output.tsv

また1行ずつカンマ区切り、タブ区切りなどで処理したい場合、
実行オプションに「何で区切るか」を指定すれば、簡単に操作できる。

動作確認していないので、間違ってたらゴメンね。

[Lucene]QueryParserによるOR検索とAND検索の切り替え

オープンソース検索エンジンLuceneで検索システムを開発していた時に
手間取った点があったので、ここに記す。

GoogleやYahoo、MSNなど大抵の検索エンジンでは、
空白区切りにキーワードを記述するとAND検索処理(絞り込み検索)が行われる。

しかし、LuceneはデフォルトでOR検索処理(または、あるいは検索)が行われる。
これだと、AND検索を行なうことができない。

OR検索からAND検索に切り替える方法があった。

独自QueryParserの作成 | 関口宏司のLuceneブログ

ここで書かれている問題は・・・QueryParserのsetDefaultOperator()で
ANDを指定しているとき、"A AND B OR C"という検索質問をQuery...

QueryParserのsetDefaultOperator()にANDを設定してやれば解決。

あやうくAND検索用の処理を書くところだった。

Apache POIで複雑なExcelを出力すると破損する

結局、原因不明で調査、作業を終えたのだが、

Apache POIで複雑なExcelを出力すると破損する

という現象が起きた。

複雑なことといっても、デザインをそれなりにいじったことと
1ファイルに4枚のシートを作成したこと。

以下のURLでも同じような現象が起きている。
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=44883&forum=12
http://d.hatena.ne.jp/kusakari/20071214/1197603134

私の場合、
1シート目から順に値をセットして、計4シートセットした後、
Excelファイルを出力する処理を記述しているのだが、
先に4シート目に値をセットしてから1,2,3シートの順に値をセットすると、
エラー(破損)が発生しなくなった。

たぶんPOIのバグだろう。

ちなみに最新BETA版「poi-bin-3.5-beta6-20090622」だと、
こんな面倒なことは起きないで正常に処理される。
バグを直したってことなのか?

Apache PoiでExcelシートの印刷の向きを横に変更する

ここで初めて知ったのだが、Poiではシートごとに印刷時の設定を編集することができるようだ。

HSSFWorkbook workbook = new HSSFWorkbook();

HSSFSheet sheet = workbook.createSheet(Excel.COVER);

HSSFPrintSetup setup = sheet.getPrintSetup();

// 印刷の向きを横か縦に変更
setup.setLandscape(true);

HSSFPrintSetupには、その他印刷系機能が備わっている。
詳しくは以下参考サイトで。

■参考URL
http://blog.goo.ne.jp/fkcalc/e/8b11a8af75898f7c620ac9dda687706a
http://poi.apache.org/apidocs/org/apache/poi/hssf/usermodel/HSSFPrintSetup.html

[SAStruts]Tomcat起動時に初回のみ呼び出す独自のクラスでデータベース接続

SAStruts(Super Agile Struts)の開発、設定方法に苦戦した。



やりたいことは以下。

1.WebサーバTomcat起動時に独自に作成したクラスを呼び出したい。

2.呼び出したクラス内でデータベースにSELECTを発行し、取得したレコードをメモリに読み込みたい。



1点目の解決法は、customizer.diconにinitializeServiceを設定すれば解決できる。

(customizer.diconへの設定例)
<components>
...(中略)
    <component name="initializeService" class="jp.mikuriya.Init">
        <initMethod name="init">
            <arg>"/home/hoge/sample/property/sys.properties"</arg>
        </initMethod>
    </component>
<components>


(クラスの記述例)
package jp.mikuriya;

import org.seasar.extension.jdbc.JdbcManager;

public class Init {
    public JdbcManager jdbcManager;

    public void init(String propertyFile) {
        /* -------------------- */
        /* 適当な処理内容を記述 */
        /* -------------------- */
        System.out.println("Tomcat起動時に呼ばれたよ。[propertyFile=" + propertyFile + "]");
    }
}

Tomcatを起動すればこれでSystem.outは実行される。


しかし、上記の「クラスの記述例」で記述している「JdbcManager jdbcManager」に注目してもらいたい。

フィールドに設定しておくと、勝手にデータベースに接続してくれる

SAStrutsの特徴であるJdbcManagerが記述されている。

これがどうにも上手くいかない。

うまくいかないとはデータベースに接続できないってこと。



Tomcatのログ(catalina.out)を確認すると、以下のようなメッセージが出力されている。

「...プロパティ(jdbcManager)が見つからないので設定をスキップします」

Tomcatのログをもっと確認してみると、customizer.diconを呼び出しているようなログが

s2jdbc.diconを呼び出しているようなログよりも前の行に表示されている。

ってことは、s2jdbc.diconを呼び出してから、例題のプログラムを起動させればよいと考えた。



そこで先ほどcustomizer.diconに設定していた内容を切り取って、

s2jdbc.diconに追加する。

(s2jdbc.diconへの設定例)
<components>
...(中略)
    <component name="initializeService" class="jp.mikuriya.Init">
        <initMethod name="init">
            <arg>"/home/hoge/sample/property/sys.properties"</arg>
        </initMethod>
    </component>
</components>



これで再度Tomcatのログを確認してみると、s2jdbc.diconを呼び出した後に

System.outが出力されているのがわかる。



他にやり方がありそうなのだが、わかんねぇ。

「書くのが面倒臭せぇ」symfonyの参考サイト紹介

PHPとか結構ナメてるけど、

Javaを個人の金銭で動かせるレンタルサーバがないので

PHPも勉強しなきゃいけないかな、と思った。



そんで今回symfonyっていうフレームワークを勉強することにした。

やっててわかったけど、最近のフレームワークは「Ruby on Rails」に近いのね。

コマンドベースで楽に開発できる。



PHPのインストールもそうだけど、解説文を書くのが面倒になってきたので

最適な参考サイトを紹介する。



■symfony入門(1):symfonyで始めるPHPフレームワーク

http://codezine.jp/article/detail/704?p=1

Javaオープンソース「Nutch」はクロール→インデクシング→検索までいける

Nutchというクローラ、インデクサ、検索を行なうオープンソースがあったので、

軽く触ってみた。

Nutch内部ではLucene、Hadoopが動作してるようなので、勉強にはちょうどいいかと思う。

早速、インストールから動作までの解説をする。



■クローラ

1.Nutch本体ダウンロード、解凍

# tar -xvzf nutch-0.9.tar.gz
# mv nutch-0.9 /usr/local/nutch



2.環境変数にパスを通す

# vi /etc/bashrc

export NUTCH_HOME=/usr/local/nutch
export PATH=${NUTCH_HOME}/bin:${PATH}

# source /etc/bashrc



3.クロール先を決める

クロール先URLリストを作成する。

今回は2サイトをクロールする予定。

# cd ${NUTCH_HOME}
# mkdir crawl_urls
# vi crawl_urls/corporate_sites

http://www.datasection.co.jp/

# vi crawl_urls/blogs

http://blog.mikuriya.biz/



要は作成したディレクトリcrawl_urls以下に1行1URLで

クロールしたいサイトの開始位置をどんどん記述するってことみたい。



4.クロールのフィルタ設定

今回のクロール対象は2サイトなので、それ以外はクロールしたくない。

以下のファイルに正規表現でフィルタリングを行なう。(正規表現はJava仕様)

# cd ${NUTCH_HOME}
# vi conf/crawl-urlfilter.txt

(修正前)
+^http://([a-z0-9]*\.)*MY.DOMAIN.NAME/
(修正後)
+^http://www\.datasection\.co\.jp/
+^http://blog\.mikuriya\.biz/

※よく見ると先頭に「+」とか「-」が入ってる。

クロールしたいURLパターンは「+」、クロールしたくないURLパターンは「-」を

このファイルに追加していくようだ。



5.クロール設定

クロール用の設定ファイルは初期段階では何も書かれていないので、

nutch-default.xmlをそのままコピーしてくる。

# cat conf/nutch-default.xml > nutch-site.xml

nutch-site.xmlの「http.agent.name」は必須っぽい。適当な名前をつけて。

私の場合は、クロールしたデータを「/usr/local/nutch/crawl_data」に

格納したいので以下を編集した。

# vi conf/nutch-site.xml
<property>
  <name>searcher.dir</name>
  <value>/usr/local/nutch/crawl_data</value> ← ここを編集した
  <description>
    ...
  </description>
</property>

nutch-site.xmlには、propertyのdescription属性に

設定の説明が書いてあるので、各自適当に読んで設定してもらいたい。



6.クロール開始

# /usr/local/nutch/bin/nutch crawl /usr/local/nutch/crawl_urls -dir /usr/local/nutch/crawl_data -depth 3 -topN 50 &

※なおcrawl_dataは勝手に作成されるので、いちいち作らなくてよい。



■WEBアプリケーション

Tomcatからクロールしたデータを検索表示することができるので、その設定を行なう。

${NUTCH_HOME}/nutch-0.9.warがその実体。

# cd ${NUTCH_HOME}
# mkdir nutch_web
# cp nutch-0.9.war nutch_web/
# cd nutch_web
# unzip nutch-0.9.war



解凍したアプリケーションの設定ファイルには、何も書かれていないので

クロール用で使用した設定ファイルを上書きしてやる。

# cp conf/nutch-site.xml nutch_web/WEB-INF/classes/nutch-site.xml



Tomcatで見れるようにシンボリックリンクを貼る。

# cd /usr/local/tomcat/webapps
# ln -s /usr/local/nutch/nutch_web nutch



Tomcat起動

# /usr/local/tomcat/bin/startup.sh



■検索結果のウェブ画面







形態素解析器Senの導入(日本語対応)、Hadoopによる分散(複数のサーバで運用)、

その他パフォーマンスなどは、もったいないから教えない。



■参考URL:

http://dev.team-lab.com/index.php?itemid=120

http://kazuhiro.ty.land.to/blog/2007/01/nutch.html