|
2006年3月5日
Nokia在Maxis推廣Widget的時候告訴我Widget只能在S603.2上運行,所有S603.0系列手機可以通過軟件升級來支持這個新功能
Baidu一把,發現一大把人在說不能升級到S603.2,那不和Nokia的說法矛盾,Google一把Nokia software upgrade,找到一個自動更新程序
連上手機,可以自己幫你識別你的電話是否有最新軟件升級可用,花了10多分鐘就下載完114Mb的升級文件,然后又花了5分鐘刷機成功,開機后感覺速度沒有太大提升,反而鈴聲沒有以前清脆了,我一款短信鈴聲以前聽起來高音非常不錯,現在聽有爆音了.......馬上測試了下我自己開發的Widget,果然可以識別并提示安裝,裝好了就和普通的Symbian Application一樣,不錯,又有得玩了........
但是由于一直沒有查到S60的版本查看方法,所以我始終不知道我到底是不是升級到了3.2,如果有人知道,麻煩留言告訴一聲
好像國內對Adobe的新產品AIR反應還不多,我個人試用了下覺得其實用處還是很大的,于是我就拋磚引玉寫一篇相關介紹文章吧
AIR其實是一套框架和一個VM,它允許用戶把Javascript,HTML,CSS集成到統一的客戶端,在用戶桌面運行,避免了瀏覽器差異,并且實現了跨平臺的通用性,同時又對Javascript功能進行了很多擴展,比如讀取本地磁盤文件,做跨域的遠程訪問,使用多媒體文件等等(相信是flash的底層在支持),相對于兩年前的Flex,AIR在RIA領域無疑又是一個跨越,想象一下以后我們可以用JS+HTML+CSS來寫基于http的遠程且防火墻安全的C/S應用了,還是蠻爽吧
Demo在這里:http://labs.adobe.com/showcase/air/?promoid=BJXTF
用JS來寫應用的文檔在這里:http://livedocs.adobe.com/labs/air/1/devappshtml/
Adobe AIR出新版SDK后,出乎意料的是很多之前的Demo不能跑了,會出"parsing disallowed",原因就是adobe換用了新的安全框架,禁止掉了Javascript中某些可能對其框架做出安全威脅的API,比如說JSON的命根--eval
Adobe的官方解釋是在AIR2禁止掉了類似eval這種動態代碼加載技術在其Application sandbox中的運行,解決辦法是把你有eval的應用移到Browse sandbox中執行,所謂的Browse sandbox意思是你的應用主頁面是通過application.xml中配置的根頁面來用iframe引入的,在iframe引入的頁面中你就可以做eval,而把其他如跨域查詢等AIR提供的高級API操作放到根頁面中去做,然后通過一個parent/childSandboxBridge來做互相引用和傳遞數據的橋梁,但是同時你在iframe中的js也不能直接使用AIR所提供的一些高級API,比如air.trace().原文的解釋在這里
,Adobe甚至還寫了一篇文章來鼓吹這種方式其實更符合設計模式--根頁面負責數據傳遞,iframe頁面負責業務邏輯.但是無論如何這篇文章作為Browse sandbox的入門來講還是很值得細讀的
于是結合自己當前的實際需要,我寫了一個批量查詢airasia.com機票的小工具,因為airasia從來都是打廣告說從多久到多久,從那里飛到那里才幾塊MYR起! 就是這個"起"字相當關鍵......直接造成每次我去查的時候發現因為"已經快滿坐"了,所以價格和平時的一樣,甚至更高,聽同事說他們都是先一天一天去查看哪天便宜就趕快預定,太辛苦了吧,那我要查2007-11-05到2008-01-31日的機票要花多少時間啊,而且不查到最后一天還不知道是不是最便宜的,嘲笑他們原始之后我就決定自己寫個工具來查
所以我寫的第一個AIR應用就是這個AirAsiaTicketsSearch,可以批量查詢某個時間段去和某個時間段回的所有機票,并且把機票價格用jQuery.tablesort給排序出來,并且用jQuery.tablesort.page做了分頁(說句題外話,jQuery的tablesort確實很強大,但是在排序"1,280.00 CNY"這種數據的時候還是有問題).另外開發環境值得一說,無論是eclipse+aptana或者aptana standalone都一樣的,aptana就是一個Eclipse的RCP,關鍵就是aptana真的是很好用的工具,目前不僅支持AIR,而且還支持開發Apple iPhone的應用,只是專業版要收費.....
后面給出截圖,結果發現昨天還有295.99的機票,到了今天就漲到349.99了-_-!

