JAVAで文字コード変換

文字列から文字列で変換するのはよくある話

String sjis_str = "SJISの文字列";
byte[] sjis_bytes = sjis_str.getBytes( "Windows-31J" );
String utf8_str = new String( sjis_bytes, "UTF-8" );

って。


でも、できないーと思っていたら、
sjis_strにUTF-8が入っていたんだ。


まぁ何でこんなことになったかって言うと、
問題はInputStreamReaderだった。


WEBページをゲットする際に、
InputStream

InputStreamReader

BufferedReeader

BufferedReeader#readLine()
で値をとることが多い。


InputStreamReaderのコンストラクタには、
文字コードを指定する奴があって、
その時点でWindows-31Jを指定してやって、
それをUTF-8に変換しなきゃいけないってね。


また一つ勉強になった。

S2Chronosでいろいろやる

ちょっといろいろ作ってみているが、
なんか不可思議な現象が。


SscheduleにaddTaskとremoveTaskがあるけど、
実際に中のほうで持っているのは、

Sschedule#TaskScheduleEntryManager#taskScheduleEntryClassMap

こいつかタスクを管理している(?)。


んで、こいつの型が、

ConcurrentHashMap<Class<?>, TaskScheduleEntry>


ConcurrentHashMapってチョー厳密なハッシュマップ(w)だから、
型であっても、インスタンスが違ったら不一致になる。


型変数とか見よう見まねでしか勉強をしたことがない、
実際にJVM的にどうなるのかよくわかってないのだが、
あるときに生成したClass型のインスタンス(?)

別のときに生成したClass型のインスタンス(?)
って、
別のインスタンスになるから、
ConcurrentHashMapじゃとってこれない気がするんだけど、
なので、
Schedule#addTaskしたものが、
Schedule#removeTaskでからぶる。

  • 検証

検証シチュエーション:
既にスケジュールが動いている状態
検証コード:

TaskScheduleEntryManager value = TaskScheduleEntryManager.getInstance();

Field f2 = ReflectionUtil.getDeclaredField( value.getClass(), "taskScheduleEntryClassMap" );
f2.setAccessible( true );
ConcurrentHashMap<Class<?>, TaskScheduleEntry> taskScheduleEntryClassMap = (ConcurrentHashMap<Class<?>, TaskScheduleEntry>)ReflectionUtil.getValue( f2, value );

Method m = ReflectionUtil.getDeclaredMethod( ConcurrentHashMap.class, "hash", int.class );
m.setAccessible( true );

for ( Map.Entry<Class<?>, TaskScheduleEntry> ent : taskScheduleEntryClassMap.entrySet() ) {
	Object key = ent.getKey();
	int hash = (Integer)ReflectionUtil.invokeStatic( m, key.hashCode() );
	logger.debug( key+"="+hash );
}
int hash = (Integer)ReflectionUtil.invokeStatic( m, clazz.hashCode() );
logger.debug( clazz+"="+hash );

結果:

DEBUG 2010-11-24 16:11:29,715 [http-80-1] class rootpackage.task.OneMinuteTask=1103040895
DEBUG 2010-11-24 16:11:29,715 [http-80-1] class rootpackage.task.Class20101124154520Task=138201009
DEBUG 2010-11-24 16:11:29,715 [http-80-1] class rootpackage.task.Class20101124154520Task=1567105810


同じ型なのに、ConcurrentHashMapのgetするキー?が違うんだよね。
うーん?俺のアプローチの仕方が違うのかな。
addTaskもremoveTaskも引数がClassだから、
これでいいと思うんだけど…。




と思ったんだけど、
Tomcatを落としあげてもう一回やってみると合う…、?????




というか、
ConcurrentHashMapのキーが同じになって、
removeTaskが正常に動作することもある。


ConcurrentHashMapのキーが違う値になって、
removeTaskが正常に動作しない場合もある。


えーwなにこれーw



なんかわかった気がするが、
今はまとめる気にならないので、
いつかまとめる。


ConcurrentHashMap的にhashが違うのは、
本当にClassのインスタンスが違ったのだ。
そりゃー違うわねw
型は同じなのにインスタンスが違うという、
クラスローダー的な話だが、その辺はあまり考えたくないw


