2007年5月18日

          搭建過(guò)程備注:
          1. 虛擬機(jī)軟件Vmware 8.0 Workstation,Windows 2008 Enterprise Server, Sql Server 2008 R2。
          2. 倆個(gè)節(jié)點(diǎn)平臺(tái)版本必須一致,都為企業(yè)版。
          3. 與構(gòu)建Windows 2003群集不同,不能使用vmware的共享磁盤機(jī)制。Windows 2008集群對(duì)存儲(chǔ)要求很高,不支持SCSI硬盤做集群。
              本次使用starwind 5.4代替vmware的共享磁盤實(shí)現(xiàn)群集存儲(chǔ)。
          4. 搭建Windows集群需要3臺(tái)虛擬機(jī):2個(gè)節(jié)點(diǎn)+1臺(tái)存儲(chǔ)。
          5. 搭建SqlServer 2008集群需要4替虛擬機(jī):2個(gè)節(jié)點(diǎn)+1臺(tái)DC+1臺(tái)存儲(chǔ)。

          搭建順序:
          1. 安裝DC+DNS服務(wù)器。
          2. 安裝集群節(jié)點(diǎn), 配置雙網(wǎng)卡,域登錄。
          3. 安裝群集磁盤服務(wù)器
          4. 在集群節(jié)點(diǎn)上配置iSCSI發(fā)起。
          5. 在集群節(jié)點(diǎn)上安裝“故障轉(zhuǎn)移群集”功能。
          6. 進(jìn)行故障轉(zhuǎn)移群集驗(yàn)證和創(chuàng)建。
          7. 至此,Windows集群環(huán)境安裝完畢。
          8. 在集群節(jié)點(diǎn)上按群集方式安裝SqlServer 2008。
          9. SqlServer 2008集群環(huán)境構(gòu)建完畢。

          參考文檔:
          Windows Server 2008的故障轉(zhuǎn)移群集入門: http://os.51cto.com/art/201007/210286.htm
          windows server2008虛擬機(jī)+群集: http://wenku.baidu.com/view/5e5b2be8e009581b6bd9eb1a.html
          Windows2008+sqlserver2008集群安裝:http://wenku.baidu.com/view/601dc74d2b160b4e767fcf46.html

          posted @ 2012-06-21 09:23 bluoy 閱讀(3954) | 評(píng)論 (0)編輯 收藏

          神一樣的軟件,膜拜ing...
          連我這天生kernel iptable有缺陷的都能用。

          當(dāng)前版本:2.04.
          還是個(gè)Open Source的,改天一定要好好觀摩一番的。

          posted @ 2011-09-28 15:55 bluoy 閱讀(324) | 評(píng)論 (0)編輯 收藏

          If you meet following errors below when you try to build your source code:

           

          Checking build tools versions...

          build/core/main.mk:72:

          ************************************************************

          build/core/main.mk:73: You are attempting to build on a 32-bit system.

          build/core/main.mk:74: Only 64-bit build environments are supported beyond froyo/2.2.

          build/core/main.mk:75:

          ************************************************************

          Don’t panic, just change the code:

          build/core/main.mk

          ifeq ($(BUILD_OS),linux)

          build_arch := $(shell uname -m) 

          ---ifneq (64,$(findstring 64,$(build_arch))) 

          +++ifneq (i686,$(findstring i686,$(build_arch)))

           

          and change the code in four mk files below from “+=-m64” to “+=-m32”


          external/clearsilver/cgi/Android.mk

          external/clearsilver/java-jni/Android.mk

          external/clearsilver/util/Android.mk

          external/clearsilver/cs/Android.mk


          LOCAL_CFLAGS += -m32

          LOCAL_LDFLAGS += -m32

          end.

          posted @ 2011-01-07 10:54 bluoy 閱讀(375) | 評(píng)論 (0)編輯 收藏

          I got this idea when i was surfing the web in search of a tool similar to the Nokia Pc Suite for my Linux

          This How-To  works with many NOKIA Mobile Phone, especially for Nokia 3230, 6670, 6680, 6682 e 7610, 6120, Sony Ericsson Z1010, LG U8110/8120.

          First of all, we have to grant access for Mobile Phone to “dialout” group.

          sudo gedit /etc/udev/rules.d/40-permissions.rules

          Now we have to add to the end of file:

          # NOKIA 6120
          BUS==”usb”, SYSFS{idVendor}==”0421″, SYSFS{idProduct}==”002f”, GROUP=”dialout”

          where 0421 and 002f could be different depending on your Mobile Phone.
          To check your idVendor and idProduct, we have to type on terminal

          lsusb
          Bus 003 Device 009: ID 0421:002f Nokia Mobile Phones

          Now, we have to reload udev permission file:

          sudo /etc/init.d/udev restart

          We have to add our username on group “dialout”

          gpasswd -a username dialout

          All basics configurations for USB Data Cable are completed. We can start installation of obexftp and obextool GUI. Obextool GUI is written for tk graphic library, so GUI not have a good design as GTK.

          sudo apt-get install openobex-apps libopenobex1 obexftp obextool

          If you want start obextool from terminal we have to type for the first time:

          export OBEXCMD=”obexftp -t /dev/ttyACM0 -u 1″
          obextool

          or, we can start it simply by typing:

          obextool –obexcmd “obexftp -t /dev/ttyACM0 -u 1″

          When we start Obextool we can see this error message:

          It seems, that your device does not support the memory status feature.
          Memory status will be disabled

          To solve this problem we have to set some values on obextool.cfg:

          sudo gedit /etc/obextool.cfg

          set ObexConfig(config,memstatus) 0
          set ObexConfig(config,filemove) 0

          Another error message that we can see is:

          FIle ‘/FileName/’ could not be uploaded to ‘E:/Path’!
          Please check your file permissions.

          To solve it:

          sudo gedit /etc/obextool.cfg

          set ObexConfig(config,dir_slash) 1

          Good Job! Now your Mobile Phone works well in Ubuntu Gutsy with ObexTool.
          If we want add it as Desktop Entry:

          sudo gedit /usr/share/applications/obextool.desktop

          [Desktop Entry]
          Encoding=UTF-8
          Version=1.0
          Type=Application
          Exec=/usr/bin/obextool –obexcmd “obexftp -t /dev/ttyACM0 -u 1″
          Icon=/usr/share/icons/gnome/scalable/devices/phone.svg
          Terminal=false
          Name=Obextool
          GenericName=
          Comment=Browser your Mobile Phone
          Categories=Application;Utility;

          So, you can find it in your Gnome Panel over: “Applications” -> “Accessories” -> Obextool

          posted @ 2009-04-23 16:30 bluoy 閱讀(391) | 評(píng)論 (0)編輯 收藏

          下面的例子實(shí)現(xiàn)把一個(gè)整數(shù)的各個(gè)位上的數(shù)字相加,通過(guò)這個(gè)例子我們?cè)俅卫斫? connect by.

          create or replace function f_digit_add(innum integer) return number
          is
          outnum integer;
          begin
          if innum<0 then
          return 0;
          end if;
          select sum(nm) into outnum from(
          select substr(innum,rownum,1) nm from dual connect by
          rownum<length(innum)
          );
          return outnum;
          end f_digit_add;
          /

          select f_digit_add(123456) from dual;

          posted @ 2009-04-01 17:02 bluoy 閱讀(841) | 評(píng)論 (1)編輯 收藏

          終于搞明白了困惑很久的問(wèn)題,罪魁禍?zhǔn)走€是jdk啊。天殺的。
          以下內(nèi)容轉(zhuǎn)自網(wǎng)絡(luò):

          測(cè)試環(huán)境:Win2K Pro日文版,SUN J2SDK 1.5.0-beta2

          經(jīng)過(guò)測(cè)試,發(fā)現(xiàn)Shift_JIS和MS932編碼的全角波浪線(“~”)的編碼都是 0x8160(16進(jìn)制,兩個(gè)字節(jié),高位在前)。通過(guò)sun.io.ByteToCharMS932轉(zhuǎn)換后得到Unicode字符'\uFF5E',而通過(guò)sun.io.ByteToCharSJIS轉(zhuǎn)換后則得到Unicode字符'\u301C'。

          反之,Unicode字符'\uFF5E'通過(guò)sun.io.CharToByteMS932轉(zhuǎn)換后會(huì)得到MS932編碼的本地字符0x8160(16進(jìn)制,兩個(gè)字節(jié),高位在前),而Unicode字符'\u301C'通過(guò) sun.io.CharToByteSJIS轉(zhuǎn)換后也會(huì)得到Shift_JIS編碼的本地字符0x8160(16進(jìn)制,兩個(gè)字節(jié),高位在前),兩者的轉(zhuǎn)換結(jié)果相同。

          結(jié)論:在WinNT/2K/XP上,MS932和Shift_JIS這兩種本地字符集完全相同,只是分別采用JDK的sun.io.ByteToCharMS932和sun.io.ByteToCharSJIS對(duì)個(gè)別特殊的本地字符進(jìn)行轉(zhuǎn)換后所得到的 Unicode字符并不一樣。實(shí)際上,MS932就是WinNT/2K/XP上的Shift_JIS,只是與標(biāo)準(zhǔn)版的Shift_JIS字符集相比,MS932收錄了更多的字符,比如NEC和IBM對(duì)Shift_JIS的擴(kuò)展(如日文中的“?????①..?...”等等);然而,JDK中的 ByteToCharSJIS及CharToByteSJIS卻使用了標(biāo)準(zhǔn)的Shift_JIS字符集,所以部分?jǐn)U展字符在從byte轉(zhuǎn)換成char或是從char轉(zhuǎn)換成byte時(shí)會(huì)出現(xiàn)亂碼,這的確是JDK讓人非常迷惑的一處。

          參考資料1(日文):http://www.asahi-net.or.jp/~ez3k-msym/charsets/jis2ucs.htm

          posted @ 2009-02-03 16:52 bluoy 閱讀(1412) | 評(píng)論 (0)編輯 收藏

          1. 函數(shù)的overwrite實(shí)現(xiàn)時(shí),函數(shù)參數(shù)類型必須嚴(yán)格一致。與overload不同,并不遵守參數(shù)優(yōu)先匹配的原則。
          所以,不能用子類,或這接口的實(shí)現(xiàn)類來(lái)妄圖得到overwrite的目的。
          2. 使用反射手法時(shí),getMethod()的調(diào)用,參數(shù)類型必須與要得到的函數(shù)類型嚴(yán)格一致。與overload不同,并不遵守參數(shù)優(yōu)先匹配的原則。
          3內(nèi)部類,要實(shí)例化時(shí)必須首先實(shí)例化包含類。可以理解為內(nèi)部類只是包含類的數(shù)據(jù)成員
          4非public類,非javabean規(guī)范的Bean,內(nèi)部類BeanUtil類無(wú)法進(jìn)行操作,比如clone()等等。

          posted @ 2008-12-28 10:54 bluoy 閱讀(200) | 評(píng)論 (0)編輯 收藏

          雖然java沒(méi)有提供函數(shù)指針的操作,而是必須通過(guò)對(duì)象來(lái)曲線救國(guó)。
          不過(guò)延伸一下這個(gè)思路,其實(shí)也未必不是件好事。從某種意義上來(lái)說(shuō),整個(gè)java系統(tǒng),或者對(duì)象系統(tǒng),其實(shí)就是不計(jì)其數(shù)的鉤子組成的系統(tǒng)。因?yàn)椋瑓?shù)傳遞的過(guò)程中完全依賴著對(duì)象,一種行為和數(shù)據(jù)的結(jié)合體。這里,關(guān)鍵詞是參數(shù)傳遞和對(duì)象的行為,當(dāng)然離不開多態(tài)。
                  改變既有代碼的行為步驟:
                  1. 派生參數(shù)類得到新的子類。
                  2. 在子類中覆寫(overwrite)父類既有方法。
                  3. 將子類的實(shí)例作為參數(shù)傳遞。
                  這樣,就得到了改變父類行為的目的。
           對(duì)于既有框架自作主張的封裝,阻礙自己的目的的時(shí)候,這個(gè)做法往往能獨(dú)辟蹊徑。

          posted @ 2008-12-28 10:40 bluoy 閱讀(199) | 評(píng)論 (0)編輯 收藏

          Spring Framework 的理解以及可維護(hù)性是否得以改善的思考

          Spring的特性:
          1. 提供了一種管理對(duì)象的方法,可以把中間層對(duì)象有效地組織起來(lái)。一個(gè)完美的框架“黏合劑”。
          2. 采用了分層結(jié)構(gòu),可以增量引入到項(xiàng)目中。
          3. 有利于面向接口編程習(xí)慣的養(yǎng)成。
          4. 目的之一是為了寫出易于測(cè)試的代碼。
          5. 非侵入性,應(yīng)用程序?qū)pring API的依賴可以減至最小限度。
          6. 一致的數(shù)據(jù)訪問(wèn)介面。
          6. 一個(gè)輕量級(jí)的架構(gòu)解決方案。

          對(duì)Spring的理解
          Spring致力于使用POJOs來(lái)構(gòu)建應(yīng)用程序。由框架提供應(yīng)用程序的基礎(chǔ)設(shè)施,將只含有業(yè)務(wù)邏輯的POJOs作為組件來(lái)管理。從而在應(yīng)用程序中形成兩條相對(duì)獨(dú)立發(fā)展的平行線,并且在各自的抽象層面上延長(zhǎng)了各自的生命周期。

          Spring的工作基礎(chǔ)是Ioc。Ioc將創(chuàng)建對(duì)象的職責(zé)從應(yīng)用程序代碼剝離到了框架中,通常2中注入方式:setter 和 ctor參數(shù)。
          每個(gè)Bean定義被當(dāng)作一個(gè)POJO(通過(guò)類名和JavaBean的初始屬性或構(gòu)造方法參數(shù)兩種方式定義的Bean)。
          Spring的核心在org.springframework.beans,更高抽象層面是BeanFactory. BeanFactory是一個(gè)非常輕量級(jí)的容器。

          關(guān)于可維護(hù)性的思考
          Spring之類的技術(shù)確實(shí)帶來(lái)了應(yīng)用系統(tǒng)的可維護(hù)性的提高嗎?
          Ioc, AOP之類的技術(shù),本質(zhì)上都是將原本位于應(yīng)用程序代碼中"硬編碼"邏輯,剝離出來(lái)放到了配置文件中(或者其他形式)。主流聲音都是認(rèn)為提高了應(yīng)用程序的可維護(hù)性。

          但如果從以下方面觀察,結(jié)合項(xiàng)目實(shí)際經(jīng)驗(yàn),個(gè)人感覺(jué)這些技術(shù)的應(yīng)用大大降低了應(yīng)用程序的可維護(hù)性,尤其是面對(duì)一個(gè)陌生的系統(tǒng),或者項(xiàng)目人員變動(dòng)頻繁的時(shí)候。
          1. 中斷了應(yīng)用程序的邏輯,使代碼變得不完整,不直觀。此時(shí)單從Source無(wú)法完全把握應(yīng)用的所有行為。
          2. 將原本應(yīng)該代碼化的邏輯配置化,增加了出錯(cuò)的機(jī)會(huì)以及額外的負(fù)擔(dān)。
          3. 時(shí)光倒退,失去了IDE的支持。在目前IDE功能日益強(qiáng)大的時(shí)代,以往代碼重構(gòu)等讓人頭痛的舉動(dòng)越來(lái)越容易。而且IDE還提供了諸多強(qiáng)大的輔助功能,使得編程的門檻降低很多。通常來(lái)說(shuō),維護(hù)代碼要比維護(hù)配置文件,或者配置文件+代碼的混合體要容易的多。
          4. 調(diào)試階段不直觀,后期的bug對(duì)應(yīng)階段,不容易判斷問(wèn)題所在。
          5. 性能問(wèn)題。雖說(shuō)硬件性能日新月異,但是性能也是在不經(jīng)意間一點(diǎn)一點(diǎn)地流失的。從匯編到高級(jí)語(yǔ)言,到面向?qū)ο螅教摂M機(jī),一直處于這樣的發(fā)展趨勢(shì)。

          posted @ 2008-07-06 10:21 bluoy 閱讀(2021) | 評(píng)論 (3)編輯 收藏

          項(xiàng)目中組員偶然寫了一段垃圾的sql語(yǔ)句,不想?yún)s誤打誤撞的發(fā)現(xiàn)了一個(gè)jdbc的bug,包括Oracle 10g附帶的版本。

          詳細(xì)描述可以參考如下代碼:
             public static void testSetTimestampBug() throws Exception{
                  Calendar calendar = new GregorianCalendar();
                  Date d = calendar.getTime();
                  
                  String sql = "select 1+1 from dual where ?-sysdate<1";         //error sql
                  String sql1 = "select ?-sysdate from dual";                          //no error sql
                  String sql2 = "select 1+1 from dual where ?-1<sysdate";       //no error sql
                  PreparedStatement pst = cn.prepareStatement(sql);
                  //pst.setDate(1, new java.sql.Date(d.getTime()));                 //no  error
                  pst.setTimestamp(1, new java.sql.Timestamp(d.getTime()));   //bug!!!, throw SQLException: ORA-00932
              }
          三種sql的寫法中,第一種寫法在使用setTimestamp()時(shí)會(huì)出錯(cuò),其他倆種卻不會(huì)有問(wèn)題。
          即正常調(diào)用PreparedStatement.setTimestamp()方法,遇到某些特殊寫法的sql語(yǔ)句卻會(huì)出錯(cuò)。
          本例中,拋出如下例外:
          java.sql.SQLException: ORA-00932: inconsistent datatypes: expected NUMBER got INTERVAL.
          然而,如果使用setDate()方法,則一切正常,三種寫法都沒(méi)有問(wèn)題。

          因?yàn)橛羞@個(gè)問(wèn)題,如果在持久層使用了其他的中間件,則這個(gè)問(wèn)題可能變的更加隱蔽,比如iBatis中的處理是這樣的:
          java.util.Date ---> ibatis.DateTypeHandler----->PreparedStatement.setTimestamp() 
          java.sql.Date ---> ibatis.SqlDateTypeHandler----->PreparedStatement.setDate()
          如果不注意輸入?yún)?shù)類型的話,就會(huì)遇到上述問(wèn)題。我就因此費(fèi)了不少周折。
          對(duì)于iBatis的使用建議,保證入口參數(shù)類型始終為java.sql.Date即可。

          posted @ 2008-03-26 17:17 bluoy 閱讀(1800) | 評(píng)論 (0)編輯 收藏

          Web架構(gòu)特性及REST架構(gòu)風(fēng)格(部分內(nèi)容摘自網(wǎng)絡(luò))

          良好的Web架構(gòu)風(fēng)格:
              1. 客戶/服務(wù)器模式:  實(shí)現(xiàn)了UI與數(shù)據(jù)的分離。
              2. 服務(wù)端無(wú)狀態(tài)性: 可見(jiàn)性,可靠性,可伸縮性等方面的改善。
               可見(jiàn)性-無(wú)狀態(tài)性使得服務(wù)器不必要維護(hù)海量的上下文(Context)。
               可靠性-無(wú)狀態(tài)性減少了服務(wù)器從局部錯(cuò)誤中恢復(fù)的任務(wù)量。
               可伸縮性-無(wú)狀態(tài)性使得服務(wù)器可以很容易的釋放資源。
              3. 緩存: 減少服務(wù)端不必要的處理。
              4. 可伸縮性: 便于分布式和集群部署。
               上面的2,3點(diǎn)也是影響4的主要因素。而隨著系統(tǒng)用戶規(guī)模的指數(shù)上升,可伸縮性將變的至關(guān)重要。

          現(xiàn)在大多數(shù)應(yīng)用程序都忽略或者違反了上述2, 3的風(fēng)格。當(dāng)然也肯定失去了4帶來(lái)的好處。
          比如Java Servlet中HttpSession的應(yīng)用,使服務(wù)器端保存了客戶端的狀態(tài)。
          時(shí)下流行的動(dòng)態(tài)頁(yè)面的做法也使得資源緩存變得困難或者不可能。
          這些都直接影響了應(yīng)用的可伸縮性。

          改善現(xiàn)狀的思路是,把服務(wù)端的處理和狀態(tài)前移,由客戶端來(lái)實(shí)現(xiàn)。使服務(wù)端回歸到無(wú)狀態(tài)的特性。
          以采用ajax技術(shù)的應(yīng)用系統(tǒng)為例:因?yàn)椴恍枰耆⑿戮涂梢耘c服務(wù)器進(jìn)行交互,使得有狀態(tài)客戶機(jī)成為可用選擇。基于瀏覽器的應(yīng)用程序代碼可以在必要時(shí)獲取新的服務(wù)器數(shù)據(jù),并把這些數(shù)據(jù)織入當(dāng)前頁(yè)面。
          將處理和狀態(tài)前移到每個(gè)客戶機(jī)上后,實(shí)現(xiàn)了無(wú)狀態(tài)的服務(wù)端;同時(shí)緩存服務(wù)器可以緩存ajax引擎(比如dojo, prototype etc.),以及狀態(tài)無(wú)關(guān)的數(shù)據(jù)。
          個(gè)人理解,多種瀏覽器的plug-in技術(shù)(Sun的applet, MS的ActiveX等等),都應(yīng)該是這種思路的不同技術(shù)實(shí)現(xiàn)。

          經(jīng)過(guò)以上分析整理,實(shí)際上已經(jīng)涉及到了時(shí)下流行的一個(gè)概念-REST.

          REST(Representational State Transfer)來(lái)源于Dr. Roy Thomas Fielding,  <Architectural Styles and the Design of Network-based Software Architectures>
          當(dāng)瀏覽器瀏覽訪問(wèn)一個(gè)url資源時(shí),返回的頁(yè)面即為該url資源的representation,這個(gè)representation給瀏覽器一個(gè)state,當(dāng)
          瀏覽器訪問(wèn)下一個(gè)url資源時(shí),瀏覽器的state就transfer了。
          REST其本身只是為分布式超媒體系統(tǒng)(distributed hypermedia systems)設(shè)計(jì)的一種架構(gòu)風(fēng)格,而不是某個(gè)標(biāo)準(zhǔn),框架。

          REST的設(shè)計(jì)準(zhǔn)則
              1.網(wǎng)絡(luò)上的所有事物都被抽象為資源(resource);
              2.每個(gè)資源對(duì)應(yīng)一個(gè)唯一的資源標(biāo)識(shí)符(resource identifier);
              3.通過(guò)通用的連接器接口(generic connector interface)對(duì)資源進(jìn)行操作;
              4.對(duì)資源的各種操作不會(huì)改變資源標(biāo)識(shí)符;
              5.所有的操作都是無(wú)狀態(tài)的(stateless)。

          REST中的資源所指的不是數(shù)據(jù),而是數(shù)據(jù)和表現(xiàn)形式的組合。
          REST是基于Http協(xié)議的,任何對(duì)資源的操作行為都是通過(guò)Http協(xié)議來(lái)實(shí)現(xiàn)。以往的Web開發(fā)大多數(shù)用的都是Http協(xié)議中的GET和POST方法,對(duì)其他方法很少使用,這實(shí)際上是因?yàn)閷?duì)Http協(xié)議認(rèn)識(shí)片面的理解造成的。Http不僅僅是一個(gè)簡(jiǎn)單的運(yùn)載數(shù)據(jù)的協(xié)議,而是一個(gè)具有豐富內(nèi)涵的網(wǎng)絡(luò)軟件的協(xié)議。他不僅僅能對(duì)互聯(lián)網(wǎng)資源進(jìn)行唯一定位,而且還能告訴我們?nèi)绾螌?duì)該資源進(jìn)行操作。Http把對(duì)一個(gè)資源的操作限制在4個(gè)方法以內(nèi):GET, POST,PUT和DELETE,這正是對(duì)資源CRUD操作的實(shí)現(xiàn)。由于資源和URI是一一對(duì)應(yīng)的,執(zhí)行這些操作的時(shí)候URI是沒(méi)有變化的,這和以往的 Web開發(fā)有很大的區(qū)別。正由于這一點(diǎn),極大的簡(jiǎn)化了Web開發(fā),也使得URI可以被設(shè)計(jì)成更為直觀的反映資源的結(jié)構(gòu),這種URI的設(shè)計(jì)被稱作 RESTful的URI。這位開發(fā)人員引入了一種新的思維方式:通過(guò)URL來(lái)設(shè)計(jì)系統(tǒng)結(jié)構(gòu)。當(dāng)然了,這種設(shè)計(jì)方式對(duì)一些特定情況也是不適用的,也就是說(shuō)不是所有的URI都可以RESTful的。
          REST 之所以可以提高系統(tǒng)的可伸縮性,就是因?yàn)樗笏械牟僮鞫际菬o(wú)狀態(tài)的。由于沒(méi)有了上下文(Context)的約束,做分布式和集群的時(shí)候就更為簡(jiǎn)單,也可以讓系統(tǒng)更為有效的利用緩沖池(Pool)。并且由于服務(wù)器端不需要記錄客戶端的一系列訪問(wèn),也減少了服務(wù)器端的性能。

          posted @ 2008-03-24 16:35 bluoy 閱讀(399) | 評(píng)論 (0)編輯 收藏

                 Java語(yǔ)言編程中更新XML文檔的四種方法。第一種方法是直接讀寫XML文件。第二種方法是使用Apache Crimson的XmlDocument類,這種方法極為簡(jiǎn)單,使用方便,如果你選用Apache Crimson作為XML解析器,那么不妨使用這種方法,不過(guò)這種方法似乎效率不高(源于效率低下的Apache Crimson),另外,高版本的JAXP或者是Java XML Pack、JWSDP不直接支持Apache Crimson,亦即這種方法不通用。第三種方法是使用JAXP的XSLT引擎(Transformer類)來(lái)輸出XML文檔,這種方法也許是標(biāo)準(zhǔn)的方法 了,使用起來(lái)十分靈活,特別是可以自如控制輸出格式,我們推薦采用這種方法。第四種方法是第三種方法的變種,采用了Xalan XML Serializer,引入了串行化操作,對(duì)于大量文檔的修改/輸出有優(yōu)越性,可惜的是要重復(fù)設(shè)置XSLT引擎的屬性和XML Serializer的輸出屬性,比較麻煩,而且依賴于Apache Xalan和Apache Xerces技術(shù),通用性略顯不足。除此之外,實(shí)際上應(yīng)用別的API(比如dom4j、JDOM、Castor、XML4J、Oracle XML Parser V2)也有很多辦法可以更新XML文檔。

          概念介紹
                  Xerces/Crimson是XML解析器,Xalan是XSLT處理器,xml-apis.jar實(shí)際上是JAXP。
                  Apache Crimson的前身是Sun Project X Parser, 至今Apache Crimson的很多代碼都是從X Parser中直接移植過(guò)來(lái)的。早期的JAXP是和X Parser捆綁在一起的。后來(lái)的 JAXP和Apache Crimson捆綁在一起,比如JAXP 1.1。最新的JAXP 1.2 EA(Early Access)改弦更張,采用性能更好的Apache Xalan和Apache Xerces分別作為XSLT處理器和XML解析器,不能直接支持Apache Crimson了。
                  dom4j(dom4j.jar)是一個(gè)Java的XML API,類似于jdom,用來(lái)讀寫XML文件的。dom4j是一個(gè)非常非常優(yōu)秀的Java XML API,具有性能優(yōu)異、功能強(qiáng)大和極端易用使用的特點(diǎn),同時(shí)它也是一個(gè)開放源代碼的軟件,可以在SourceForge上找到它。在IBM developerWorks上面可以找到一篇文章,對(duì)主流的Java XML API進(jìn)行的性能、功能和易用性的評(píng)測(cè),dom4j無(wú)論在那個(gè)方面都是非常出色的。

          posted @ 2008-03-19 10:27 bluoy 閱讀(1985) | 評(píng)論 (0)編輯 收藏

          .NET垃圾收集器的過(guò)去、現(xiàn)在和未來(lái)(一)

          Patrick Dussud介紹:
          Patrick Dussud在微軟工作了11年,曾經(jīng)負(fù)責(zé)VBA、Jscript、MS Java等語(yǔ)言運(yùn)行時(shí)的垃圾收集器(Garbage Collector)的設(shè)計(jì),目前負(fù)責(zé).NET CLR垃圾收集器的設(shè)計(jì)。他是.NET CLR的架構(gòu)師,WinFX的首席架構(gòu)師,Windows架構(gòu)師組的成員。
          在微軟之前,Patrick是德州儀器(TI)Explorer工作站系統(tǒng)的主要設(shè)計(jì)人,Lucid公司Energize產(chǎn)品的首席架構(gòu)師。

          關(guān)鍵內(nèi)容摘要

          1. 微管理 / 內(nèi)存的顯式管理 ---  手動(dòng)內(nèi)存管理(new/delete)
                  你必須保證在釋放之前內(nèi)存沒(méi)有被別人使用,如果你把內(nèi)存給了別人,往往你就不確定應(yīng)該何時(shí)釋放內(nèi)存了。當(dāng)你釋放了內(nèi)存,不知道別人正在使用這塊內(nèi)存時(shí),就產(chǎn)生了程序崩潰的問(wèn)題。所以,當(dāng)你顯式進(jìn)行“new”和“delete”時(shí),內(nèi)存管理是一個(gè)復(fù)雜的問(wèn)題,并且,此時(shí)你的代碼不可組合。要么你必須確定對(duì)自己的內(nèi)存有完全的控制,因此,要達(dá)到這種完全隔離的目的,你必須在將內(nèi)存?zhèn)鬟f給別的模塊時(shí)進(jìn)行完全拷貝,這樣,別的模塊就只對(duì)這個(gè)完全拷貝的內(nèi)存負(fù)責(zé)。要么你就得在某個(gè)地方形成對(duì)整個(gè)內(nèi)存池的統(tǒng)一的管理,這就是自動(dòng)化內(nèi)存管理,這就是垃圾收集器的工作。

          2. 對(duì)象終止器的調(diào)用時(shí)機(jī)由垃圾收集器決定,這些對(duì)象的析構(gòu)函數(shù)被調(diào)用的先后順序是無(wú)法預(yù)先確定的。提出了“關(guān)鍵終止化對(duì)象”的概念。當(dāng)有一系列對(duì)象需要終止化時(shí),關(guān)鍵終止化對(duì)象最后被終止化,直到上層對(duì)象干完工作前。

          3.  工作機(jī)理: 垃圾收集器首先遍歷所有的棧和靜態(tài)變量,然后返回最初的樹集。然后遍歷樹集對(duì)程序能夠到達(dá)的每一個(gè)對(duì)象作標(biāo)記。此時(shí),我們就能逐個(gè)對(duì)象地檢查內(nèi)存,發(fā)現(xiàn)它被標(biāo)記了,好的,留下。沒(méi)有被標(biāo)記?喔,我們有一個(gè)垃圾了。

          4.  垃圾收集器的絕大部分速度和效率都來(lái)源于對(duì)回收策略的調(diào)整。通過(guò)保持內(nèi)存緊湊,形成緩存本地化,頁(yè)面本地化等等優(yōu)勢(shì),很可能其效率甚至高于傳統(tǒng)“new”和“delete” 操作,尤其是對(duì)于非常難以管理的服務(wù)器內(nèi)存來(lái)說(shuō)更是如此。

          posted @ 2008-03-13 21:26 bluoy 閱讀(356) | 評(píng)論 (0)編輯 收藏

          如下代碼:
          class A{
              public void foo(){print("aaaaa");}
          }

          class B extends A{
              public void foo(){print("bbbbb");}
          }

          如果想通過(guò)B的實(shí)例化變量來(lái)調(diào)用被override的父類的方法foo():

          B b = new B();

          在C++中(VC 6)可以兩種途徑;
          1.  ((A)b).foo();
          2.  A a = B();

          在java中類似做法則行不通,依然訪問(wèn)的是子類方法。
          而且,在java中好像達(dá)不到這個(gè)目的。

          posted @ 2008-03-06 10:34 bluoy 閱讀(1069) | 評(píng)論 (3)編輯 收藏

          web常用的功能性測(cè)試方法

                
                  1. 頁(yè)面鏈接檢查:每一個(gè)鏈接是否都有對(duì)應(yīng)的頁(yè)面,并且頁(yè)面之間切換正確。

                  2. 相關(guān)性檢查:刪除/增加一項(xiàng)會(huì)不會(huì)對(duì)其他項(xiàng)產(chǎn)生影響,如果產(chǎn)生影響,這些影響是否都正確。

                  3. 檢查按鈕的功能是否正確:如update、cancel、delete、save等功能是否正確。

                  4. 字符串長(zhǎng)度檢查:輸入超出需求所說(shuō)明的字符串長(zhǎng)度的內(nèi)容,看系統(tǒng)是否檢查字符串長(zhǎng)度,會(huì)不會(huì)出錯(cuò)。

                  5. 字符類型檢查:在應(yīng)該輸入指定類型的內(nèi)容的地方輸入其他類型的內(nèi)容(如在應(yīng)該輸入整型的地方輸入其他字符類型),看系統(tǒng)是否檢查字符類型,會(huì)否報(bào)錯(cuò)。

                  6. 標(biāo)點(diǎn)符號(hào)檢查:輸入內(nèi)容包括各種標(biāo)點(diǎn)符號(hào),特別是空格、各種引號(hào)、回車鍵。看系統(tǒng)處理是否正確。

                  7. 中文字符處理:在可以輸入中文的系統(tǒng)輸入中文,看會(huì)否出現(xiàn)亂碼或出錯(cuò)。

                  8. 檢查帶出信息的完整性:在查看信息和update信息時(shí),查看所填寫的信息是不是全部帶出,帶出信息和添加的是否一致。

                  9. 信息重復(fù):在一些需要命名,且名字應(yīng)該唯一的信息輸入重復(fù)的名字或ID,看系統(tǒng)有沒(méi)有處理,會(huì)否報(bào)錯(cuò),重名包括是否區(qū)分大小寫,以及在輸入內(nèi)容的前后輸入空格,系統(tǒng)是否作出正確處理。

                  10. 檢查刪除功能:在一些可以一次刪除多個(gè)信息的地方,不選擇任何信息,按”delete”,看系統(tǒng)如何處理,會(huì)否出錯(cuò);然后選擇一個(gè)和多個(gè)信息,進(jìn)行刪除,看是否正確處理。

                  11. 檢查添加和修改是否一致:檢查添加和修改信息的要求是否一致,例如添加要求必填的項(xiàng),修改也應(yīng)該必填;添加規(guī)定為整型的項(xiàng),修改也必須為整型。

                  12. 檢查修改重名:修改時(shí)把不能重名的項(xiàng)改為已存在的內(nèi)容,看會(huì)否處理,報(bào)錯(cuò)。同時(shí),也要注意,會(huì)不會(huì)報(bào)和自己重名的錯(cuò)。

                  13. 重復(fù)提交表單:一條已經(jīng)成功提交的紀(jì)錄,back后再提交,看看系統(tǒng)是否做了處理。

                  14. 檢查多次使用back鍵的情況:在有back的地方,back,回到原來(lái)頁(yè)面,再back,重復(fù)多次,看會(huì)否出錯(cuò)。

                  15. search檢查:在有search功能的地方輸入系統(tǒng)存在和不存在的內(nèi)容,看search結(jié)果是否正確。如果可以輸入多個(gè)search條件,可以同時(shí)添加合理和不合理的條件,看系統(tǒng)處理是否正確。

                  16. 輸入信息位置:注意在光標(biāo)停留的地方輸入信息時(shí),光標(biāo)和所輸入的信息會(huì)否跳到別的地方。

                  17. 上傳下載文件檢查:上傳下載文件的功能是否實(shí)現(xiàn),上傳文件是否能打開。對(duì)上傳文件的格式有何規(guī)定,系統(tǒng)是否有解釋信息,并檢查系統(tǒng)是否能夠做到。

                  18. 必填項(xiàng)檢查:應(yīng)該填寫的項(xiàng)沒(méi)有填寫時(shí)系統(tǒng)是否都做了處理,對(duì)必填項(xiàng)是否有提示信息,如在必填項(xiàng)前加* 

                  19. 快捷鍵檢查:是否支持常用快捷鍵,如Ctrl+C Ctrl+V Backspace等,對(duì)一些不允許輸入信息的字段,如選人,選日期對(duì)快捷方式是否也做了限制。

                  20. 回車鍵檢查:在輸入結(jié)束后直接按回車鍵,看系統(tǒng)處理如何,會(huì)否報(bào)錯(cuò)。

          posted @ 2008-01-11 09:55 bluoy 閱讀(197) | 評(píng)論 (0)編輯 收藏

          調(diào)整完/usr的掛載點(diǎn)后,出現(xiàn)了一個(gè)奇怪的現(xiàn)象,原來(lái)正確的系統(tǒng)時(shí)鐘現(xiàn)在出故障了,提前了8個(gè)小時(shí)。
          鼓掌現(xiàn)象具體表現(xiàn)為:每次啟動(dòng)系統(tǒng),ubuntu會(huì)用BIOS的時(shí)間+8后作為系統(tǒng)時(shí)鐘,同時(shí)會(huì)把新的時(shí)間重新同步到BIOS中。所以每啟動(dòng)一次,時(shí)間就會(huì)快進(jìn)8小時(shí)。很是怪異。
          網(wǎng)上一通google才搞定。

          原因是因?yàn)?usr的掛載時(shí)間被滯后了,由于/etc/localtime(時(shí)區(qū)信息)是連接到/usr/share/zoneinfo/下的某個(gè)設(shè)定好的時(shí)區(qū)文件。在系統(tǒng)獲取時(shí)區(qū)信息時(shí)/usr尚未掛載,所以系統(tǒng)始終就錯(cuò)了。

          修復(fù)辦法很簡(jiǎn)單:
          1.  rm /etc/localtime(取消原來(lái)的符號(hào)連接)
          2. 把/usr/share/zoneinfo/下的某個(gè)設(shè)定好的時(shí)區(qū)文件copy到/etc/localtime.
          3. 重新啟動(dòng),故障消除。

          相關(guān)概念:
          UTC(Universal Time Coordinated)  = GMT  (Greenwich Mean Time)
          hwclock :   query and set the hardware clock (RTC)
          hwclock通過(guò)/etc/default/rcS的UTC(=y(tǒng)es/no)來(lái)認(rèn)定BIOS時(shí)鐘是UTC還是localtime。

          參考文章:
          http://blog.chinaz.com/u1/5830/archives/2006/36628.shtml

          posted @ 2007-11-13 12:09 bluoy 閱讀(294) | 評(píng)論 (0)編輯 收藏

          昨天由于ubuntu的/分區(qū)空間緊張,決定把/usr掛載到別的分區(qū)。
          掛載步驟(root權(quán)限執(zhí)行):
          1.   init  1  -- 切換到單用戶模式。
          2.   cp -ax /usr/*  /mnt/tmp  (tmp為新的/usr分區(qū))。 -- 拷貝現(xiàn)在/usr下的內(nèi)容到待切換的分區(qū)。
          3.   ls -l /dev/disk/by-uuid    -- 查看分區(qū)的UUID。
          4.   修改/etc/fstab中/usr的掛載方式,掛接到新的/usr分區(qū)。
          5.   mv /usr /usr.old   -- 重命名現(xiàn)有的/usr為/usr.old, 為第6步做準(zhǔn)備,重啟動(dòng)后可以刪除之。
          6.   mkdir /usr   -- 創(chuàng)建新的/usr掛載點(diǎn),啟動(dòng)時(shí)自動(dòng)掛載/usr分區(qū)到此處。
          7.   restart

          posted @ 2007-11-13 11:49 bluoy 閱讀(5738) | 評(píng)論 (5)編輯 收藏

          /home 分區(qū)是最常移動(dòng)的分區(qū)之一。某些時(shí)候,/home 中的全部空間都用完了,而且需要增加一個(gè)硬盤驅(qū)動(dòng)器。另一些時(shí)候,/home 被設(shè)置為根分區(qū)的一部分,為了提高性能或便于備份,可能需要將它移動(dòng)到別的地方。我會(huì)針對(duì)每種情況說(shuō)明如何安全有效地移動(dòng) /home。

          please visit the address:
          http://www.ibm.com/developerworks/cn/linux/l-tip-prompt/tip05/index.html

          posted @ 2007-11-09 15:52 bluoy 閱讀(148) | 評(píng)論 (0)編輯 收藏

          網(wǎng)上常見(jiàn)的推薦是tora. 地址: http://sourceforge.net/projects/tora/
          但由于License關(guān)系,二進(jìn)制版本剔除了對(duì)oracle的providor. 所以需要下載源碼自己編譯。
          感覺(jué)比較麻煩。

          最近又找到一個(gè)比較好的東東-- Aqua Data Studio。 (http://www.aquafold.com/index.html)
          而且也有免費(fèi)版本。
          下載試用了一下,非常方便易用。
          推薦給有此需要者。

          posted @ 2007-11-07 11:49 bluoy 閱讀(2505) | 評(píng)論 (0)編輯 收藏

          如何臨時(shí)增加交換空間。

          1.產(chǎn)生一個(gè)64M的空文件

          #dd if=/dev/zero of=/swapfile bs=1024 count=65536

          2.初始化該文件為交換文件:

          mkswap /swapfile 65536

          sync

          3.激活這個(gè)交換文件:

          swapon /swapfile

          posted @ 2007-11-06 14:03 bluoy 閱讀(305) | 評(píng)論 (0)編輯 收藏

          The follow statement execute error using 9i driver(Oracle JDBC Driver version - 9.0.2.0.0).
          throw UncategorizedSQLException(Invalid Column Type Exception), 
          errorcode: 17004.
          Upgrade to Oracle JDBC Driver version - 10.2.0.1.0, it is OK.

          Example:

          ......
          PreparedStatement pst = cn.prepareStatement("select sysdate from dual where 1=?");
          pst.setNull(index,  java.sql.Types.NULL);   -------- throw exception!!
          ......




          posted @ 2007-10-09 19:39 bluoy 閱讀(912) | 評(píng)論 (0)編輯 收藏

          Using the JDBC 8i, 9iR1, Oracle's DATE datatype is mapped to the "java.sql.Timestamp" class. However, the new "ojdbc14.jar" driver maps DATE to "java.sql.Date", and "java.sql.Date" only holds a date (without a time), whereas "java.sql.Timestamp" holds both a date and a time.




          Subject: JDBC 920x Date/TimeStamp mapping
          Type: BULLETIN
          Status: UNDER_EDIT
          Content Type: TEXT/PLAIN
          Creation Date: 29-JUL-2003
          Last Revision Date: 04-OCT-2004


          PURPOSE
          -------
             Clarify the use of oracle.jdbc.V8Compatible property flag
           
          SCOPE & APPLICATION
          -------------------
          JDBC 920x Date/TimeStamp mapping is different from JDBC 8i, 9iR1.
          <TITLE FOR MAIN ARTICLE TEXT>
          -----------------------------
          Summary of  features afftected by oracle.jdbc.V8Compatible.
           
          As of 9.2.0.1.0 Oracle realigned its DATE type with the java.sql.Types.DATE type.
          Prior to this
          java.sql.DATE and  java.sql.TIMESTAMP were mapped to java.sql.Types.TIMESTAMP.
           
          This mapping change applies to JDBC default mapping (i.e when getObject() is
          used for Date column.
           
          example:
          select sysdate from dual;
          ...
          while (rset.next ())  {
          System.out.println("getObject for sysdate  : " +
          rset.getObject(1).getClass().getName());
          System.out.println("getDate for sysdate :" +
          rset.getDate(1).getClass().getName());
          System.out.println("getTimetamp for sysdate :" +
          rset.getTimestamp(1).getClass().getName());
          }
           
          Prior to 9201, this will return
          getObject for sysdate  : java.sql.Timestamp      <<<<
          getDate for sysdate :java.sql.Date
          getTimetamp for sysdate :java.sql.Timestamp
           
          As of 9201 onward the following will be returned
           
          getObject for sysdate  : java.sql.Date        <<<<<
          getDate for sysdate :java.sql.Date            >> no change
          getTimetamp for sysdate :java.sql.Timestamp   >> no change
           
           
           
          Note: java.sql.Date has no time portion whereas java.sql.Timestamp does.
           
           
          With this change in Datatype mapping, some application will fail and/or generate
          incorrect results when JDBC driver is upgraded from 8i/ 9iR1 to 920x JBDC driver.
          To maintain compatibility and keep applications working after upgrade, a compatibility flag was
          Provided.  Developers now have some options:
           
          1>
          Use oracle.jdbc.V8Compatible flag.
           
          JDBC Driver does not detect database version by default.
          To change the compatibility flag for handling TIMESTAMP datatypes,
          connection property 'oracle.jdbc.V8Compatible' can be set to
          'true' and the driver behaves as it behaved in 8i, 901x, 9200
          (with respect to TIMESTAMPs).
          By default the flag is set to 'false'. In OracleConnection constructor
          the driver obtains the server version and set the compatibility flag
          Appropriately.
           
          java.util.Properties prop = new java.util.Properties ();
          prop.put ("oracle.jdbc.V8Compatible", "true");
          prop.put ("user", "scott");
          prop.put ("password", "tiger");
          String url ="jdbc:oracle:thin:@host:port:sid";
          Connection conn = DriverManager.getConnection (url,prop);
           
           
           
          With JDBC 10.1.0.x, in instead of the connection property, the following system
          property can be useed
          java -Doracle.jdbc.V8Compatible=true .....
           
           
           
          Note: This flag is a client only flag that governs the Timestamp and Date mapping.
          It does not affect any Database feature.
           
           
           
          2> use set/getDate and set/getTimestamp   when dealing with Date and TimeStamp column datatype accordingly.
          9i server  supports both Date and Timestamp column types
           
          DATE is mapped to  java.sql.Date and TIMESTAMP is mapped to java.sql.Timestamp
           
          I> using setTimestamp
           
          PreparedStatement pstmt = conn.prepareStatement(
          "SELECT count(*) from  tstable where tscol between ? and ?");
          // tscol of type Timetamp (or it can be Date)
           
          String s = new String("2003-01-14 10:00:00.000000000");
          Timestamp ts1 = Timestamp.valueOf(s);
          pstmt.setTimestamp(1, ts1); // Timestamp
           
          String s2 = new String("2003-01-16 10:00:00.000000000");
          Timestamp ts2 = Timestamp.valueOf(s2);
          pstmt.setTimestamp(2, ts2); // Timestamp
          ...
           
           
          II>using setDate
           
          PreparedStatement pstmt = conn.prepareStatement(
          "SELECT count(*) from  tstable where datecol between ? and ?");
          // datecole of type Date
           
          /*
          pstmt.setDate(1,new java.sql.Date(System.currentTimeMillis()));
          pstmt.setDate(2,new java.sql.Date(System.currentTimeMillis()));
          */
           
          SimpleDateFormat start_dt_in1 = new SimpleDateFormat("2002-09-18 00:00:00");
          SimpleDateFormat start_dt_in2 = new SimpleDateFormat("2003-09-18 00:00:00");
          pstmt.setDate(1,start_dt_in1);
          pstmt.setDate(2,start_dt_in2);
           
           
           
          Summary of  features afftected by oracle.jdbc.V8Compatible.
           
          Is backward compatible (with oracle.jdbc.V8Compatible)?
          
           
           
          * Examples:
          ..
          The following will fail   when using JDBC 9iR1, 9iR2 connecting 817 server since the
          817 did not support Timestamp
           
           
          Connection conn = DriverManager.getConnection(url, "scott",  "tiger");
          // Prepare a statement to cleanup the emp table
          Statement  stmt = conn.createStatement();
          try {
          stmt.execute("delete from EMP where EMPNO = 1");
          } catch (SQLException e) {
          }
          try {
          stmt.execute("INSERT INTO EMP (EMPNO, ENAME, HIREDATE) VALUES (1, 
          'ALI', {ts '2003-04-14 14:19:24.94'})");
          } catch (SQLException e) {
          e.printStackTrace();
          }
           
          Error : Exception in thread "main" java.sql.SQLException: ORA-00904: invalid column name
           
          Solution you need
          1> fix for Bug 2640192 (included in 9204)
          2> oracle.jdbc.V8Compatible", "true"
           
           
           
          In earlier versions of JDBC drivers  SQL FUNCTION "TS" was mapped to "to_date" .   So, the query
           
          select {ts '2002-10-18 18:02:00'} from dual;
          was translated by JDBC to,
          select TO_DATE ('2002-10-18 18:02:00',  'YYYY-MM-DD HH24:MI:SS') from dual;
           
           
          With 9i Timestamp is supported in the database and also by 9203 JDBC Drivers.
          So the query
           
          select {ts '2002-10-18 18:02:00'} from dual;
           
          is now translated  by JDBC to
           
          select TO_TIMESTAMP('2002-10-18 18:02:00', 'YYYY-MM-DD HH24:MI:.SS.FF') from dual;
           
           
          Known issues:  There is some performances issue when set/getTimestamp
          Bug 3037615
          Bug 2770935
          These bugs are very likely duplicate.
           
           
          The following code will no longer work with 9203+ unless V8 flag is set to true
           
          Timestamp start_dt_in = Timestamp.valueOf("2002-09-18 00:00:00");
          Timestamp now_period_start_dt ;
          PreparedStatement stmt = null;
          ResultSet rs = null;
           
          System.out.println("start_dt_in="+  start_dt_in );
           
          try {
          stmt = conn.prepareStatement( "SELECT TRUNC(?) FROM DUAL" );
          stmt.setTimestamp( 1, start_dt_in );
          rs = (OracleResultSet) stmt.executeQuery();
          if ( rs.next() ) {
          now_period_start_dt = rs.getTimestamp( 1 );
          System.out.println("Curr Period Start="+  now_period_start_dt );
          }
           
           
          will generate
          Exception in thread "main" java.sql.SQLException:
          ORA-932: inconsistent datatypes
           
           
          Reason : trunc ( )  supports Date columns and does not support  Timestamp  (this is an RDBMS issue).
          So, you need to set the V8 flag to true
           
          Another bug that changed the Date/Timetamp mapping is  2428427 to comly with
          J2EE 1.3 CTS.  This was fixed in 9014 and it specific to classesdmx*.zip/jar
          (the *dms* jar filed mainly used by iAS/OC4J).  These *dms* jar files, by the
          default value for oracle.jdbc.J2EE13Compliant  is true.  in classes111.zip
          classes12.jar and ojdbc14.jar/zip the default is false.
           
          One can toggel this flag  true/false by
           
          java -Doracle.jdbc.J2EE13Compliant=true|false
           
           
          example of of sample runs:
           
          query used :"select sysdate from dual"
          classes12dms.jar used.
           
           
          Driver Version      Object Type
          ==============      ===========
          9.0.1.3.0         java.sql.Timestamp >> fix for 2428427 NOT included
          9.0.1.4.0         java.sql.Date   >> fix for 2428427 INCLUDED
          9.0.1.5.0         java.sql.Date   >> fix for 2428427 INCLUDE
           
          In JDBC 9014+ ,to keep older (9013) behavior  simply run the application with
           
           
          $java -Doracle.jdbc.J2EE13Compliant=false .....
           
           
          However please note that J2EE 1.3 CTS require that Date to mapped to
          java.sql.Date.
          

          posted @ 2007-10-09 19:16 bluoy 閱讀(1126) | 評(píng)論 (0)編輯 收藏

          我們知道,在Struts 1.0中,我們只能在web.xml中為ActionServlet指定一個(gè)配置文件,這對(duì)于我們這些網(wǎng)上的教學(xué)例子來(lái)說(shuō)當(dāng)然沒(méi)什么問(wèn)題,但是在實(shí)際的應(yīng)用開發(fā)過(guò)程中,可能會(huì)有些麻煩。因?yàn)樵S多開發(fā)人員都可能同時(shí)需要修改配置文件,但是配置文件只能同時(shí)被一個(gè)人修改,這樣肯定會(huì)造成一定程度上的資源爭(zhēng)奪,勢(shì)必會(huì)影響開發(fā)效率和引起開發(fā)人員的抱怨。

          在Struts 1.1中,為了解決這個(gè)并行開發(fā)的問(wèn)題,提出了兩種解決方案:

          1. 多個(gè)配置文件的支持
          2. 模塊的支持

           

          支持多個(gè)配置文件,是指你能夠?yàn)锳ctionServlet同時(shí)指定多個(gè)xml配置文件,文件之間以逗號(hào)分隔,比如Struts提供的MailReader演示例子中就采用該種方法。

          
                      <!-- Action Servlet Configuration -->
                      <servlet>
                      <servlet-name>action</servlet-name>
                      <servlet-class>
                          org.apache.struts.action.ActionServlet
                      </servlet-class> <init-param> <param-name>config</param-name> <param-value>
          /WEB-INF/struts-config.xml,
          /WEB-INF/struts-config-registration.xml
          </param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>

          這種方法可以很好地解決修改沖突的問(wèn)題,不同的開發(fā)人員可以在不同的配置文件中設(shè)置自己的Action、ActionForm等等(當(dāng)然不是說(shuō)每個(gè)開發(fā)人員都需要自己的配置文件,可以按照系統(tǒng)的功能模塊進(jìn)行劃分)。但是,這里還是存在一個(gè)潛在的問(wèn)題,就是可能不同的配置文件之間會(huì)產(chǎn)生沖突,因?yàn)樵贏ctionServlet初始化的時(shí)候這幾個(gè)文件最終還是需要合并到一起的。比如,在struts-config.xml中配置了一個(gè)名為success的<forward>,而在struts-config-registration.xml中也配置了一個(gè)同樣的<forward>,那么執(zhí)行起來(lái)就會(huì)產(chǎn)生沖突。

          為了徹底解決這種沖突,Struts 1.1中引進(jìn)了模塊(Module)的概念。一個(gè)模塊就是一個(gè)獨(dú)立的子系統(tǒng),你可以在其中進(jìn)行任意所需的配置,同時(shí)又不必?fù)?dān)心和其它的配置文件產(chǎn)生沖突。因?yàn)榍懊嫖覀冎v過(guò),ActionServlet是將不同的模塊信息保存在不同的ModuleConfig對(duì)象中的。要使用模塊的功能,需要進(jìn)行以下的準(zhǔn)備工作:

          1、為每個(gè)模塊準(zhǔn)備一個(gè)配置文件

          2、配置web.xml文件,通知控制器

          決定采用多個(gè)模塊以后,你需要將這些信息告訴控制器,這需要在web.xml文件進(jìn)行配置。下面是一個(gè)典型的多模塊配置:

          
                      <init-param>
                      <param-name>config</param-name>
                      <param-value>
                          /WEB-INF/struts-config.xml
                      </param-value> </init-param> <init-param> <param-name>config/customer</param-name> <param-value>
                          /WEB-INF/struts-config-customer.xml
                      </param-value> </init-param> <init-param> <param-name>config/order</param-name> <param-value>
                          /WEB-INF/struts-config-order.xml
                      </param-value> </init-param>

          要配置多個(gè)模塊,你需要在原有的一個(gè)<init-param>(在Struts 1.1中將其對(duì)應(yīng)的模塊稱為缺省模塊)的基礎(chǔ)之上,增加模塊對(duì)應(yīng)的<init-param>。其中<param-name>表示為config/XXX的形式,其中XXX為對(duì)應(yīng)的模塊名,<param-value>中還是指定模塊對(duì)應(yīng)的配置文件。上面這個(gè)例子說(shuō)明該應(yīng)用有三個(gè)模塊,分別是缺省模塊、customer和order,它們分別對(duì)應(yīng)不同的配置文件。

          3、準(zhǔn)備各個(gè)模塊所需的ActionForm、Action和JSP等資源

          但是要注意的是,模塊的出現(xiàn)也同時(shí)帶來(lái)了一個(gè)問(wèn)題,即如何在不同模塊間進(jìn)行轉(zhuǎn)發(fā)?有兩種方法可以實(shí)現(xiàn)模塊間的轉(zhuǎn)發(fā),一種就是在<forward>(全局或者本地)中定義,另外一種就是利用org.apache.struts.actions.SwitchAction。

          下面就是一個(gè)全局的例子:

          
                      ...
                      <struts-config>
                      ...
                      <global-forwards>
                      <forward name="toModuleB"
                      contextRelative="true"
                      path="/moduleB/index.do"
                      redirect="true"/>
                      ...
                      </global-forwards>
                      ...
                      </struts-config>
                      

          可以看出,只需要在原有的path屬性前加上模塊名,同時(shí)將contextRelative屬性置為true即可。此外,你也可以在<action>中定義一個(gè)類似的本地<forward>。

          
                      <action-mappings>
                      <!-- Action mapping for profile form -->
                      <action path="/login"
                      type="com.ncu.test.LoginAction"
                      name="loginForm"
                      scope="request"
                      input="tile.userLogin"
                      validate="true">
                      <forward name="success" contextRelative="true" path="/moduleA/login.do"/>
                      </action>
                      </action-mappings>
                      

          如果你已經(jīng)處在其他模塊,需要轉(zhuǎn)回到缺省模塊,那應(yīng)該類似下面這樣定義,即模塊名為空。

          
                      <forward name="success" contextRelative="true" path="/login.do"/>
                      

          此外,你也可以使用org.apache.struts.actions.SwitchAction,例如:

          
                      ...
                      <action-mappings>
                      <action path="/toModule"
                      type="org.apache.struts.actions.SwitchAction"/>
                      ...
                      </action-mappings>
                      ...
                      

          posted @ 2007-08-17 16:25 bluoy 閱讀(194) | 評(píng)論 (0)編輯 收藏

          Oracle的systimestamp的精度與OS有關(guān)。例如:
          select systimestamp from dual;

          基于XP的輸出:07-07-03 16:07:10.328000 +08:00
          基于Solaris的輸出:07-07-03 16:09:18.328156 +08:00


          所以,如果DB中的表以timestamp類型的字段作唯一主鍵的話,在PC上就會(huì)藏有隱患:主鍵不唯一,因?yàn)榫冉档土耍l繁的insert操作很有可能產(chǎn)生相同的主鍵。而在Solaris上這個(gè)可能性就很低了。

          這點(diǎn)在DB設(shè)計(jì)中還是需要加以考慮的。

          posted @ 2007-07-03 16:43 bluoy 閱讀(3283) | 評(píng)論 (1)編輯 收藏

          java.util.Arrays.asList的BUG

          jdk 1.4對(duì)java.util.Arrays.asList的定義,函數(shù)參數(shù)是Object[]。所以,在1.4中asList()并不支持基本類型的數(shù)組作參數(shù)。

          jdk 1.5中,java.util.Arrays.asList的定義,函數(shù)參數(shù)是Varargs, 采用了泛型實(shí)現(xiàn)。同時(shí)由于autoboxing的支持,使得可以支持對(duì)象數(shù)組以及基本類型數(shù)組。

          但在使用過(guò)程中發(fā)現(xiàn)jdk1.5中存在一個(gè)BUG。就是等參數(shù)為基本類型的數(shù)組時(shí),函數(shù)的行為發(fā)生了變異:它不是把這個(gè)數(shù)組轉(zhuǎn)換為L(zhǎng)ist,而是把這個(gè)數(shù)組整體作為返回List中的第一個(gè)元素,要取得轉(zhuǎn)換后的結(jié)果,得首先get(0)才行。

          到網(wǎng)上google了一下,Sun好像認(rèn)為這并不是個(gè)問(wèn)題。理由如下:
          Arrays.asList is now a vararg method, and the behavior is as intended:  asList(int[] ...)
          The Java generics implementation does not support non-reference type parameters.
          This is all standard Java 5.0 stuff.
          URL:http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6353471

          雖然如此,但因此函數(shù)的行為就可能產(chǎn)生了歧義,對(duì)調(diào)用者還是會(huì)產(chǎn)生誤導(dǎo)的,我認(rèn)為這終歸還應(yīng)該是個(gè)問(wèn)題的,如能解決是最好的了。

          posted @ 2007-07-03 14:55 bluoy 閱讀(895) | 評(píng)論 (0)編輯 收藏

          問(wèn)題:同事不小心把項(xiàng)目DB中的一個(gè)表的數(shù)據(jù)delete all了。DB版本oracle 10g。
          網(wǎng)上簡(jiǎn)單搜了一下,搞定。以下是過(guò)程:
          Oracle 10g開始,當(dāng)我執(zhí)行Drop Table時(shí),Oracle也會(huì)把被刪除的表放到數(shù)據(jù)庫(kù)回收站(Database Recyclebin)里。這樣我們就可以用flashback table命令恢復(fù)被刪除的表,語(yǔ)法:
             Flashback table 表名 to before drop;

          開始恢復(fù),執(zhí)行以下命令:
          flashback table tmm2076 TO TIMESTAMP to_timestamp('2007-05-22
          12:00:00','yyyy-mm-dd hh24:mi:ss')
          彈出ORA-08189錯(cuò)誤,需要執(zhí)行以下命令先:
          alter table tmm2076 enable row movement

          這個(gè)命令的作用是,允許oracle修改分配給行的rowid。

          然后再flashback,數(shù)據(jù)被恢復(fù)完畢。

          posted @ 2007-05-22 16:30 bluoy 閱讀(4107) | 評(píng)論 (2)編輯 收藏

          There's a field introspector written by a Velocity user in the Wiki. You can configure velocity.properties to reference this. It require velocity version 1.4.

          PublicFieldUberspect.java
          -------------------------------------------------------------------------------------------------------------
          /*
          * Copyright 2003-2004 The Apache Software Foundation.
          *
          * Licensed under the Apache License, Version 2.0 (the "License");
          * you may not use this file except in compliance with the License.
          * You may obtain a copy of the License at
          *
          *     http://www.apache.org/licenses/LICENSE-2.0
          *
          * Unless required by applicable law or agreed to in writing, software
          * distributed under the License is distributed on an "AS IS" BASIS,
          * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
          * See the License for the specific language governing permissions and
          * limitations under the License.
          */
          package org.apache.velocity.tools.generic.introspection;
          import java.lang.reflect.Array;
          import java.lang.reflect.Field;
          import org.apache.velocity.util.introspection.Info;
          import org.apache.velocity.util.introspection.UberspectImpl;
          import org.apache.velocity.util.introspection.VelPropertyGet;
          import org.apache.velocity.util.introspection.VelPropertySet;
          /**
          * Uberspect implementation that exposes public fields.
          * Also exposes the explicit "length" field of arrays.
          *
          * <p>To use, tell Velocity to use this class for introspection
          * by adding the following to your velocity.properties:<br />
          *
          * <code>
          * runtime.introspector.uberspect = org.apache.velocity.tools.generic.introspection.PublicFieldUberspect
          * </code>
          * </p>
          *
          * @author <a href="mailto:shinobu@ieee.org">Shinobu Kawai</a>
          * @version $Id: $
          */
          public class PublicFieldUberspect extends UberspectImpl
          {
          /**
          * Default constructor.
          */
          public PublicFieldUberspect()
          {
          }
          /**
          * Property getter - returns VelPropertyGet appropos for #set($foo = $bar.woogie).
          * <br />
          * Returns a special {@link VelPropertyGet} for the <code>length</code> property of arrays.
          * Otherwise tries the regular routine.  If a getter was not found,
          * returns a {@link VelPropertyGet} that gets from public fields.
          *
          * @param obj the object
          * @param identifier the name of the property
          * @param i a bunch of information.
          * @return a valid <code>VelPropertyGet</code>, if it was found.
          * @throws Exception failed to create a valid <code>VelPropertyGet</code>.
          */
          public VelPropertyGet getPropertyGet(Object obj, String identifier, Info i)
          throws Exception
          {
          Class clazz = obj.getClass();
          boolean isArray = clazz.isArray();
          boolean isLength = identifier.equals("length");
          if (isArray && isLength)
          {
          return new ArrayLengthGetter();
          }
          VelPropertyGet getter = super.getPropertyGet(obj, identifier, i);
          // there is no clean way to see if super succeeded
          // @see http://issues.apache.org/bugzilla/show_bug.cgi?id=31742
          try
          {
          getter.getMethodName();
          return getter;
          }
          catch (NullPointerException notFound)
          {
          }
          Field field = obj.getClass().getField(identifier);
          if (field != null)
          {
          return new PublicFieldGetter(field);
          }
          return null;
          }
          /**
          * Property setter - returns VelPropertySet appropos for #set($foo.bar = "geir").
          * <br />
          * First tries the regular routine.  If a setter was not found,
          * returns a {@link VelPropertySet} that sets to public fields.
          *
          * @param obj the object
          * @param identifier the name of the property
          * @param arg the value to set to the property
          * @param i a bunch of information.
          * @return a valid <code>VelPropertySet</code>, if it was found.
          * @throws Exception failed to create a valid <code>VelPropertySet</code>.
          */
          public VelPropertySet getPropertySet(Object obj, String identifier,
          Object arg, Info i) throws Exception
          {
          VelPropertySet setter = super.getPropertySet(obj, identifier, arg, i);
          if (setter != null)
          {
          return setter;
          }
          Field field = obj.getClass().getField(identifier);
          if (field != null)
          {
          return new PublicFieldSetter(field);
          }
          return null;
          }
          /**
          * Implementation of {@link VelPropertyGet} that gets from public fields.
          *
          * @author <a href="mailto:shinobu@ieee.org">Shinobu Kawai</a>
          * @version $Id: $
          */
          protected class PublicFieldGetter implements VelPropertyGet
          {
          /** The <code>Field</code> object representing the property. */
          private Field field = null;
          /**
          * Constructor.
          *
          * @param field The <code>Field</code> object representing the property.
          */
          public PublicFieldGetter(Field field)
          {
          this.field = field;
          }
          /**
          * Returns the value of the public field.
          *
          * @param o the object
          * @return the value
          * @throws Exception failed to get the value from the object
          */
          public Object invoke(Object o) throws Exception
          {
          return this.field.get(o);
          }
          /**
          * This class is cacheable, so it returns <code>true</code>.
          *
          * @return <code>true</code>.
          */
          public boolean isCacheable()
          {
          return true;
          }
          /**
          * Returns <code>"public field getter"</code>, since there is no method.
          *
          * @return <code>"public field getter"</code>
          */
          public String getMethodName()
          {
          return "public field getter";
          }
          }
          /**
          * Implementation of {@link VelPropertyGet} that gets length from arrays.
          *
          * @author <a href="mailto:shinobu@ieee.org">Shinobu Kawai</a>
          * @version $Id: $
          */
          protected class ArrayLengthGetter implements VelPropertyGet
          {
          /**
          * Constructor.
          */
          public ArrayLengthGetter()
          {
          }
          /**
          * Returns the length of the array.
          *
          * @param o the array
          * @return the length
          * @throws Exception failed to get the length from the array
          */
          public Object invoke(Object o) throws Exception
          {
          // Thanks to Eric Fixler for this refactor.
          return new Integer(Array.getLength(o));
          }
          /**
          * This class is cacheable, so it returns <code>true</code>.
          *
          * @return <code>true</code>.
          */
          public boolean isCacheable()
          {
          return true;
          }
          /**
          * Returns <code>"array length getter"</code>, since there is no method.
          *
          * @return <code>"array length getter"</code>
          */
          public String getMethodName()
          {
          return "array length getter";
          }
          }
          /**
          * Implementation of {@link VelPropertySet} that sets to public fields.
          *
          * @author <a href="mailto:shinobu@ieee.org">Shinobu Kawai</a>
          * @version $Id: $
          */
          protected class PublicFieldSetter implements VelPropertySet
          {
          /** The <code>Field</code> object representing the property. */
          private Field field = null;
          /**
          * Constructor.
          *
          * @param field The <code>Field</code> object representing the property.
          */
          public PublicFieldSetter(Field field)
          {
          this.field = field;
          }
          /**
          * Sets the value to the public field.
          *
          * @param o the object
          * @param value the value to set
          * @return always <code>null</code>
          * @throws Exception failed to set the value to the object
          */
          public Object invoke(Object o, Object value) throws Exception
          {
          this.field.set(o, value);
          return null;
          }
          /**
          * This class is cacheable, so it returns <code>true</code>.
          *
          * @return <code>true</code>.
          */
          public boolean isCacheable()
          {
          return true;
          }
          /**
          * Returns <code>"public field setter"</code>, since there is no method.
          *
          * @return <code>"public field setter"</code>
          */
          public String getMethodName()
          {
          return "public field setter";
          }
          }
          }
          


          See
          http://wiki.apache.org/jakarta-velocity/PublicFieldUberspect

          posted @ 2007-05-18 10:10 bluoy 閱讀(276) | 評(píng)論 (0)編輯 收藏

          主站蜘蛛池模板: 嘉禾县| 屏东市| 永兴县| 赤壁市| 安乡县| 贵阳市| 松滋市| 东宁县| 益阳市| 朝阳区| 太原市| 云龙县| 东乌| 康保县| 泰安市| 丽水市| 樟树市| 通辽市| 连山| 维西| 安岳县| 双峰县| 江山市| 饶阳县| 叙永县| 宁阳县| 闽侯县| 错那县| 营口市| 黑水县| 和顺县| 高州市| 平陆县| 长乐市| 延庆县| 山西省| 阿拉善盟| 常宁市| 赤水市| 大足县| 海淀区|