幾個月前就想弄明白什么是閉包,聽名字多神奇,而且犀牛書上好像也沒有講到,baidu出來的結果倒是很多很準確,但是看著那些牛人們翻譯的英文文章,講了上千字我還是沒有明白什么是閉包,遇到復雜的地方沒法翻譯還只能引用原文來解釋,本來我的FF受某個插件影響開CSDN不僅慢還會停止響應10多秒,我都是忍痛點下CSDN的連接,結果看到這種垃圾文章真是讓人憤怒,寫了一大堆,最后還是不能讓人明白他到底想要解釋什么是閉包,還是炫耀他對技術的理解,還是要滿足他對翻譯的狂熱.
結果今天終于看到一篇 Morris Johns的文章,用了不到5分鐘就把閉包是什么講的清清楚楚,比如文章中有一句話:
In JavaScript, if you use the function
keyword inside another function, you are creating a closure.
媽的,還有比這更簡單的解釋嗎,為什么那些國內所謂的牛人就是寫不出這種平實的話,就非要浪費自己和別人的時間講一堆貌似浮云的定義,我覺得他們真的該思考下自己寫技術文章的目的,是為了在傳遞知識,還是在滿足自己的虛榮,如果是后者,建議直接在Tag中注明"自慰貼",免得浪費大家的時間.
在后面的文章中,作者列舉了很多生動的例子,每個例子后面的解釋都非常平實,沒有任何為了表現自己能力的華麗辭藻,通過他的例子,我很快理解的閉包的特點,可以用來做什么,前后不到30分鐘,回想我幾個月前光是找合適的解釋就找了近一個小時.
當我對閉包的特點已經諳熟于心后,作者再開始講一些抽象的定義,讓人感覺沒有一點障礙,就如作者自己的話:
If everything seems completely unclear then
the best thing to do is to play with the examples. Reading an explanation is
much harder than understanding examples.
My explanations of closures and stack-frames etc are not technically correct
- they are gross simplifications intended to help understanding. Once the
basic idea is grokked, you can pick up the details later.
最后給出那篇文章的地址,相信不懂閉包的人也能像我一樣很快就理解,同時也希望大家看完后別忘了別人踏踏實實寫技術文章的態度
http://www.javascriptkit.com/javatutors/closures.shtml
最近寫AJAX的應用遇到很多需要豐富的Javascript集合的地方,可惜javascript沒有Java的Collection那么強大的集合類,于是打算自己嘗試寫一個模擬Set的API,結果寫出來的模擬類和Set有點不同,有一個優勢--可以有序取單個對象,但也有一個劣勢,就是刪除單個對象需要遍歷該集合,由于我的應用不大可能用到單個刪除,所以我暫時還沒有想到一種數據結構可以實現不遍歷的單個對象刪除,又能滿足現有的API都高效完成,如果誰有更好的代碼來實現請回復
目前想到可以實現的方法:
add(o);
addAll(array)
contain(o);
get(int);
getAll();
sort(comparator); //傳進去的是一個fn,還沒有寫例子....
size();
remove();
reverse();
基本數據結構是兩個數組,一個是index數組,數組下標連續,用來存放第二個數組的下標,另一個是存放對象的數組,不連續,下標是對象的id或者對象中其他任何可以轉換成唯一Integer的Field(Set也要求放進去的對象必須要有hashCode嘛,不然沒法區別第一個和第二個)
實現的API:
function Collection(){
this.chain=new Array();
this.table=new Array();
}
Collection.prototype.get=function(i){
return this.table[this.chain[i]];
}
Collection.prototype.add=function(o){
this.table[o.id]=o;
this.chain.push(o.id);
}
Collection.prototype.addAll=function(array){
for(var _i=0;_i<array.length;_i++){
this.add(array[_i]);
}
}
Collection.prototype.contain=function(o){
if(this.table[o.id]){
return true;
}else{
return false;
}
}
Collection.prototype.getAll=function(){
tempList=new Array();
for(var _i=0;_i<this.chain.length;_i++){
tempList.push(this.table[this.chain[_i]]);
}
return tempList;
}
Collection.prototype.sort=function(comparator){
this.chain.sort(comparator);
}
Collection.prototype.remove=function(o){
var _var = this.chain;
for(var _i=0;i<this.chain.length;i++){
if(this.table[this.chain[_i]].id==o.id){
this.table[this.chain[_i]]=null;
this.chain.splice(_i,1);
return;
}
}
}
Collection.prototype.size=function(){
return this.chain.length;
}
Collection.prototype.reverse=function(){
this.chain.reverse();
}
目前還有一個addAll方法也是暫時沒有想到有什么不用遍歷的好的實現
前同事提供了一種完全和Set一樣的實現,效率滿高
function Map(){
this.obj = {};
this.count = 0;
}
Map.prototype.put = function(key, value){
var oldValue = this.obj[key];
if(oldValue == undefined){
this.count++;
}
this.obj[key] = value;
return oldValue;
}
Map.prototype.get = function(key){
return this.obj[key];
}
Map.prototype.remove = function(key){
var oldValue = this.obj[key];
if(oldValue != undefined){
this.count--;
delete this.obj[key];
}
return oldValue;
}
Map.prototype.size = function(){
return this.count;
}
function Set(getKey){
this.map = new Map();
this.getKey = getKey;
}
Set.prototype.add = function(value){
var key = this.getKey(value);
this.map.put(key, value);
}
Set.prototype.remove = function(value){
var key = this.getKey(value);
this.map.remove(key);
}
Set.protorype.getAll=function(){
tempArray=new Array();
for(var i in this.obj){
tempArray.push(i);
}
return tempArray;
}
Set.prototype.size = function(){
return this.map.size();
}
還有一個朋友的實現和我最初的差不多,但是remove方法相當有創意,用正則表達式來刪除
Collection.prototype.remove=function(o){
var _var = this.chain;
this.table[o.id]=null;
var re = new RegExp("(^["+o.id+"]$)|(^["+o.id+"][,])|([,]["+o.id+"]$)","g");
var s = "["+this.chain.toString().replace(re,"").replace(","+o.id+",",",")+"]";
this.chain=eval(s)
}
有人回復說需要添加做驗證,我覺得不必了,如果添加的值和之前的一樣就直接替換好了,如果希望不被replace,直接在添加新對象之前用contain判斷一次就可以了,畢竟在我的實現中已不是完全在模擬Set了,目前更傾向于設計一個更高效和強大的集合類
使用AJAX不可以跨域一直是一個麻煩的問題, 最近做AJAX框架時發現一種方法,不僅可以跨域,而且相比XHR可以省去很多解析XML的步驟, 后來居然發現GoogleMap的API就在用,非常驚喜,趕快分享一下
test.html <html> <title>Dynamic Script Object</title> <head/> <body> <div id="jsArea"> <script id="js" src=testa.js></script> </div> <br> <input type="button" value="test" onclick="testSrc()"> </body> </html> <script> //author:Kerwin.Weng //mail:hunteva@163.com function testSrc(){ var jsObj = document.getElementById("js"); var body = jsObj.parentNode; body.removeChild(jsObj); jsObj = null; var newJS=document.createElement("script"); newJS.id = "js"; newJS.src = "testb.js"; body.appendChild(newJS); jsArea.innerHTML="Asynchronous" } var jsArea = document.getElementById("jsArea"); </script>
testa.js document.write("This is A"); testb.js setTimeout(function(){jsArea.innerHTML="This is B,now imagine i'm a servlet";},100) 測試結果表明可以在不刷新頁面的情況下更新jsArea中的內容,如果我們把testb.js換成一個servlet會怎么樣 那不是可以在serverside直接寫數據或function給client用了嗎,完全不需要XHR來中轉,省去了不少麻煩,而且還可以實現跨域訪問 但是有兩點要注意,testb.js用document.write沒有作用,如果不用setTimeout,會直接讓我的IE7和IE6crush,具體原因不明,有牛人知道請告訴我 目前在FF2.0.0.4/Opera9.2/IE7/IE6下測試通過. 由于找了好久都不知道這種方式的官方名稱,并且很明顯這不Asynchronous JavaScript and XML,這里連XML和XmlHttp的影子都沒有, 所以為了稱呼方便我暫時叫它DSSO(DynamicSwitchScriptObject),當然這不是我發明的,Google不知道用了多久了,如果你知道準確的名字請麻煩告知我 現在我們比較下AJAX和DSSO的特點:
|
AJAX |
DSSO |
跨域訪問 |
不支持 |
支持 |
異步操作 |
支持 |
支持(body.appendChild后不需要等到完成才會繼續,當然完整的異步訪問需要另外的pattern來支持) |
數據載體 |
XML或JSON或TEXT |
可以直接由server寫成Javascript |
操作復雜性 |
需要解析XML或JSON |
可以直接使用 |
目前暫時想到這么多可以比的,期待大家的討論
我不得不承認,我從來沒有想象過同事會對我這么的好. cy知道我一個人剛來,家里沒有Internet,沒有TV,一個人在家會悶出病來,說周六正好是我生日,到時候帶我去KL的downtown逛逛, 可是后來這個計劃擱淺了,因為hh,ps,lp的加入,cy決定組織大家去附近的Putra jaya去運動運動..... 在離公司不遠的一個叫公主城的地方,我們吃著晚飯,計劃著第二天的安排,誰知道居然聊到了23點,我們吃了好大一堆東西,好消息是我發現我吃海鮮不會過敏了:D,而且我決定要學廣東話啦~~~~~~因為使用范圍實在太廣了,有中國人的地方就會有人說....... 于是生日這天我起的很早,到公司樓下等hh來接我,hh載著lp來,我們又一起去接cy,然后和ps匯合,他們說20分鐘左右的車程,原來好遠,換成是在國內糟糕的交通狀況,肯定不止一個小時,吃過早午飯(已經10點左右了),5人擠上ps的車前往Putra jaya 比我想象的近,也可能是馬來公路又寬,車又少,交通燈也少的原因,車速很快,我們很快就來到了馬來西亞政治宗教中心,一個花了全國納稅人的錢,但是不準華裔入住的城市Putra jaya, 先是去一個叫Botani的植物公園,因為在馬來西亞幾乎人人都有車,路上根本沒有給行人走的路,也沒有看到街上有自行車,所以他們很想騎自行車,所以來自自行車王國的我,肯定算是他們中的高手了:D 馬來西亞的太陽真的好曬,事實證明我后來又被曬傷了.....不過沒有在惠州嚴重.........但是我們玩得很開心; 之后,我們去附近家樂福吃飯,讓我驚訝的是,他們居然去給我買了一個小小的蛋糕,上面還插有一根蠟燭為我慶祝生日:) 滿感動得,原來之前關于友誼的某些想法是我錯了,不過我很高興發現我錯了; cy真的好厲害,是個人都會羨慕她的,比我還吃得多,一點都不胖,瘦得可以媲美日本明星.....ps很是自豪地介紹他家的蛇寵物,聽得我背后直冒冷汗; 飯后,在太陽比較和藹后,我們去一個湖邊劃船,我和cy坐的叫kaya,類似皮劃艇,不過是塑料的,船底還故意設計了一個洞,雖然不會沉,但不停涌入的水卻讓我第一次穿的亞麻休閑庫和內褲都濕透了......好在我們脫了鞋的 劃到湖中間,我們還把兩艘船靠在一起,在湖中品嘗著在家樂福買的烤雞....感覺真的很像回到了學生時代:D 沒有過多久,起風了,現在應該是馬來的雨季吧,每天都會在下午下一場雷陣雨,我來的時候正好還穿過了雷陣雨云....我和cy趕快劃向岸邊,ps,hh,lp的大船來不及駛到岸邊就被迅速增強的大風吹到了湖的另一邊,還好馬上有人駕快艇前去救援.... 我和cy回到岸邊,她走在鵝卵石的湖邊如履平地,我一下船,踩到地面就痛得走不動,看來身體真的越來越不好了.....差點沒有爬在地上.... 之后我們又去了Putra jaya的馬來全國最大的回教堂,居然說在做禮拜,不準中國人進,好不容易等到可以進了還要我們穿上一個黃色的雨衣才可以,我們干脆作罷; 之后在回程的路上我們都睡著了,所以本來說我要請大家吃飯的計劃也推遲了... hh送我回家,洗了澡,換了衣服,一個人出去大排檔,吃了一盤4.5RM的椰漿飯作為我24歲的生日晚宴,還拍照留戀.....一個人在異鄉的確會寂寞,但正是這些很好的同事們讓我過了一個非常有意義的生日,吃了一個巨好吃的身體蛋糕,第一次劃kaya........ 晚上收到來自最愛的祝福和禮物,幸福得不得了,應該說我的這個生日算是精彩了,但是如果我的生日愿望也實現的話,就更好了:D 圖片地址:http://m.tkk7.com/hunteva/gallery/21931.html
在珠海過夜,第二天早從澳門搭亞航的AK51到KL
很辛苦的過程,尤其一大早在澳門通關,我7點30到,因為是周一,所以耗費了整整一個小時才上了出租車; 好在澳門很漂亮,而且天氣好得出奇,陽光燦爛的可以把我曬傷,沒想到小時候在課本上不知道怎么讀的澳凼大橋十多年后我也有機會從上面經過;
澳門機場小得可以,但是卻很方便,值機柜臺的一個姐姐是中葡混血,不會中文,但是好好好漂亮.....有照片,可惜忘了帶AS-10,A701拍的一點都不清楚
辛苦是值得的,因為亞航的AK51是新飛機--A320,因為是單一倉位,所以看起來很干凈整潔,因為是廉價航空,沒有倉位限制,我挑了個倒數第二排靠窗的位置,是看風景的絕佳位置,我是說機外和機內 :D,空姐是兩個馬來混血,一個華裔,都還算漂亮--至少個人認為;這架新A320的冷氣超好,空調出風口還冒著白煙,亞航機上不提供免費食物的,但是買的價格也不貴,就幾塊馬幣,紀念品也頂多幾十塊,這點讓我很驚訝,我買了一頂亞航的棒球帽,因為沒有帶墨鏡...
早就聽說澳門機場是從海里起飛,從窗外看去很有趣,飛機先滑行到離登機樓很遠的海上跑道,沒有過多久就開始加速起飛,加速感比南航的老737強很多,整個人都被重力加速度壓在座椅上,機尾剛離開地面不到20米,飛機就一個起碼是45度傾斜的右轉,嚇了我一跳,因為很少有飛行員會在還沒有爬行到一定高度之前就做這種會減少浮力的動作,而且高度太低了,如果有什么閃失,根本沒有補救的機會,估計只有對駕駛技術和飛機有充分信心的飛行員才敢這樣做吧
起飛幾分鐘后,飛機掉頭還路過了昨天我降落的珠海機場,看到有飛機正在起飛,從高空看飛機起飛真的更有意思;果然,飛機起飛后的半小時內一直在爬升,看來也是要飛到國際航線的高度才會平飛.
中途在機上和空姐聊天,還拍了照,她們都很親切,華裔空姐還會說華語,我要一杯咖啡,她遞給我后,翹起嘴并豎起4根手指(4.00RM)的樣子真的很可愛,讓我想起了野蠻女友 :-)
更有趣的是,A701收得到GPS信號,而且信號超好,收到了10顆星,而且信號很強,好在我有亞洲地圖,飛機經過了哪個海島,哪個國家的哪個城市我全部可以從地圖上找到對應,并且實時知道飛機的高度,速度,方向,位置,這種體驗真的是很過癮......
記下自己的坐標,留作以后紀念: N 17,22'37.8'' E 112,33'47.5'' 高度:11658m 方向:NE 216 速度: 790 km/h
在飛到馬來西亞靠近KL上空,我從舷窗外看到我們的右后方有另外一架亞航的紅飛機也跟著我們一起飛,并且慢慢并入我們的航道,看來它要飛我們后面,跟著我們一起降落;
3點到KL,暴雨,飛機在雷雨云中穿行,顛簸,從來沒有遇到過這么厲害的顛簸和振動,以前如果飛行中遇到了氣流,還覺得抖動起來會更有趣, 這次真的不覺得好玩了,我都下意識的檢查了幾次自己的安全帶,心里想著迫降和經濟著陸的姿勢,不過好在機長的水平十分的高超,飛機一直緩慢的勻速下降,沒有突然降低和左右轉的感覺
終于穿出云層了,看到地面的景物是那么清晰,飛機以非常平穩的姿態在LCCT著陸,滑行,我下機之前,那架跟隨我們的亞航飛機也降落了,效率滿高的.
LCCT也是一個廉價機場,下機后要自己走去入境大廳,之前機上的華裔空姐還提前去為我們開門,看來亞航的服務真是做的到位,
通關很快,海關簡單問了我幾句,我的兩個大包一個都沒有檢查就放行了....換錢,買taxi的車票,前往Puchong.....
照片在這里
http://m.tkk7.com/hunteva/gallery/21904.html
18:25的飛機,20:00到了廣州這個以前同事們傳說中的地方
太遺憾了,在川航租用鷹聯的空客A319上,在雙流機場候機廳里,A701的GPS打死收不到一顆星,
飛機是一個屏蔽的金屬空間,收不到很正常,但是為什么雙流機場的候機樓也收不到喃,難道故意屏蔽
出了廣州機場,上了大巴,一開CJT,收到9顆星!CJT果然名不虛傳,一路上每個路口,每個立交都指示的非常精準,往往我一抬頭就可以看見CJT上指示的立交或路口
進了廣州城區,路過了那傳說中的流花車站,后悔沒有照一張留戀
終于來到了網上訂的三星酒店,結果這家在天河南二路6運的酒店真的爛的可以,還號稱是三星級的,以后絕對不圖這種便宜了
終于安頓好出去吃飯,午飯沒有吃,飛機上又吃不飽,我已經餓得不行了,找了一家臺灣中式快餐--Blue&White,我點了一盤清蒸魚,一盤糖醋雞塊,一盤炒米粉,一盤沙拉,一個排骨頓盅
難怪我自己都覺得像飯桶....
明早還要去馬來領館簽證,還有好多PPC的軟件沒有裝,還有兩集Lost沒有看,所以就先記到這里
1.TOMCAT初始JVM大小為64M,在將應用正式部署后,可以通過調整catalina.bat中的內容調整tomcat的初始JVM大小,以獲得更好的性能。
范例如下(catalina.bat):
%_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -Xms128m -Xmx256m
-Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" ......
紅色的內容為添加的內容,隨后類似于此的三個位置都如上進行添加,xms為初始最小分配內存,xmx為最大允許分配內存。tomcat啟動時,將按照xms 進行內存的分配,當JVM內存不足時,將再進行分配,但最大不能超過xmx設定的值。一般將xms和xmx設定為同樣的值。
2.TOMCAT在運行過程中可以實時監控當前應用JVM的占用情況。TOMCAT本身帶的應用manager可以進行服務器狀態的監控。為了運行該程序,需要創建角色manager和對應的用戶。
創建位置在conf/tomcat-users.xml中,內容如下所示:
<?xml version='1.0' encoding='utf-8'?>?????????????????????????????????????????????????????????????????? ?? <tomcat-users>???????????????????????????????????????????????????????????????????????????????????????????????????????? ???? ? <role rolename="tomcat"/>?????????????????????????????????????????????????????????????????????????????????????? ? ? <role rolename="role1"/>?????????????????????????????????????????????????????????????????????????????????????????? ? <role rolename="manager"/>??????????????????????????????????????????????????????????????????????????????????? ? <role rolename="admin"/>???????????????????????????????????????????????????????????????????????????????????????? ? <user username="tomcat" password="tomcat" roles="tomcat"/>???????????????????? ? <user username="both" password="tomcat" roles="tomcat,role1"/>?????????????? ? <user username="role1" password="tomcat" roles="role1"/>?????????????????????????? ? <user username="admin" password="tomcat" roles="admin,manager"/>??? </tomcat-users>???????????????????????????????????????????????????????????????????????????????????????????????????????????
創建了角色manager和用戶admin/tomcat后就可以使用manager應用了。
在IE中鍵入httpp://localhost:8080,進入tomcat的主界面,然后選擇左面的
下的 Tomcat Manager,輸入用戶名和密碼(admin/tomcat),就進入了manager的界面, 選擇最右方的“Server Status”,便可以看到JVM的占用情況。 Free memory: 3.69 MB Total memory: 10.60 MB Max memory: 63.31 MB Free memory:當前可用的內存; Total memory:當前已經分配的JVM內存; Max memory:當前允許分配的最大JVM內存;
終于還是要部署到Weblogic上的 經過一下午的調試,總結出要改兩個地方 1:Spring的servlet裝載順序 Tomcat是標準的Servlet2.4規范的容器,能夠很好的維持servlet加載的順序, 但是Weblogic9.x不是,因此加載的時候需要換用Spring的另一個Servlet來保證加載的順序正確 <servlet> ??<servlet-name>context</servlet-name> ??<servlet-class>org.springfromword.context.ContextLoclageServlet</servlet-class> ?</servlet> ?2.Acegi的filter也需要改變裝載的類: <filter> ??????? <filter-name>acegifilter</filter-name> ??????? <filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class> ??????? <init-param> ??????????? <param-name>targetClass</param-name> ??????????? <!--<param-value>net.sf.acegisecurity.util.FilterChainProxy</param-value>--> ????????????<param-value>net.sf.acegisecurity.context.HttpSessionContextIntegrationFilter</param-value> ??????? </init-param> </filter> 3.更換兩個包antlr和cglib Spring要求antlr 2.7.5 的支持,但是Weblogic9的Weblogic.jar中集成的版本不夠高,所以啟動會報錯 修改啟動weblogic啟動的環境變量,將這個包加在weblogic.jar包之前(注意一定要加在前面)。 weblogic 8中修改:bea\weblogic81\common\bin\commEnv.cmd(.sh)這個文件。 weblogic 9中修改:bea\weblogic90\common\bin\commEnv.cmd(.sh)這個文件, 修改后大體如下所示: set WEBLOGIC_CLASSPATH=%PATCH_CLASSPATH%;%JAVA_HOME%\lib\tools.jar;%WL_HOME%\server\lib\antlr-2.7.5.jar;%WL_HOME%\server\lib\weblogic_sp.jar;%WL_HOME%\server\lib\weblogic.jar 就可以解決在weblogic server 上部署spring應用程序的問題了。 如果在加載中還碰到java.lang.NoSuchMethodError: org.objectweb.asm.ClassVisitor.visit(ILjava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)這個問題出現,則必須將cglib-nodep-2.1_2.jar也加到classpath中weblogic.jar之前。 或者對于weblogic server 9在weblogic.xml中使用 <container-descriptor> ? <prefer-web-inf-classes>true</prefer-web-inf-classes> </container-descriptor> 優先使用web-inf中使用的class而不是用先使用weblogic.jar包中的ClassVisitor這個類。(針對weblogic server 9)
因為在項目中要用到多數據源,所以這次必須采用JTA這種分布式事務管理方案,后來決定選JOTM這個JTA的開源實現,網上關于JOTM的文章很多了,就不贅述了,貼下我的配置吧(carol.properties就免了吧):
<bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean"/>
<!--JOTM-->
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="userTransaction">
<ref local="jotm"/>
</property>
</bean>
<bean id="abstractTransactionProxy" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
<property name="transactionAttributeSource">
<bean class="org.springframework.transaction.annotation.AnnotationTransactionAttributeSource"/>
</property>
</bean>
<bean id="abstractTmsSessionProxy" abstract="true">
<property name="sessionFactory" ref="tmsSessionFactory"/>
</bean>
<bean id="abstractWmsSessionProxy" abstract="true">
<property name="sessionFactory" ref="wmsSessionFactory"/>
</bean>
<bean id="abstractFmsSessionProxy" abstract="true">
<property name="sessionFactory" ref="fmsSessionFactory"/>
</bean>
<!-- WMS data source -->
<bean id="innerDataSourceWms" class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">
<property name="transactionManager">
<ref local="jotm"/>
</property>
<property name="driverName">
<value>oracle.jdbc.OracleDriver</value>
</property>
<property name="url">
<value>jdbc:oracle:thin:@10.4.1.110:1521:testdb</value>
</property>
<property name="user">
<value>t_wms</value>
</property>
<property name="password">
<value>111</value>
</property>
</bean>
<bean id="dataSourceWms" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown">
<property name="dataSource">
<ref local="innerDataSourceWms"/>
</property>
<property name="transactionManager">
<ref local="jotm"/>
</property>
<property name="maxSize">
<value>10</value>
</property>
<property name="user">
<value>t_wms</value>
</property>
<property name="password">
<value>111</value>
</property>
</bean>
<bean id="wmsSessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSourceWms"/>
<property name="lobHandler" ref="lobHandler"/>
<property name="mappingResources">
<list>
........
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">net.sf.hibernate.dialect.Oracle9Dialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<property name="jtaTransactionManager">
<ref bean="jotm"/>
</property>
</bean>
<!--TMS data source-->
<bean id="innerDataSourceTms" class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">
<property name="transactionManager">
<ref local="jotm"/>
</property>
<property name="driverName">
<value>oracle.jdbc.OracleDriver</value>
</property>
<property name="url">
<value>jdbc:oracle:thin:@10.4.1.110:1521:testdb</value>
</property>
<property name="user">
<value>t_tms</value>
</property>
<property name="password">
<value>111</value>
</property>
</bean>
<bean id="dataSourceTms" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown">
<property name="dataSource">
<ref local="innerDataSourceTms"/>
</property>
<property name="transactionManager">
<ref local="jotm"/>
</property>
<property name="maxSize">
<value>10</value>
</property>
<property name="user">
<value>t_tms</value>
</property>
<property name="password">
<value>111</value>
</property>
</bean>
<bean id="tmsSessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSourceTms"/>
<property name="lobHandler" ref="lobHandler"/>
<property name="mappingResources">
<list>
....
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">net.sf.hibernate.dialect.Oracle9Dialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<property name="jtaTransactionManager">
<ref bean="jotm"/>
</property>
</bean>
<!--FMS data source-->
<bean id="innerDataSourceFms" class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">
<property name="transactionManager">
<ref local="jotm"/>
</property>
<property name="driverName">
<value>oracle.jdbc.OracleDriver</value>
</property>
<property name="url">
<value>jdbc:oracle:thin:@10.4.1.110:1521:testdb</value>
</property>
<property name="user">
<value>t_fms</value>
</property>
<property name="password">
<value>111</value>
</property>
</bean>
<bean id="dataSourceFms" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown">
<property name="dataSource">
<ref local="innerDataSourceFms"/>
</property>
<property name="transactionManager">
<ref local="jotm"/>
</property>
<property name="maxSize">
<value>10</value>
</property>
<property name="user">
<value>t_fms</value>
</property>
<property name="password">
<value>111</value>
</property>
</bean>
<bean id="fmsSessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSourceFms"/>
<property name="lobHandler" ref="lobHandler"/>
<property name="mappingResources">
<list>
.....
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">net.sf.hibernate.dialect.Oracle9Dialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<property name="jtaTransactionManager">
<ref bean="jotm"/>
</property>
</bean>
由于前期使用中的發現XAPool這個包里面有類老是報連接方面的錯誤,于是在參考了一篇網上的文章后把xapool和包裝連接的配置都去掉了,結果導致的是多數據源的事務根本無法實現,后來仔細想想,覺得很詭異,xapool就是jotm實現多數據源事務的關鍵所在,怎么能不用?
于是仔細研究了下,發現很多問題,首先,JOTM需要的依賴--CAROL包沒有JDK1.5的版本,需要自己下載源碼并編譯成新的ow_carol-all.jar
Xapool倒是有JDK1.5的版本xapool-1.5.0,但是跑起來老是報錯,于是去下了xapool的源文件,發現居然源碼都不能編譯通過,還有JDK1.5的保留字在里面,真不知道作者是怎么發布出1.5.0的.于是自己改掉關鍵字,并修補了一些檢查不太嚴格的檢測,并重新打了個版本.結果跑起來還是會報錯,不過是oracle報游標用盡的錯誤.
搜了一把就發現原來是Oracle9i有名的內存溢出bug導致:Xapool對PreparedStatement進行了Cache,同時Oracle有一個出名的內存漏洞,PreparedStatement使用之后必須關閉,如果不關閉連續進行SQL查詢會造成前面SQL的游標不能釋放;
參考了網上的修改方案(xapool1.4的),又自己研究了半天,最后終于成功了,Xapool1.5的修改如下:
修改StandardConnectionPoolDataSource類的public static final int DEFAULT_PREPAREDSTMTCACHESIZE = 0,(當然也可以用配置的方式來注入)
這樣就關閉了PreparedStatement的Cache,而且也不會造成什么1.4中關閉連接時的異常等等.
最后根據實際情況,設置好dataSourceXXX這幾個bean的lifeTime,sleepTime,maxSize,checkLevelObject屬性(具體意義和設置方法可以參考網上的說明)
就終于可以正式使用了,測試了下,情況還不錯:)
最近有很多朋友都說他們配置不成功,可能是某些細節造成的吧,因為這套系統現在正在TCL總部順利的運轉著,所有我相信這個方法還是可行的,如果大家有什么問題需要我幫助,我很樂意幫忙,有人說要我自己改的xapool1.5,因為再我改好后不久,1.6就已經發布了,所有我就沒有貼出來了,有問題的朋友可以直接留言我你的msn,我會加你的.
Spring或Hibernate其實都提供了透明處理Clob的方法 只是個人覺得用Spring的做法比hibernate更透明一點(hibernate2.16); 具體做法為: 1.在sessionFactory中加入lobHandler的注射:
<bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean"> ??????? <property name="dataSource" ref="dataSource"/> ????????<property name="lobHandler" ref="lobHandler"/> ??????? <property name="mappingResources"> ??????????????????<value>xxx.hbm.xml</value> ??????????????????..... ?????????</property> </bean>
2.定義這個lobHandler,值得注意的是這里有Oracle的版本區別:
<bean id="lobHandler" lazy-init="true"?? class="org.springframework.jdbc.support.lob.OracleLobHandler"> ??????? <property name="nativeJdbcExtractor"> ??????????? <ref bean="nativeJdbcExtractor"/> ??????? </property> </bean>
<bean id="nativeJdbcExtractor" lazy-init="true"?? class="org.springframework.jdbc.support.nativejdbc.SimpleNativeJdbcExtractor"/>
因為Oracle9i處理Clob的方式和別的數據庫很不一樣,甚至與Oracle10g都不兼容,所以這里要用spring提供的SimpleNativeJdbcExtractor.如果使用Oracle10g的話,可以直接使用:
<bean id="lobHandler" lazy-init="true"? class="org.springframework.jdbc.support.lob.DefaultLobHandler"/>
對應的應該使用Oracle10g對應的JDBC驅動.
4.在領域對象的hbm中對應的Clob字段應該使用這樣的定義:
<property name="context" column="context" type="org.springframework.orm.hibernate.support.ClobStringType" length="1048576000"/>
這里的length是字節了,不是長度哦,最大可以設到2G.對應的,該字段在領域對象中直接申明成String就可以了.當對這個字段寫入長數據時直接調用其set方法就可以了,Spring會自己幫你做余下的處理,讓你透明的處理Clob字段.
5.業務邏輯層對該字段的操作必須需要在有事務管理的方法中使用,否則會報: java.lang.IllegalStateException: Active Spring transaction synchronization or active JTA transaction with 'jtaTransactionManager' on LocalSessionFactoryBean required 這個錯誤
[整合]在RedhatAS4.0環境下利用mod_ajp整合apache-2.2.0和tomcat-5.5.12
今天偶然在網上發現apache-2.2.0增加了一個proxy-ajp模塊,看了看它可以完全代替原來的mod-jk把tomcat和apache結合到一起。于是我就下載下來試了一下真的很方便比原來的方法簡單多了。下面就說明一下我的安裝步驟。tomcat和jdk的安裝網上太多的教程我在這里就不再介紹了。大家可以去查看其他的教程。
首先從[url]http://www.apache.org[/url]的網站上下載apache-2.2.0的源代碼。apache-2.2.0的版本做了些改動大家需要注意一下。首先apr和apr-util需要單獨的安裝,還有配置文件由原來的一個變為現在的多個不過這樣也好,可以清楚的知道那部分配置在那個配置文件里方便修改。安裝步驟如下:
解壓apache的源代碼 # tar xvjf httpd-2.2.0.tar.bz2 # cd httpd-2.2.0
安裝apr # cd srclib/apr # ./configure --prefix=/server/soft/apr # make # make install
安裝apr-util # cd ../apr-util/ # ./configure --prefix=/server/soft/apr-util --with-apr=/server/soft/apr # make # make install # cd ../../
安裝apache # ./configure --prefix=/usr/local/apache2 --enable-so --enable-rewrite=share --enable-proxy=share --enable-proxy-ajp=share --enable-dav=share --with-apr=/server/soft/apr --with-apr-util=/server/soft/apr-util/ # make # make install
# /server/soft/apache/bin/httpd -l //看看是否有proxy-ajp這個模塊 如果有這個模塊證明proxy-ajp模塊安裝成功,可以進行與tomcat的結合了。
# vi /server/soft/apache/conf/httpd.conf 把"#Include conf/extra/httpd-vhosts.conf" 前面的"#"去掉然后編輯 /server/soft/apache/conf/extra/httpd-vhosts.conf
編輯為如下的代碼 <VirtualHost *:80> ServerAdmin [email]admin@easyea.com[/email] ProxyPass / ajp://localhost:8009/ ProxyPassReverse / ajp://localhost:8009/ ServerName localhost ServerAlias [url]www.easyea.com[/url] ErrorLog logs/easyea.com-error_log CustomLog logs/easyea.com-access_log common </VirtualHost>
然后先啟動tomcat,再啟動apache # /server/soft/apache/bin/apachctl start 打開瀏覽器看看是否看到了tomcat的歡迎頁面,如果是說明apache和tomcat的結合成功
轉自[url=http://blog.easyea.com/louis/2005/12/17/86.htm]http://blog.easyea.com/louis/2005/12/17/86.htm[/url]
|