結論的には多分S2ChronosもConccurentHashMapも悪くない。
俺のアイディア?かロジック?がぶっ飛んでいたようだw

pomを見直し編

いったい、いつになったらS2Chronosを動かすにたどり着けるのだか…w


前回 id:akubito:20101123:1290516426 dependencyからいろいろ消して、
見直していなかったので、見直し。
消しても、他のものの依存性で追加される場合があるので。


消したもの


cglib
easymock
easymockclassextension
svnkit
antlr
aopalliance
commons-beanutils
commons-digester
commons-el
commons-fileupload
commons-logging
h2
oro
javassist
jstl
poi


この中から、
mvnを流した後に、再びclasspathに追加になっているものは、


easymock
svnkit
antlr
aopalliance
commons-beanutils
commons-digester
commons-fileupload
commons-logging
oro
javassist
poi


うーん、考えるのがめんどくなくなったので、
復元されたものはいったん戻しておこう。


最終的に、
geronimo-servlet
geronimo-jsp
servlet-api
がWEB-INF/libに入っていなきゃいいや。



2010/11/24 13:53追加
c:forEachつかったら、jstlでExceptionが。

javax.servlet.ServletException: java.lang.NoClassDefFoundError: javax/servlet/jsp/jstl/core/LoopTag

jstlも戻しておこうw

sa-strutsとしてプロジェクトを作成編

sa-strutsのプロジェクトを作る事のおさらいも含めてやってみる。


Doltengでプロジェクトを作成。
って、Dolteng入ってないやw
3.5にしたと気にいれてなかった。


http://eclipse.seasar.org/updates/3.3/


ここを新規ソフトウェアのインストールについかして、
Doltengをインストール。
2010/11/23時点の多分最新をインスコ

  • Root Package Name:自分のつけたいパッケージ体制
  • Application Type:Web Application
  • Presentation:SAStruts
  • Persistence:S2JDBC
  • Server Management:Sysdeo Tomcat Plugin


これでプロジェクトを作成。

pom.xmlができあがるので、自動で入るdependencyを全部見てみよう。

  • cglib、easymock、easymockclassextension

 まったくわからねぇwのでいったん削除

 S2JDBC-GENでant走らせるときに必要なのでそのまま
 scopeがtestなのは気になるけど。
 前はmavenサイトに無かった気がするけど、なので自分でコピーしていたなぁ。

 詳しく分かってないけど、tomcatのモックなので必要らしい。
 ただ、warを作成するときには必要ないので、scopeはprovidedに(デフォでされているけど)

 まぁJUnitテストをするだろうから入れておくのがいいだろう

 エンティティ作るから入れておく

  • svnkit、antlr、aopalliance、commons-beanutils

 まったくわからねぇwのでいったん削除 

  • commons-collections

 CollectionUtils.isEmptyとCollectionUtils.isNotEmptyを使用したいので、3.2.1に。いまローカルリポジトリにあったやつがそうだったので。

  • commons-digester、commons-el、commons-fileupload

 まったくわからねぇwのでいったん削除 

  • commons-io

 IOUtilsを使うので、そのまま

  • commons-logging

 いるのかな、ログとかはlog4jを使用するから、いったん削除

  • commons-validator

 まったくわからねぇwのでいったん削除 

 うーん、geronimoはまぁそのままでいいやw

  • h2はいらないので削除

 人それぞれあわせればいい
 うちはPostgreSQL

  • oro

 他のはまぁアドリブで判断できたけど、これにいたっては何も判断できないw まぁ削除

  • standard

 これはtaglib用なのでそのまま

 これはなんだったかなぁ、忘れてしまったが、いったん削除

 まったくわからねぇwのでいったん削除

 そのまま使用

  • ognl

 diconで使用するのでそのまま

  • poi

 ExcelとかPDFとかのAPIだったような気がする、今回は使わないので削除

  • s2-extension、s2-framework、s2-tiger

 まぁこの辺はね

 バージョンがまぁまぁ変わるので注意

 まぁsa-strutsのベースだしそのまま


PostgreSQLを使用するので、

 追加(独自のmavenサイトにおいておく)


