1.0.0をちょっとみてみる

SAStruts1.0.0をちょっとみてみる。

ふーむ、RequestProcessorを継承したS2RequestProcessorでActionを作っているのか。
で、Actionはリクエストの度に作られると。これはStruts1.2.9とちがうな。

Struts1.2.9の場合、Actionはリクエスト間で共有されるので、インスタンスフィールドをもっちゃ
ダメだっていうけれど、SAStrutsだとそれは無いわけか。

というかSAStrutsでは、Action1つで全部やっちゃいましょうってカンジだな。

Cubbyはどんなカンジなのかな。

クラスローダ

http://www-06.ibm.com/jp/software/websphere/developer/j2ee/strategy/を読んでわかった気になって、
後日またわからなくなって、また読み返してしまう。そんなクラスローダ。^^);

ちなみに、Strutsの以下のクラスローディングの仕方は

    public static Class applicationClass(String className) throws ClassNotFoundException {

        // Look up the class loader to be used
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        if (classLoader == null) {
            classLoader = RequestUtils.class.getClassLoader();
        }

        // Attempt to load the specified class
        return (classLoader.loadClass(className));

    }

有名みたいで、

ソースコードリーディングから学ぶ Javaの設計と実装

ソースコードリーディングから学ぶ Javaの設計と実装

Java World (ジャバ・ワールド) 2005年 9月号

Java World (ジャバ・ワールド) 2005年 9月号

*1
に出てたりします。

applicationClassメソッドはRequestProcessorからActionクラスをロードする際に呼ばれます。

で、単純にClass.forNameだとstruts-xx.jarがEARクラスローダで読み込まれた場合に、自作したActionクラスは
WARクラスローダのクラスパス上にあり、親から子がみれずClassNotFoundExceptionになるようです。

それを回避するためにStrutsは上記のようなことをやっているようです。

スレッドに関連付けられたコンテキストクラスローダ(HTTPリクエストにひもづいたWARクラスローダ)を取得できたら、
それを使い、取得できなかったら(どんな場合?)、Strutsをロードしたクラスローダを使うようです(これがEARクラスローダだったら、やっぱりActionクラスが見つからないような。。。)。

*1:この雑誌にはひがさんも記事書いてます。JUnitから学んだシンプルさを身に着けようと思いSeasarの初期バージョン(APサーバのほうかな?)を書いたようです。またIBMの方がSeasarJTA、コネクションプーリング部分の実装のシンプルさに感心した記事もありました。

メリット、デメリット

http://d.hatena.ne.jp/higayasuo/20080203#1202012253
http://d.hatena.ne.jp/shot6/20080203
http://d.hatena.ne.jp/habuakihiro/20080203#1202033512

うーむ。

私自身はTeedaJSF)はあんまり触ったことないので、なんともいえないですが、
何となく思うのは、
1ビュー(HTML):1クラス(Page)よりも、
1リクエスト:1クラス(Action)のほうが感覚的にわかりやすいのかもしれませんね。

もっとも、こんなTeedaプラグイン
できたら状況が変わるかも。

だいたいのステップ数

プロダクト バージョン ステップ数
S2 EA1 4.9k
s2framework 2.4.22 26k
s2extention 2.4.22 15k
s2tiger 2.4.22 20k
teeda-core 1.0.11-SP2 40k
teeda-extention 1.0.11-SP2 23k
struts 1.2.9 27k
sa-struts 1.0.0 2.8k

確かにSAStruts少ないな。

不安定

Eclipse 3.3にWebLauncher入れてるとなんか不安定になるな。以下のエラーログが出てるし。どういうときに
再現するのかが良くわからないけど。ま、そんなに使わないのでとりあえずアンインストールしておく。

