Apache Struts

Struts導入メモ。

バージョン1.2以前と1.3との相違

この時期にStrutsを導入する場合に注意しなければならないのは、 バージョン1.2と1.3では、その構成が大分変わっていること。 (今では、1.2以前をStrutsクラシックと呼ぶらしい。)

互換性

1.2以前でコンパイルされたアプリケーションは、一応動作する模様。 ただやはり、1.3で構築しなおす方が無難。

struts.jar はどこいった?

1.2以前で struts.jar としてまとまっていたライブラリが、 1.3では struts-*.jar のような名前になって機能ごとに分割されている。

ということで、struts-*.jar と名前のつくライブラリを全部参照設定してしまえば、 1.2以前で作成したソースはコンパイルできるはずである。 (本当は、必要なものだけ参照設定する方がスマートだけど。)

TLD の URI

Struts が Jakarta プロジェクトじゃなくなったらしい(?)ので、 ドメインが変更になっている。

struts-config.xml の設定

struts-config.xml の DOCTYPE に記述する宣言は変更になっているっぽい。

<!DOCTYPE struts-config PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
	"http://struts.apache.org/dtds/struts-config_1_3.dtd">

変更されたのは、

  • バージョンが 1.3(当然)。
  • URIが jakarta.apache.org/struts から struts.apache.org になっている。

というところ。

1.3でなくなったもの

  • ActionError?
  • DataSourceConfig?

これらはなくなったらしい。ActionError?ActionMessage? に置き換えるべし。

Struts の罠

作業をしていてぶち当たった問題とその解決方法をメモ。

データソースの初期化に失敗する件

struts-config.xml の data-source に次のように設定したとする。

<struts-config>

   <data-sources>
      <data-source key="oracle">
         <set-property property="driverClass" value="oracle.jdbc.driver.OracleDriver" />
         <set-property property="url" value="jdbc:oracle:thin:@127.0.0.1:1521:ORCL" />
         <set-property property="user" value="user" />
         <set-property property="password" value="passwd" />
         <set-property property="maxCount" value="64" />
         <set-property property="minCount" value="10" />
         <set-property property="autoCommit" value="false" />
      </data-source>
   </data-sources>

(以下略)

一見設定は正しいように見える(というか、設定自体は正しい)。 しかし、これで、あるとき突然次のようなエラーを吐いて、action サーブレットが使えなくなることがある。

   :
   :
2007/03/16 19:42:19 org.apache.catalina.core.ApplicationContext log
情報: サーブレット action を利用不可能にマークします
2007/03/16 19:42:19 org.apache.catalina.core.StandardContext loadOnStartup
致命的: サーブレット /app_hoge がload()例外を投げました
javax.servlet.UnavailableException: Initializing application data source oracle
   at org.apache.struts.action.ActionServlet.initModuleDataSources(ActionServlet.java:1091)
   at org.apache.struts.action.ActionServlet.init(ActionServlet.java:472)
   at jp.co.hoge.MyActionServlet.init(MyActionServlet.java:62)
   at javax.servlet.GenericServlet.init(GenericServlet.java:212)
   at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1161)
   at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:981)
   at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4044)
   at org.apache.catalina.core.StandardContext.start(StandardContext.java:4350)
   at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:760)
   at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:740)
   at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:525)
   at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:626)
   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:1138)
   at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:311)
   at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:120)
   at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1022)
   at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)
   at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1014)
   at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
   at org.apache.catalina.core.StandardService.start(StandardService.java:451)
   at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
   at org.apache.catalina.startup.Catalina.start(Catalina.java:552)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:585)
   at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
   at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)

(以下略)

これは、data-source の設定が不味い(接続先の情報、ユーザ名、パスワードなど)ときにも出るエラーなのだけど、 コンソール(Oracle の場合は SQLPlus )などで接続すると、ちゃんとつながったりする。 つまり、DBMSも落ちてないし、設定も間違っていない。 であるのに、データソースの初期化に失敗し、UnavailableException? (このサーブレットは使えないよ)というエラーが発生する(ことがある)。

これ、大ハマリしたんだけど、原因は、Oracle のプーリング機能が働いてる為だった。

データベースのコネクションプールというのは、 あらかじめいくつかの接続を開いておいて、 2度目以降のアクセスで同じ接続先だったりSQLだったりしたときに、 前に使っていた接続をプールから探して、同じのがあればそれを再利用するという機能。

つまり、このあらかじめ開いておく接続数がサーバの許容(接続可能な数)を超えてしまうとつながらないと。 SQLPlus は接続を1本しか張らないから、すんなりつながるわけですな。

これがDBサーバの設定や状態によって発生したりしなかったりするエラーなので、 突然つながらなくなったり、かと思えば突然つながるようになったりするので、 原因がさっぱりつかめずにハマるパターンだったりする。

大抵、DBサーバを再起動すればしばらく正常につながる。 ただ、開発やデバッグの段階ではプーリング機能はあまり関係ないので、 minCount や maxCount の値を小さく(両方 1 でも良い)してしまえば良い。

native2ascii

ネイティブコード (Latin 1 および Unicode 以外) のファイルを Unicode コードに変換。

JDK に含まれているはず。(\bin の中)

Unicode に変換

C:\(JDK ディレクトリ)\bin> native2ascii (ネイティブコードのファイル) (変換先ファイル)

例えば、

C:\JDK1.5\bin> native2ascii C:\temp\hoge.properties C:\temp\hoge.properties.asc

とか。

※ファイル名はフルパスで。

ネイティブに戻す

reverse オプションを使う。

C:\(JDK ディレクトリ)\bin> native2ascii -reverse (Unicode のファイル) (変換先ファイル)

文字コードを指定する

encoding オプションを使う

C:\(JDK ディレクトリ)\bin> native2ascii -encoding (文字コード) (ネイティブコードのファイル) (変換先ファイル)

例えば、

C:\JDK1.5\bin> native2ascii -encoding EUC-JP C:\temp\hoge.properties C:\temp\hoge.properties.asc

とか。

参考

参考サイト


プログラム・開発系メモ


トップ   編集 凍結解除 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2010-05-15 (土) 12:07:49 (5264d)