これでいったんmavenを起動。

mvn -e package 

mvnのログでなんかjarが書き換わったとかjarをコピーしたというログが出ない。
当たり前だった、何も指定していないしなw(自作自演かw)

mvn -e package dependency:copy-dependencies eclipse:eclipse

と同時に、下記を追加

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-dependency-plugin</artifactId>
	<version>2.0</version>
	<executions>
		<execution>
			<goals>
				<goal>copy-dependencies</goal>
			</goals>
			<configuration>
				<outputDirectory>src/main/webapp/WEB-INF/lib</outputDirectory>
				<excludeScope>provided</excludeScope>
				<overWriteIfNewer>true</overWriteIfNewer>
				<overWriteReleases>true</overWriteReleases>
				<overWriteSnapshots>true</overWriteSnapshots>
			</configuration>
		</execution>
	</executions>
</plugin>

と同時に、projectのnatureのdefaultにtomcatを指定するので、

<plugin>
	<artifactId>maven-eclipse-plugin</artifactId>
	<configuration>
		<additionalProjectnatures>
			<projectnature>com.sysdeo.eclipse.tomcat.tomcatnature</projectnature>
		</additionalProjectnatures>
	</configuration>
</plugin>

projectnatureの値は、.projectのnatureの値


うーん、eclipseの設定が反映されているのか分からないな。
いったん、
eclipse:clean と eclipse:eclipse の両方を指定してみよう。


昔、eclipse:cleanしてmvnを流すと、tomcatプロジェクトが外れちゃったのだけれども、
natureの設定をしているからか、消えないな。
たぶんこれでいいのだろう…。


ただ、これだとWEB-INF/libが最新化されない。


何かいいpluginがあるのだろうが、
以前からmavenから呼ぶantでごりごりやっていたので、
今回もそれで。

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-antrun-plugin</artifactId>
	<version>1.1</version>
	<executions>
		<execution>
			<id>delete-WEB-INF-and-target-lib</id>
			<phase>clean</phase>
			<configuration>
				<tasks>
					<echo message="./src/main/webapp/WEB-INF/libを削除します"/>
					<delete dir="./src/main//webapp/WEB-INF/lib" />
					<echo message="./target/libを削除します"/>
					<delete dir="./target/lib" />
				</tasks>
			</configuration>
			<goals>
				<goal>run</goal>
			</goals>
		</execution>
	</executions>
</plugin>

これを追加して、mvnを流す。
antrun:runをcleanのフェーズでながすので、cleanとpackageを指定。

mvn -e clean package eclipse:clean eclipse:eclipse antrun:run dependency:copy-dependencies 

今回はなんとなく、pluginを指定を順番ぽくした


うん、WEB-INF/libにちゃんとコピーされたっぽい。
ごみファイルをおいておいたが、それもなくなってるし。

tomcatを起動してみよう。
tomcatのコンテキスト更新を忘れないようにw


dicon周辺が全然だめだったwwww

  • app.dicon

 そのまま

  • convention.dicon

 Doltengで生成しているので、rootpackgeは正しいものを指定してされている

 Dto、Interceptor、Daoは必要ないので、削除
 以前はFormCreatorは無かったけど、今はデフォで指定されているのねぇ。

 PostgreSQLを使用するので、H2はコメントアウトして、PostgreSQL用のDataSourceに
 ただ、疑問があるのだが、下のほうでdataSourceを指定しているけど、nameがDataSourceになっているけど、nameってインスタンスの名前だから、dataSourceじゃないのかな?

  • s2ontainer.dicon

 そのまま

 dialectをPostgreSQL用に修正


tomcatを起動
起動した!
Doltengが生成したActionとJSPが表示された!


余談:
JSPがWEB-INF/viewの下におかれている。

<context-param>
    <param-name>sastruts.VIEW_PREFIX</param-name>
    <param-value>/WEB-INF/view</param-value>
</context-param>

context-paramをコメントアウトして起動すると、
index.jspが無いと怒られるので、それなんだろう。
それに合うようにファイルを移動させると、

400 - Direct access for JSP is not permitted. Remove "index.jsp" from welcome-file-list of (default) "web.xml".

