顯示具有 開發:SpringFramework 標籤的文章。 顯示所有文章
顯示具有 開發:SpringFramework 標籤的文章。 顯示所有文章

2007年6月8日 星期五

JBoss中Web應用程式利用Spring設定自行定義的Log4j

將在tomcat 上測好的程式包成war檔後deployjboss 後發現jboss 讀到log4j時會出現以下訊息

ERROR: invalid console appender config detected, console stream is looping.

或不出現錯誤訊息。而無法使用war檔中的log4j.properties




是的,jboss本身在[JBOSS_HOME]serverdefaultconflog4j.xml 就有這個設定檔作loger形式的初始化,如果再讓自己的webapp 有一個servlet去讀自己設定的lo4joutput type,無論是log4j.properties or log4j.xml都會造成 ----->ERROR: invalid console appender config detected, console stream is looping.

所以如果你要deploy自己的webappjboss上時 ,一般而言只要去以上的路徑的log4j.xml去修改你想要的輸出型式就ok了。

[JBOSS_HOME]serverdefaultconflog4j.xml 改或加自己的設定這不太make sense,最好還是要針對個別application有自己的log4j設定檔比較合理。因此,我們可以透過SpringLog4j的補強,得到較彈性的設定,並且額外的解決log4j設定無法在JBoss使用的問題。

Spring最擅長的,就是在別家的蛋糕上再加些cream,讓你J2EE without Spring的時候心癢癢。

log4j,可以有如下的cream

1. 動態的改變記錄級別和策略,不需要重啓Web應用,如《Effective Enterprise Java》所說。

2. log文件定在 /WEB-INF/logs/ 而不需要寫絕對路徑。

3. 可以把log4j.properties和其他properties一起放在/WEB-INF/ ,而不是Class-Path

web.xml 添加

<context-param>

<param-name>log4jConfigLocation</param-name>

<param-value>WEB-INF/log4j.properties</param-value>

</context-param>

<context-param>

<param-name>log4jRefreshInterval</param-name>

<param-value>60000</param-value>

</context-param>

<listener>

<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>

</listener>

在上文的配置裏,

Log4jConfigListener會去WEB-INF/log4j.propeties 讀取配置文件;開一條watchdog線程每60秒掃描一下配置文件的變化;並把web目錄的路徑壓入一個叫webapp.root的系統變數。

然後,在log4j.properties 裏就可以這樣定義logfile位置

log4j.appender.logfile.File=${webapp.root}/WEB-INF/logs/myfuse.log

如果有多個web應用,怕webapp.root變數重復,可以在context-param裏定義webAppRootKey

但透過Spring的設定會導致JBoss出現如下另外的錯誤訊息:

15:03:32,531 INFO [STDOUT] log4j:ERROR A "org.jboss.logging.util.OnlyOnceErrorHandler" object is no

15:03:32,546 INFO [STDOUT] log4j:ERROR The class "org.apache.log4j.spi.ErrorHandler" was loaded by

15:03:32,546 INFO [STDOUT] log4j:ERROR [WebappClassLoader

delegate: false

repositories:

/WEB-INF/classes/

----------> Parent Classloader:

java.net.FactoryURLClassLoader@1f808e6

] whereas object of type

關於這個問題只需進行以下修正即可。

1.開啟JBoss相關設定檔%jboss_home%/server/default/deploy/jbossweb-tomcat55.sar/META-INF/jboss-service.xml

2.修改指定屬性即可

<attribute name="Java2ClassLoadingCompliance">true</attribute>

<attribute name="UseJBossWebLoader">true</attribute>


Read More......

2007年5月30日 星期三

SpringSide1.0 SpringMVC中Validation功能實作

SpringMVC使用Commons-Validation
在SpringSide 1.0中使用SpringMVC作為Presentation Layer架構。
當中將MultiActionController進行了擴充,使其能應用在所有呈現層狀況。
而在Validation中使用了springmodules的validation模組,使其能完整的整合Commons-Validation。
因此若希望在SpringMVC中使用Commons-Validation的話。
只需進行以下設定:

<!-- 定义 Commons-Validator Factory
注意:当前版本的springmodules, validatorFactory不能定义在bookstore-servlet-->
<bean id="validatorFactory" class="org.springmodules.validation.commons.DefaultValidatorFactory">
<property name="validationConfigLocations">
<list>
<value>classpath*:conf/validator/validator-rules.xml</value>
<value>classpath*:conf/validator/validator.xml</value>
</list>
</property>
</bean>

<!-- 用"validators"作id,方便autowire到 web controllers -->
<bean id="validators" class="org.springmodules.validation.commons.DefaultBeanValidator">
<property name="validatorFactory" ref="validatorFactory"/>
</bean>

validator-rules.xml,validator.xml使用Commons-Validation或Struts的都知道這是幹嘛的!在此就不說明。
在上述的設定中,將Commons-Validation設定至Bean Id為validators中,可直接注入SpringMVC的設定。

SpringMVC使用一般的Validation
有時候validation邏輯太過複雜,以至Commons-Validation無法勝任,或可勝任,但設定可讀性相當低,
反而造成難以維護的窘境,這時可直接使用Spring本身的Validation機制,甚至可合併二個Validation一起使用。
Spring注設方式如下:
<bean name="/xxx.do" class="com.sample.web.controller.MyController">
<description>Validation範例</description>
<property name="methodNameResolver" ref="methodNameResolver"/>
<property name="commandClass" value="com.sample.to.MyForm"/>
<property name="commandManager" ref="myDao"/>
<property name="formView" value="page/my"/>
<property name="validators"> <bean id="myValidator" class="com.sample.validation.MyValidator"/> </property> </bean>
將自定的Validator注射進validators屬性中,注意在程式碼中validators是陣列型態,而在Spring中並無說明陣列應如何注射。
開發人員可參考上述的做法注射多個Validator進SpringMVC的Action中。


Read More......

2007年5月25日 星期五

Quartz設定後無預期並行排程解疑

在Spring中我們可以整合Quartz進行定時排程的程式呼叫!
其設定如下:



上述的設定,定義了在每天凌晨1點進行排程執行SpringContainer中的ldapManager物件中的batchLdap的函式。看來似乎沒問題,但在實際執行中會發現,在排程時間到了之後會持續不斷執行batchLdap函式,直到凌晨2點為止。並且若使用Log4j設定%t顯示log中執行緒資訊的話,會發現,Quartz不但連續執行指定的函式,並且並行多條執行緒。若不希望Quartz同時間啟動多條執行緒進行排程函式的話。可加入如下:



而會一直不斷執行的問題還沒解決,其實這並不是問題,只是設定錯誤而已,本例若希望在凌晨1點只執行一次排程的話。只需進行設定的修改,如下:




也就是說,指定在凌晨1點零分零秒時執行,之前[*]的定義是代表會持續任意時間,所以才會發生會連續不斷的執行排程函式。這點是所有使用Quartz的開發人員該注意的。

Read More......