java.lang.NullPointerException
at java.util.Hashtable.get(Hashtable.java:334)
at org.seasar.weblauncher.Activator.findProject(Activator.java:104)
at org.seasar.weblauncher.action.ToggleServerAction.getProjectByBrowserId(ToggleServerAction.java:140)
at org.seasar.weblauncher.action.ToggleServerAction.checkEnabled(ToggleServerAction.java:106)
at org.seasar.weblauncher.action.ServerAction.maybeEnabled(ServerAction.java:45)
at org.seasar.weblauncher.action.ServerAction$1.partHidden(ServerAction.java:77)
at org.eclipse.ui.internal.PartListenerList2$6.run(PartListenerList2.java:149)
at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:37)
at org.eclipse.core.runtime.Platform.run(Platform.java:857)
at org.eclipse.ui.internal.PartListenerList2.fireEvent(PartListenerList2.java:53)
at org.eclipse.ui.internal.PartListenerList2.firePartHidden(PartListenerList2.java:147)
at org.eclipse.ui.internal.PartService.firePartHidden(PartService.java:126)
at org.eclipse.ui.internal.WorkbenchPagePartList.firePartHidden(WorkbenchPagePartList.java:63)
at org.eclipse.ui.internal.PartList.partHidden(PartList.java:197)
at org.eclipse.ui.internal.PartList.access$3(PartList.java:188)
at org.eclipse.ui.internal.PartList$1.propertyChanged(PartList.java:46)
at org.eclipse.ui.internal.WorkbenchPartReference.fireInternalPropertyChange(WorkbenchPartReference.java:372)
at org.eclipse.ui.internal.WorkbenchPartReference.fireVisibilityChange(WorkbenchPartReference.java:533)
at org.eclipse.ui.internal.PartPane.setVisible(PartPane.java:304)
at org.eclipse.ui.internal.ViewPane.setVisible(ViewPane.java:531)
at org.eclipse.ui.internal.presentations.PresentablePart.setVisible(PresentablePart.java:179)
at org.eclipse.ui.internal.presentations.util.PresentablePartFolder.select(PresentablePartFolder.java:272)
at org.eclipse.ui.internal.presentations.util.LeftToRightTabOrder.select(LeftToRightTabOrder.java:65)
at org.eclipse.ui.internal.presentations.util.TabbedStackPresentation.selectPart(TabbedStackPresentation.java:400)
at org.eclipse.ui.internal.PartStack.refreshPresentationSelection(PartStack.java:1256)
at org.eclipse.ui.internal.PartStack.setSelection(PartStack.java:1209)
at org.eclipse.ui.internal.PartStack.presentationSelectionChanged(PartStack.java:843)
at org.eclipse.ui.internal.PartStack.access$1(PartStack.java:829)
at org.eclipse.ui.internal.PartStack$1.selectPart(PartStack.java:139)
at org.eclipse.ui.internal.presentations.util.TabbedStackPresentation$1.handleEvent(TabbedStackPresentation.java:131)
at org.eclipse.ui.internal.presentations.util.AbstractTabFolder.fireEvent(AbstractTabFolder.java:267)
at org.eclipse.ui.internal.presentations.util.AbstractTabFolder.fireEvent(AbstractTabFolder.java:276)
at org.eclipse.ui.internal.presentations.r33.DefaultTabFolder.access$1(DefaultTabFolder.java:1)
at org.eclipse.ui.internal.presentations.r33.DefaultTabFolder$2.handleEvent(DefaultTabFolder.java:84)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:66)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:938)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:962)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:947)
at org.eclipse.swt.widgets.Widget.notifyListeners(Widget.java:706)
at org.eclipse.swt.custom.CTabFolder.setSelection(CTabFolder.java:3227)
at org.eclipse.swt.custom.CTabFolder.onMouse(CTabFolder.java:2005)
at org.eclipse.swt.custom.CTabFolder$1.handleEvent(CTabFolder.java:316)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:66)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:938)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3682)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3293)
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2389)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2353)
at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2219)
at org.eclipse.ui.internal.Workbench$4.run(Workbench.java:466)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:289)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:461)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:106)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:169)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:106)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:76)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:363)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:176)
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:597)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:508)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:447)
at org.eclipse.equinox.launcher.Main.run(Main.java:1173)
at org.eclipse.equinox.launcher.Main.main(Main.java:1148)