これになる。
rootpakageのIndexActionのJSPをindex.jspにするのはかなりやりがち。
でも、そうするとwebappの直下にindex.jspをおかなきゃいけないので、
そうするとweb.xmlのwelcome-file-listにindex.jspを追加せにゃいけなく、
それがイヤだから、指定しているのだろう。


まぁ自動でこう生成されたので、これでいいかな。


ちなみにSAStrutsプラグインはこの辺も見ているので、
viewはweb.xmlにさえ書いてあれば大丈夫っぽい。


2010/11/25 14:47追記
上のmvnコマンドだとソースがくっついてこないので、

mvn -e clean package eclipse:clean eclipse:eclipse antrun:run dependency:copy-dependencies -DdownloadSources=true

がいいかな。

S2Chronosを動かす サンプル編

ちょっと時間で起動するようにした面白いものができるかなと思って使ってみようかなと思った。


s2chronos


サンプルを落とす。
俺はsa-strutsをがっつりなので、
ダウンロードから、

s2chronos-sastruts-example-1.0.0.zip
SAStrutsを使ったS2Chronosのサンプル(dbsessionのセッションタイマー実装)

を保存。


Eclipseアーカイブを読み込ませる。
pom.xmlはあるので、
mvnを起動。

mvn -e install dependency:copy-dependencies

いったんはWEB-INF/libにjarがあればいいので、
dependency:copy-dependenciesを指定

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-dependency-plugin</artifactId>
	<version>2.0</version>
	<executions>
		<execution>
			<goals>
				<goal>copy-dependencies</goal>
			</goals>
			<configuration>
				<outputDirectory>src/main/webapp/WEB-INF/lib</outputDirectory>
				<excludeScope>provided</excludeScope>
				<overWriteIfNewer>true</overWriteIfNewer>
				<overWriteReleases>true</overWriteReleases>
				<overWriteSnapshots>true</overWriteSnapshots>
			</configuration>
		</execution>
	</executions>
</plugin>

オプションはこの辺だけでいいかな。
installとかpackageとかはよく分からんけど、
これで必要なところにコピーされたので良しとする。


次の問題は、クラスパスにjarがないと。

プロジェクト 's2chronos-sastruts-example' に、必要なライブラリー 'D:\repo\org\seasar\chronos\s2chronos-core\0.0.1-RC7-SNAPSHOT\s2chronos-core-0.0.1-RC7-SNAPSHOT.jar' がありません
プロジェクト 's2chronos-sastruts-example' に、必要なライブラリー 'D:\repo\org\seasar\chronos\s2chronos-extension\0.0.1-RC7-SNAPSHOT\s2chronos-extension-0.0.1-RC7-SNAPSHOT.jar' がありません

ですって。


あー、クラスパスがmavenによって書き換わっていないのか。

mvn -e install dependency:copy-dependencies eclipse:eclipse

mavenを起動しなおし。
おっけーおっけー。


JSPコンパイルエラーが出る(Amateras)けど、むしむし。
いったんはWEBから見ないし。


次は、tomcatの設定を
プロパティからコンテキスト名を設定。
Webアプリケーション・ルートとするサブディレクトリーを

/src/main/webapp/

に。


tomcatを起動。

org.seasar.framework.beans.PropertyNotFoundRuntimeException: [ESSR0065]クラス(org.seasar.chronos.core.SchedulerConfiguration)のプロパティ(hotdeployDisabled)が見つかりません
	at org.seasar.framework.beans.impl.BeanDescImpl.getPropertyDesc(BeanDescImpl.java:132)
	at org.seasar.framework.container.assembler.AccessTypePropertyDef.bind(AccessTypePropertyDef.java:48)
	at org.seasar.framework.container.assembler.AccessTypePropertyDef.bind(AccessTypePropertyDef.java:41)
	at org.seasar.framework.container.assembler.AutoPropertyAssembler.assemble(AutoPropertyAssembler.java:56)
	at org.seasar.framework.container.deployer.SingletonComponentDeployer.assemble(SingletonComponentDeployer.java:68)
	at org.seasar.framework.container.deployer.SingletonComponentDeployer.deploy(SingletonComponentDeployer.java:48)
	at org.seasar.framework.container.deployer.SingletonComponentDeployer.init(SingletonComponentDeployer.java:76)
	at org.seasar.framework.container.impl.ComponentDefImpl.init(ComponentDefImpl.java:236)
	at org.seasar.framework.container.impl.S2ContainerImpl.init(S2ContainerImpl.java:563)
	at org.seasar.framework.container.impl.S2ContainerImpl.init(S2ContainerImpl.java:560)
	at org.seasar.framework.container.impl.S2ContainerImpl.init(S2ContainerImpl.java:560)
	at org.seasar.framework.container.impl.S2ContainerImpl.init(S2ContainerImpl.java:560)
	at org.seasar.framework.container.impl.S2ContainerImpl.init(S2ContainerImpl.java:560)
	at org.seasar.framework.container.factory.SingletonS2ContainerFactory.init(SingletonS2ContainerFactory.java:150)
	at org.seasar.framework.container.servlet.SingletonS2ContainerInitializer.initialize(SingletonS2ContainerInitializer.java:55)
	at org.seasar.framework.container.servlet.S2ContainerServlet.initializeContainer(S2ContainerServlet.java:139)
	at org.seasar.framework.container.servlet.S2ContainerServlet.init(S2ContainerServlet.java:127)
	at javax.servlet.GenericServlet.init(GenericServlet.java:212)
	at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1172)
	at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:992)
	at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4058)
	at org.apache.catalina.core.StandardContext.start(StandardContext.java:4371)
	at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:791)
	at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:771)
	at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:525)
	at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:627)
	at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.java:553)
	at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:488)
	at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1149)
	at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:311)
	at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
	at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053)
	at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)
	at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
	at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
	at org.apache.catalina.core.StandardService.start(StandardService.java:516)
	at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
	at org.apache.catalina.startup.Catalina.start(Catalina.java:578)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
	at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)

これがでて起動できない。
正直、これは本当にふざけた理由。
公式からサンプルダウンロードしたのに、
プロパティ名間違ってるって何なの?w


org.seasar.chronos.core.SchedulerConfiguration
を見ると、

private boolean hotdeployDisable;

「d」ねーじゃんwww


chronosCustomize.dicon
の記述を修正。

<property name="hotdeployDisabled">true</property>

<property name="hotdeployDisable">true</property>

に。


起動しました。

DEBUG 2010-11-23 18:34:30,375 [chronos-pool-1-daemonthread-1] cronExpression = 0 */1 * * * ?
DEBUG 2010-11-23 18:34:30,375 [chronos-pool-1-daemonthread-1] cronExpression = 0 */5 * * * ?
DEBUG 2010-11-23 18:34:30,375 [chronos-pool-1-daemonthread-1] cronExpression = 0 */1 * * * ?
DEBUG 2010-11-23 18:34:30,375 [chronos-pool-1-daemonthread-1] cronExpression = 0 */1 * * * ?

このログが出ているのと、
デバッグウィンドウに、
chronos-pool-*thread
とか
chronos-pool-1-daemonthread-*
とか
のプロセスが動いているので、
これでタスクが動くのは間違いないでしょう。


いったんサンプルを動かしてみたらこんな感じ。

S2Chronosを動かす ようやくS2Chronosのモジュールを組み込む編

ようやくようやくS2Chronosのモジュールを組み込むまで到達


公式サイトのように設定ファイルを組み込む
公式の手順の通りやる。

  • S2Choronosのjarファイルをビルドパスに加える.
<dependency>
	<groupId>org.seasar.chronos</groupId>
	<artifactId>s2chronos-extension</artifactId>
	<version>1.0.0</version>
</dependency>

これで何とかなるだろう。

  • chronosCustomize.diconを適宜編集しビルドパスに加える.

 公式の表示してあるものをそのままコピペ

  • creator.diconに以下を追加する.

 公式の表示してあるものをそのままコピペ

  • customizer.diconに以下を追加する.

 公式の表示してあるものをそのままコピペ


インストールガイドはこれしかないので、
これだけやってtomcatを起動。

DEBUG 2010-11-23 23:12:53,515 [main] S2Containerを作成します。path=hotdeploy.dicon
DEBUG 2010-11-23 23:12:53,515 [main] S2Containerを作成します。path=convention.dicon
DEBUG 2010-11-23 23:12:53,781 [main] S2Containerを作成しました。path=convention.dicon
DEBUG 2010-11-23 23:12:53,781 [main] S2Containerを作成します。path=customizer.dicon
DEBUG 2010-11-23 23:12:53,781 [main] S2Containerを作成します。path=default-customizer.dicon
DEBUG 2010-11-23 23:12:53,781 [main] S2Containerを作成します。path=std-customizer.dicon
DEBUG 2010-11-23 23:12:53,796 [main] S2Containerを作成します。path=std-customizer-tiger.dicon
DEBUG 2010-11-23 23:12:53,859 [main] S2Containerを作成しました。path=std-customizer-tiger.dicon
DEBUG 2010-11-23 23:12:53,875 [main] S2Containerを作成しました。path=std-customizer.dicon
DEBUG 2010-11-23 23:12:53,875 [main] S2Containerを作成しました。path=default-customizer.dicon
DEBUG 2010-11-23 23:12:53,906 [main] S2Containerを作成しました。path=customizer.dicon
DEBUG 2010-11-23 23:12:53,906 [main] S2Containerを作成します。path=creator.dicon
DEBUG 2010-11-23 23:12:53,937 [main] S2Containerを作成しました。path=creator.dicon
DEBUG 2010-11-23 23:12:53,937 [main] S2Containerを作成しました。path=hotdeploy.dicon
DEBUG 2010-11-23 23:12:54,031 [main] S2Containerを作成します。path=app.dicon
DEBUG 2010-11-23 23:12:54,031 [main] S2Containerを作成します。path=convention.dicon
DEBUG 2010-11-23 23:12:54,046 [main] S2Containerを作成しました。path=convention.dicon
DEBUG 2010-11-23 23:12:54,046 [main] S2Containerを作成します。path=aop.dicon
DEBUG 2010-11-23 23:12:54,109 [main] S2Containerを作成しました。path=aop.dicon
DEBUG 2010-11-23 23:12:54,109 [main] S2Containerを作成します。path=j2ee.dicon
DEBUG 2010-11-23 23:12:54,109 [main] S2Containerを作成します。path=jta.dicon
DEBUG 2010-11-23 23:12:54,156 [main] S2Containerを作成しました。path=jta.dicon
DEBUG 2010-11-23 23:12:54,156 [main] S2Containerを作成します。path=jdbc.dicon
DEBUG 2010-11-23 23:12:54,203 [main] S2Containerを作成しました。path=jdbc.dicon
DEBUG 2010-11-23 23:12:54,218 [main] S2Containerを作成しました。path=j2ee.dicon
DEBUG 2010-11-23 23:12:54,218 [main] S2Containerを作成します。path=s2jdbc.dicon
DEBUG 2010-11-23 23:12:54,218 [main] S2Containerを作成します。path=s2jdbc-internal.dicon
DEBUG 2010-11-23 23:12:54,234 [main] S2Containerを作成しました。path=s2jdbc-internal.dicon
DEBUG 2010-11-23 23:12:54,343 [main] S2Containerを作成しました。path=s2jdbc.dicon
DEBUG 2010-11-23 23:12:54,343 [main] S2Containerを作成しました。path=app.dicon

chronosCustomize.dicon を読み込むログは出ない。
まぁそうか。
サンプルの用に、
app.dicon
に、

これがあるので、これを追加。

DEBUG 2010-11-23 23:15:18,015 [main] S2Containerを作成します。path=chronos-extension.dicon
DEBUG 2010-11-23 23:15:18,015 [main] S2Containerを作成します。path=chronos-core.dicon
DEBUG 2010-11-23 23:15:18,015 [main] S2Containerを作成します。path=chronos-base.dicon
DEBUG 2010-11-23 23:15:18,031 [main] S2Containerを作成します。path=chronosCustomize.dicon
DEBUG 2010-11-23 23:15:18,046 [main] S2Containerを作成しました。path=chronosCustomize.dicon
DEBUG 2010-11-23 23:15:18,234 [main] S2Containerを作成しました。path=chronos-base.dicon
DEBUG 2010-11-23 23:15:18,343 [main] S2Containerを作成しました。path=chronos-core.dicon
DEBUG 2010-11-23 23:15:18,343 [main] S2Containerを作成しました。path=chronos-extension.dicon

この辺が出たので、読み込まれているのだろう。
ただ、プロセスを見てもChronosのプロセルは動いていない。



ここから起動させるまでが異様に時間がかかった。


web.xmlS2Chronosサーブレット登録をしないといけないっぽい。

<!-- for S2Chronos -->
<servlet>
	<servlet-name>chronosServlet</servlet-name>
	<servlet-class>org.seasar.chronos.extension.servlet.S2ChronosServlet</servlet-class>
	<load-on-startup>3</load-on-startup>
</servlet>


tomcat起動

DEBUG 2010-11-23 23:25:59,593 [main] スケジューラ を 開始します.
WARN  2010-11-23 23:25:59,593 [main] ルートパッケージ(rootpackage.task)に対応するリソースがクラスパスから見つかりませんでした。
DEBUG 2010-11-23 23:25:59,593 [main] スケジューラ を 開始しました.

って言うのが出たので、
どうやらこれでいいのだろう。
しかし、なぜセットアップのところに
org.seasar.chronos.extension.servlet.S2ChronosServlet
の記述のことが一切書いていないのだろうか。
TomcatだからServletを登録するのは当たり前なのかな。
でも、別にwebとして表示するためのものじゃないし、
プロセス立ち上げるには、別途記述しておかないと分からない気がするなぁ。


1つくらいタスクを作ってみるか。

package rootpackage.task;

import org.apache.log4j.Logger;
import org.seasar.chronos.core.annotation.task.Task;
import org.seasar.chronos.core.annotation.trigger.CronTrigger;

@Task
@CronTrigger(expression = "0 */1 * * * ?")
public class OneMinuteTask {

	Logger logger = Logger.getLogger( OneMinuteTask.class );
	
	public void doExecute() {
		logger.debug( this );
	}
}

こんなTaskを作成

DEBUG 2010-11-23 23:36:54,484 [chronos-pool-1-daemonthread-1] HOT deployを開始します
DEBUG 2010-11-23 23:36:54,484 [chronos-pool-1-daemonthread-1] cronExpression = 0 */1 * * * ?
DEBUG 2010-11-23 23:36:54,515 [chronos-pool-1-daemonthread-1] HOT deployを終了しました
DEBUG 2010-11-23 23:36:56,515 [chronos-pool-1-daemonthread-1] HOT deployを開始します
DEBUG 2010-11-23 23:36:56,515 [chronos-pool-1-daemonthread-1] HOT deployを終了しました
DEBUG 2010-11-23 23:36:58,515 [chronos-pool-1-daemonthread-1] HOT deployを開始します
DEBUG 2010-11-23 23:36:58,515 [chronos-pool-1-daemonthread-1] HOT deployを終了しました
DEBUG 2010-11-23 23:37:00,515 [chronos-pool-1-daemonthread-1] HOT deployを開始します
DEBUG 2010-11-23 23:37:00,515 [chronos-pool-1-daemonthread-1] タスク (rootpackage.task.OneMinuteTask) を 開始します.
DEBUG 2010-11-23 23:37:00,515 [chronos-pool-1-daemonthread-2] タスク (rootpackage.task.OneMinuteTask) を 開始しました.
DEBUG 2010-11-23 23:37:00,546 [chronos-pool-3-thread-1] BEGIN rootpackage.task.OneMinuteTask#doExecute()
DEBUG 2010-11-23 23:37:00,546 [chronos-pool-3-thread-1] rootpackage.task.OneMinuteTask$$EnhancedByS2AOP$$8b9df2@13a848
DEBUG 2010-11-23 23:37:00,546 [chronos-pool-3-thread-1] END rootpackage.task.OneMinuteTask#doExecute() : null
DEBUG 2010-11-23 23:37:00,546 [chronos-pool-1-daemonthread-2] タスク (rootpackage.task.OneMinuteTask) を 終了します.
DEBUG 2010-11-23 23:37:00,546 [chronos-pool-1-daemonthread-2] タスク (rootpackage.task.OneMinuteTask) を 終了しました.
DEBUG 2010-11-23 23:37:00,546 [chronos-pool-1-daemonthread-2] HOT deployを終了しました
WARN  2010-11-23 23:37:02,515 [chronos-pool-1-daemonthread-1] HOT deploy対象クラス(rootpackage.task.OneMinuteTask)が非対象クラスから参照されて通常のクラスローダにロードされています。
DEBUG 2010-11-23 23:37:02,515 [chronos-pool-1-daemonthread-1] HOT deployを開始します
DEBUG 2010-11-23 23:37:02,546 [chronos-pool-1-daemonthread-1] HOT deployを終了しました
DEBUG 2010-11-23 23:37:04,546 [chronos-pool-1-daemonthread-1] HOT deployを開始します
DEBUG 2010-11-23 23:37:04,546 [chronos-pool-1-daemonthread-1] HOT deployを終了しました
DEBUG 2010-11-23 23:37:06,546 [chronos-pool-1-daemonthread-1] HOT deployを開始します
DEBUG 2010-11-23 23:37:06,546 [chronos-pool-1-daemonthread-1] HOT deployを終了しました
DEBUG 2010-11-23 23:37:08,546 [chronos-pool-1-daemonthread-1] HOT deployを開始します
DEBUG 2010-11-23 23:37:08,546 [chronos-pool-1-daemonthread-1] HOT deployを終了しました

ログが出た。

DEBUG 2010-11-23 23:37:00,546 [chronos-pool-3-thread-1] rootpackage.task.OneMinuteTask$$EnhancedByS2AOP$$8b9df2@13a848

これが出たので、成功だろう。


ただ、2秒ごとにデバッグログが出る。
chronosCustomize.dicon

2000L
の設定のためだろう。
どうやら


設定秒数ごとに登録されているタスクを全部見て、
起動するポイントだったら起動させる。


という感じだろうな。
なんかピンポイントで起動させるのかなぁと思っていたけど、
まぁ、よく考えたらそうだよなぁ
時の神なのですばらしいと思うほどの期待があっただけに、
意外と普通なことだったので、なんか残念だなぁ。
いや、まぁもちろんすごいのには変わりないんだけど。


自分で、「毎時分秒で起動するようなバッチ」を自分で作るのとどっちがいいのかなぁ。
まぁ、起動する部分や時間のトリガーを自分で作ったりしなくて良い分、
こっちを使うほうがいいなぁ。
一番気になっていたTomcatに組み込むということだが、
j5ik2oさんが2年も前wに、mainで呼び出せばバッチ処理ができると下記の記事で書いている
id:j5ik2o:20080916:1221535006
この辺を自分のバッチとしてプロジェクト作るのが一番よさそうだなぁ。

javax.mail.internet.MimeMessageのgetSubject()でのデコード

Re4:=?ISO-2022-JP?B?GyRCJCpCVCQ/JDskNyReJDckPxsoQg==?=

というものをデコードしたかった。

MimeMessageに対して、InputStreamでメールの内容を読み込ませて、

MimeMessage#getSubject()

でタイトルを取り出してみると、

Re4:=?ISO-2022-JP?B?GyRCJCpCVCQ/JDskNyReJDckPxsoQg==?=

されないwww

=?ISO-2022-JP?B?GyRCJCpCVCQ/JDskNyReJDckPxsoQg==?=

タイトルの先頭にエンコード対象のものではないものがあるので、
それを削除してやってみると、

お待たせしました

されたw


そういうもんなのかな…。


ちなみにこれでやっても中途半端になったw

=?iso-2022-jp?B?GyRCJCpCVCQ/JDskNyReJDckPxsoQg==?= Re4:Re4:Re4:=?iso-2022-jp?B?GyRCJCpCVCQ/JDskNyReJDckPxsoQg==?=
お待たせしました Re4:Re4:Re4:=?iso-2022-jp?B?GyRCJCpCVCQ/JDskNyReJDckPxsoQg==?=