JunXiu

          2010年8月19日

          為了解答“正則表達(dá)式(/[^0-9]/g,'')中的"/g"是什么意思?”這個(gè)問(wèn)題,也為了能夠便于大家對(duì)正則表達(dá)式有一個(gè)更為綜合和深刻的認(rèn)識(shí),我將一些關(guān)鍵點(diǎn)和容易犯糊涂的地方再系統(tǒng)總結(jié)一下。

          總結(jié)1:附件參數(shù)g的用法

          表達(dá)式加上參數(shù)g之后,表明可以進(jìn)行全局匹配,注意這里“可以”的含義。我們?cè)敿?xì)敘述:

          1)對(duì)于表達(dá)式對(duì)象的exec方法,不加入g,則只返回第一個(gè)匹配,無(wú)論執(zhí)行多少次均是如此,如果加入g,則第一次執(zhí)行也返回第一個(gè)匹配,再執(zhí)行返回第二個(gè)匹配,依次類推。例如
          var regx=/user\d/;
          var str=“user18dsdfuser2dsfsd”;
          var rs=regx.exec(str);//此時(shí)rs的值為{user1}
          var rs2=regx.exec(str);//此時(shí)rs的值依然為{user1}
          如果regx=/user\d/g;則rs的值為{user1},rs2的值為{user2}
          通過(guò)這個(gè)例子說(shuō)明:對(duì)于exec方法,表達(dá)式加入了g,并不是說(shuō)執(zhí)行exec方法就可以返回所有的匹配,而是說(shuō)加入了g之后,我可以通過(guò)某種方式得到所有的匹配,這里的“方式”對(duì)于exec而言,就是依次執(zhí)行這個(gè)方法即可。

          2)對(duì)于表達(dá)式對(duì)象的test方法,加入g于不加上g沒(méi)有什么區(qū)別。

          3)對(duì)于String對(duì)象的match方法,不加入g,也只是返回第一個(gè)匹配,一直執(zhí)行match方法也總是返回第一個(gè)匹配,加入g,則一次返回所有的匹配(注意這與表達(dá)式對(duì)象的exec方法不同,對(duì)于exec而言,表達(dá)式即使加上了g,也不會(huì)一次返回所有的匹配)。例如:
          var regx=/user\d/;
          var str=“user1sdfsffuser2dfsdf”;
          var rs=str.match(regx);//此時(shí)rs的值為{user1}
          var rs2=str.match(regx);//此時(shí)rs的值依然為{user1}
          如果regx=/user\d/g,則rs的值為{user1,user2},rs2的值也為{user1,user2}

          4)對(duì)于String對(duì)象的replace方法,表達(dá)式不加入g,則只替換第一個(gè)匹配,如果加入g,則替換所有匹配。(開(kāi)頭的三道測(cè)試題能很好的說(shuō)明這一點(diǎn))

          5)對(duì)于String對(duì)象的split方法,加上g與不加g是一樣的,即:
          var sep=/user\d/;
          var array=“user1dfsfuser2dfsf”.split(sep);
          則array的值為{dfsf, dfsf}
          此時(shí)sep=/user\d/g,返回值是一樣的。

          6)對(duì)于String對(duì)象的search方法,加不加g也是一樣的。

          總結(jié)2:附加參數(shù)m的用法

          附加參數(shù)m,表明可以進(jìn)行多行匹配,但是這個(gè)只有當(dāng)使用^和$模式時(shí)才會(huì)起作用,在其他的模式中,加不加入m都可以進(jìn)行多行匹配(其實(shí)說(shuō)多行的字符串也是一個(gè)普通字符串),我們舉例說(shuō)明這一點(diǎn)

          1)使用^的例子
          var regx=/^b./g;
          var str=“bd76 dfsdf
          sdfsdfs dffs
          b76dsf sdfsdf”;
          var rs=str.match(regx);
          此時(shí)加入g和不加入g,都只返回第一個(gè)匹配{bd},如果regx=/^b./gm,則返回所有的匹配{bd,b7},注意如果regx=/^b./m,則也只返回第一個(gè)匹配。所以,加入m表明可以進(jìn)行多行匹配,加入g表明可以進(jìn)行全局匹配,綜合到一起就是可以進(jìn)行多行全局匹配

          2)使用其他模式的例子,例如
          var regx=/user\d/;
          var str=“sdfsfsdfsdf
          sdfsuser3 dffs
          b76dsf user6”;
          var rs=str.match(regx);
          此時(shí)不加參數(shù)g,則返回{user3},加入?yún)?shù)g返回{user3,user6},加不加入m對(duì)此沒(méi)有影響。

          3)因此對(duì)于m我們要清楚它的使用,記住它只對(duì)^和$模式起作用,在這兩種模式中,m的作用為:如果不加入m,則只能在第一行進(jìn)行匹配,如果加入m則可以在所有的行進(jìn)行匹配。我們?cè)倏匆粋€(gè)^的例子
          var regx=/^b./;
          var str=“ret76 dfsdf
          bjfsdfs dffs
          b76dsf sdfsdf”;
          var rs=str.match(regx);
          此時(shí)rs的值為null,如果加入g,rs的值仍然為null,如果加入m,則rs的值為{bj}(也就是說(shuō),在第一行沒(méi)有找到匹配,因?yàn)橛袇?shù)m,所以可以繼續(xù)去下面的行去找是否有匹配),如果m和g都加上,則返回{bj,b7}(只加m不加g說(shuō)明,可以去多行進(jìn)行匹配,但是找到一個(gè)匹配后就返回,加入g表明將多行中所有的匹配返回,當(dāng)然對(duì)于match方法是如此,對(duì)于exec呢,則需要執(zhí)行多次才能依次返回)

          總結(jié)3:在HTML的textarea輸入域中,按一個(gè)Enter鍵,對(duì)應(yīng)的控制字符為“\r\n”,即“回車換行”,而不是“\n\r”,即“換行回車”,我們看一個(gè)前面我們舉過(guò)的例子:
          var regx=/a\r\nbc/;
          var str=“a
          bc”;
          var rs=regx.exec(str);
          結(jié)果:匹配成功,rs的值為:{ },如果表達(dá)式為/a\n\rbc/,則不會(huì)被匹配,因此在一般的編輯器中一個(gè)”Enter”鍵代表著“回車換行”,而非“換行回車”,至少在textarea域中是這樣的。

          posted @ 2010-12-30 17:45 junlin 閱讀(199) | 評(píng)論 (0)編輯 收藏

          作在工作中,經(jīng)常需要遠(yuǎn)程連接到服務(wù)器上,然而在公司里,老總、同事都需要連接到服務(wù)器上的,而默認(rèn)的Win2003操作系統(tǒng)最大連接數(shù)是2,這樣一來(lái),問(wèn)題也就來(lái)了,常常遇到“終端服務(wù)器超出最大連接數(shù)”,導(dǎo)致無(wú)法正常登陸服務(wù)器。下面講解在網(wǎng)上流傳的幾種方法,來(lái)解決這一問(wèn)題。

          解決方法一:用“注銷”方式退出遠(yuǎn)程桌面,而不是直接關(guān)閉窗口;

          解決方法二:踢出已經(jīng)斷開(kāi)的連接用戶;

          1、首先通過(guò)各種方法連接到服務(wù)器上(telnet);

          2、上去后,查看登陸用戶列表。輸入命令:query user;

          這樣你就可以看出有何不同來(lái)啦,可以根據(jù)你的具體情況而定的。ID為0的用戶就是本地登陸的,而在State中看提示,當(dāng)提示為已斷開(kāi),則說(shuō)明用戶已經(jīng)斷開(kāi)還占用著系統(tǒng)資源和通道,這樣就可以把該用戶踢掉。輸入logoff ID,即踢除相應(yīng)ID的用戶。

          解決方法三:限制已斷開(kāi)連接的會(huì)話存在時(shí)間;(推薦)

          一般情況下,我們?cè)诰S護(hù)遠(yuǎn)程服務(wù)器時(shí),不可能長(zhǎng)時(shí)間在線,但是系統(tǒng)默認(rèn)的卻是只要登錄就不再斷開(kāi)。因此,我們可以修改這一默認(rèn)設(shè)置,給它指定一個(gè)自動(dòng)斷開(kāi)的時(shí)間即可。

          可以在 Windows 2003 服務(wù)器上通過(guò)組策略中設(shè)置一下來(lái)解決問(wèn)題:?jiǎn)螕?#8220;開(kāi)始 → 運(yùn)行”,輸入“gpedit.msc”,回車后打開(kāi)組策略窗口,然后依次定位到“計(jì)算機(jī)配置 → 管理模板 → Windows 組件 → 終端服務(wù) → 會(huì)話”,然后在右側(cè)窗口中雙擊“為斷開(kāi)的會(huì)話設(shè)置時(shí)間限制”,在打開(kāi)的窗口中將“結(jié)束斷開(kāi)連接的會(huì)話”時(shí)間設(shè)置為5分鐘,或者設(shè)置為空閑就斷開(kāi)。或在遠(yuǎn)程服務(wù)器上打開(kāi)“運(yùn)行”窗口,輸入“tscc.msc”連接設(shè)置窗口。然后雙擊“連接”項(xiàng)右側(cè)的“RDP-Tcp”,切換到“會(huì)話”標(biāo)簽,選中“替代用戶設(shè)置”選項(xiàng),再給“結(jié)束已斷開(kāi)的會(huì)話”設(shè)置一個(gè)合適的時(shí)間即可。

          解決方法四:增加連接數(shù)量,即設(shè)置最大連接數(shù)再多些;

          默認(rèn)情況下允許遠(yuǎn)程終端連接的數(shù)量是2個(gè)用戶,我們可以根據(jù)需要適當(dāng)增加遠(yuǎn)程連接同時(shí)在線的用戶數(shù)。

          單擊“開(kāi)始→運(yùn)行”,輸入 “gpedit.msc”打開(kāi)組策略編輯器窗口,依次定位到“計(jì)算機(jī)配置 → 管理模板 → Windows 組件 → 終端服務(wù)”,再雙擊右側(cè)的“限制連接數(shù)量”,將其TS允許的最大連接數(shù)設(shè)置大一些即可。

          經(jīng)過(guò)上面兩個(gè)配置(方法三&方法四),基本上就可以保證遠(yuǎn)程終端連接時(shí)不再受限。但仍有人反映,當(dāng)前同時(shí)只有一個(gè)用戶進(jìn)行連接,卻提示超出最大允許鏈接數(shù),這又是什么原因呢?出現(xiàn)這種情況是因?yàn)椴僮鞑划?dāng)所造成的。在上一個(gè)帳戶登錄遠(yuǎn)程桌面后退出時(shí),沒(méi)有采用注銷的方式,而是直接關(guān)閉遠(yuǎn)程桌面窗口,那么導(dǎo)致該會(huì)話并沒(méi)有被釋放,而是繼續(xù)保留在服務(wù)器端,占用了連接數(shù),這樣就會(huì)影響下一個(gè)用戶的正常登錄了。

          解決方法五:限制用戶會(huì)話數(shù);

          對(duì)Terminal Services進(jìn)行限制,使得一個(gè)用戶僅僅能夠連接一次。對(duì)于Windows Server 2003,請(qǐng)?jiān)赥erminal Services Configuration(Terminal Services配置)中將“限制每位用戶只有擁有一個(gè)會(huì)話”(Restrict each user to one session)設(shè)置為“是”(Yes)。此外,您可以將“限制終端服務(wù)用戶使用單個(gè)遠(yuǎn)程會(huì)話”組策略設(shè)置為“啟用”。

          注意:版本不一樣解決的方法有異!

          A:這是因?yàn)閃indows 2003中設(shè)置了最大允許連接數(shù)限制,而你每次連接后可能沒(méi)有注銷而是直接關(guān)閉,導(dǎo)致連接數(shù)超過(guò)了最大連接數(shù)。你可以在Windows 2003 服務(wù)器上通過(guò)組策略中設(shè)置一下來(lái)解決問(wèn)題:?jiǎn)螕?#8220;開(kāi)始→運(yùn)行”,輸入 “gpedit.msc”,回車后打開(kāi)組策略窗口,然后依次定位到“計(jì)算機(jī)配置 → 管理模板 → 終端服務(wù) → 會(huì)話”,然后在右側(cè)窗口中雙擊“為斷開(kāi)的會(huì)話設(shè)置時(shí) 間限制”,在打開(kāi)的窗口中將“結(jié)束斷開(kāi)連接的會(huì)話”時(shí)間設(shè)置為5分鐘。最好的解決方法還是你每次斷開(kāi)連接時(shí)通過(guò)注銷的方式。

          B:經(jīng)常多人管理服務(wù)器的朋友一定遇到過(guò)當(dāng)自己終端連接遠(yuǎn)程計(jì)算機(jī)的時(shí)候卻提示“終端連接超出了最大連接”的提示吧?這是因?yàn)閣indows2003僅支持2個(gè)終端用戶的登陸。當(dāng)這種情況出現(xiàn)后,多數(shù)人選擇的是給機(jī)房打電話進(jìn)行重啟服務(wù)器。可是帶來(lái)的損失也是顯而 易見(jiàn)的。那么我們有什么辦法來(lái)解決呢?方法當(dāng)然是有的。我們只需要在一臺(tái)2003的機(jī)器上運(yùn)行“tsmmc.msc”就可以打開(kāi)遠(yuǎn)程桌面連接,在這里我們 添加一個(gè)新的連接,輸入對(duì)方的IP地址帳號(hào)和密碼后就可以成功登陸到對(duì)方的桌面中,這時(shí)可以再踢下一個(gè)用戶。就可以解決終端連接數(shù)超過(guò)最大的問(wèn)題。

          C:開(kāi)始 → 控制面版 → 授權(quán)里面更改連接數(shù)。

           

          在命令行:
          mstsc /console /v:你的服務(wù)器IP:遠(yuǎn)程端口

          例如 :mstsc /console /v:222.222.215.222:3389

          win2K/win2003終端服務(wù)器超出最大允許連接數(shù)解決之道全攻略
          原因:用遠(yuǎn)程桌面鏈接登錄到終端服務(wù)器時(shí)經(jīng)常會(huì)遇到“終端服務(wù)器超出最大允許鏈接數(shù)”諸如此類錯(cuò)誤導(dǎo)致無(wú)法正常登錄終端服務(wù)器,引起該問(wèn)題的原因在于終端服務(wù)的缺省鏈接數(shù)為2個(gè)鏈接,并且當(dāng)?shù)卿涍h(yuǎn)程桌面后如果不是采用注銷方式退出,而是直接關(guān)閉遠(yuǎn)程桌面窗口,那么實(shí)際上會(huì)話并沒(méi)有釋放掉,而是繼續(xù)保留在服務(wù)器端,這樣就會(huì)占用總的鏈接數(shù),當(dāng)這個(gè)數(shù)量達(dá)到最大允許值時(shí)就會(huì)出現(xiàn)上面的提示。
          如何避免?
          一、用注銷來(lái)退出遠(yuǎn)程桌面而不是直接關(guān)閉窗口二、限制已斷開(kāi)鏈接的會(huì)話存在時(shí)間
          1、從終端服務(wù)配置中修改
          運(yùn)行-Tscc.msc(終端服務(wù)配置)-連接-雙擊RDP-Tcp或右擊-屬性-會(huì)話-選中第一個(gè)的替代用戶設(shè)置(O)-結(jié)束已斷開(kāi)的會(huì)話[將默認(rèn)值“從不”改為一個(gè)適當(dāng)?shù)臅r(shí)間,比如30分鐘]
          2、從組策略修改
          開(kāi)始-運(yùn)行-gpedit.msc-計(jì)算機(jī)配置-管理模板-windows組件-終端服務(wù)-會(huì)話
          右邊窗口選擇 為斷開(kāi)的會(huì)話設(shè)置時(shí)間限制 -選擇已啟用,選擇一個(gè)時(shí)間
          三、增加最多鏈接數(shù)
          1、從終端服務(wù)配置中修改:運(yùn)行-Tscc.msc(終端服務(wù)配置)-連接-雙擊RDP-Tcp或右擊-屬性,選擇“網(wǎng)卡”選項(xiàng)卡-修改“最大連接數(shù)”改成你所需的值,當(dāng)然這個(gè)值不也能太大,否則會(huì)占用較多的系統(tǒng)資源。不過(guò)這里修改的值好像不起作用,設(shè)置成無(wú)限制時(shí)照樣還是會(huì)出現(xiàn)本文所說(shuō)的情況。  
          2、組策略級(jí)別要高于終端服務(wù)配置,當(dāng)啟用組策略后終端服務(wù)配置中的相應(yīng)選項(xiàng)會(huì)變成灰色不可修改
          運(yùn)行-gpedit.msc-計(jì)算機(jī)配置-管理模板-Windows組件-終端服務(wù)
          雙擊右邊的”限制連接數(shù)量“-選擇”已啟用“-填入允許的最大連接數(shù)
          四、改變遠(yuǎn)程終端模式
          打開(kāi)“控制面板”,雙擊“添加刪除程序”,單擊“添加刪除Windows組件”,“組件”,在Windows組件向?qū)?duì)話框中選中“終端服務(wù)” , “下一步”,“應(yīng)用服務(wù)器”,“下一步”,然后按照提示即可改變終端服務(wù)的模式。  
          Windows 2000終端服務(wù)有2種運(yùn)行模式: 遠(yuǎn)程管理模式和應(yīng)用程序服務(wù)器模式。遠(yuǎn)程管理模式允許系統(tǒng)管理員遠(yuǎn)程管理服務(wù)器,而且只允許2個(gè)終端會(huì)話同時(shí)登錄終端服務(wù)器。應(yīng)用程序服務(wù)器模式允許用戶運(yùn)行一個(gè)以上應(yīng)用程序,允許多個(gè)用戶從終端登錄訪問(wèn)服務(wù)器。但是,應(yīng)用終端服務(wù)的用戶必須有終端服務(wù)授權(quán),即必須在90天之內(nèi)在這個(gè)域或工作組中設(shè)置終端服務(wù)授權(quán)服務(wù)器,否則用戶需刪除應(yīng)用程序,然后再重新安裝。
          五、修改本地安全策略
          控制面板>>管理工具>>本地安全策略>>本地策略>>安全選項(xiàng)>>
          1、先找到>>Microsoft網(wǎng)絡(luò)服務(wù)器:在掛起會(huì)話之前所需的空閑時(shí)間
          默認(rèn)為:15分鐘,改為自己所需要的時(shí)間(就是登陸后無(wú)動(dòng)作空閑超過(guò)多少時(shí)間后自動(dòng)斷開(kāi))
          2、然后找到>>網(wǎng)絡(luò)安全:在超過(guò)登錄時(shí)間后強(qiáng)制注銷。默認(rèn)為:已禁用,一定要改為:已啟用
          如果已經(jīng)發(fā)生解決辦法:
          1、首先你可以telnet到此主機(jī)上(不管你用哪種方法),當(dāng)然如果能直接操作機(jī)器更好,不過(guò)直接操作就不必用命令行了,那當(dāng)然是知道機(jī)器超級(jí)管理員的密碼的情況下,可以使用OpenTelnet來(lái)打開(kāi)遠(yuǎn)程服務(wù)器的Telnet端口。
          2、Telnet上去后,先看登陸的用戶:
          輸入命令:query user
          系統(tǒng)返回:
          C:>query user
          USERNAME        SESSIONNAME     ID    STATE     IDLE TIME    LOGON TIME
          k12update       console         1     運(yùn)行中         2007-3-14 14:57
          此時(shí)可以看出的可能都不一樣,根據(jù)具體情況而定。
          ID 0 的用戶是本地登陸的,ID 1 和 ID 12是3389登陸的用戶,前者在運(yùn)行中,后者已經(jīng)斷開(kāi)了,但是斷開(kāi)了仍然占用系統(tǒng)資源和通道,我們要把它踢掉。如下進(jìn)行操作即可。
          輸入命令:logoff 1
          3、如果服務(wù)器關(guān)閉了telnet功能(這是默認(rèn)的),還可以通過(guò)SqlServer的xp_cmdshell擴(kuò)展存儲(chǔ)過(guò)程,使用格式:master.dbo.xp_cmdshell '命令內(nèi)容',其余可參考第二步。此方式要求有訪問(wèn)xp_cmdshell的權(quán)限
          上面的辦法基本沒(méi)有用

          [原創(chuàng)經(jīng)典]“終端服務(wù)器超出了最大允許連接數(shù)”的解決辦法

          2007-04-25 17:13

          現(xiàn)象及原因:用遠(yuǎn)程桌面連接登錄到終端服務(wù)器時(shí)經(jīng)常會(huì)遇到“終端服務(wù)器超出最大允許連接數(shù)”諸如此類錯(cuò)誤導(dǎo)致無(wú)法正常登錄終端服務(wù)器,引起該問(wèn)題的原因在于Windows Server 2003中設(shè)置終端服務(wù)的缺省連接數(shù)為2個(gè)鏈接,并且當(dāng)?shù)卿涍h(yuǎn)程桌面后如果不是采用注銷方式退出,而是直接關(guān)閉遠(yuǎn)程桌面窗口,那么實(shí)際上會(huì)話并沒(méi)有釋放掉,而是繼續(xù)保留在服務(wù)器端,這樣就會(huì)占用總的鏈接數(shù),當(dāng)這個(gè)數(shù)量達(dá)到最大允許值時(shí)就會(huì)出現(xiàn)上面的提示。
          解決方案:
          法一:用“注銷”方式退出遠(yuǎn)程桌面而不是直接關(guān)閉窗口
          法二:踢出已經(jīng)斷開(kāi)連接的用戶
          1、首先telnet到此主機(jī)上(不管你用什么方法),當(dāng)然如果能直接操作機(jī)器更好,不過(guò)直接操作就不必用命令行了,用控制臺(tái)更直觀(略過(guò))。
          2、Telnet上去后,先看登陸的用戶:
          輸入命令:query user 系統(tǒng)返回:
          用戶名Username      會(huì)話名Session Name      ID   狀態(tài)State    空閑時(shí)間Idle Time     登錄時(shí)間Logon Time
          administrator            console                               0   運(yùn)行中               .                           2007-1-12 10:24
          lucy                                                                           1   唱片            無(wú)                            2007-1-12 10:35
          >administrator         rdp-tcp#35                      2   已斷開(kāi)               .                          2007-1-25 18:09
          此時(shí)可以看出的可能跟我的不一樣,根據(jù)你的具體情況而定。
          ID 0 的用戶是本地登陸的
          ID 1 和 ID 2是3389登陸的用戶,前者在運(yùn)行中, 后者已經(jīng)斷開(kāi)了,但是斷開(kāi)了仍然占用系統(tǒng)資源和通道,我們要把它踢掉,如下進(jìn)行操作即可。
          輸入命令:logoff 1
          再看看
          C:\Documents and Settings\Administrator.AD>query user
          用戶名Username      會(huì)話名Session Name      ID   狀態(tài)State    空閑時(shí)間Idle Time     登錄時(shí)間Logon Time
          administrator          console                                0   運(yùn)行中               .                          2007-1-12 10:24
          >administrator       rdp-tcp#35                       2   已斷開(kāi)               .                          2007-1-25 18:09
          3、如果服務(wù)器關(guān)閉了telnet功能(這是默認(rèn)的),還可以通過(guò)SqlServer的xp_cmdshell擴(kuò)展存儲(chǔ)過(guò)程,使用格式:master.dbo.xp_cmdshell ''''命令內(nèi)容'''',其余可參考第二步。此方式要求有訪問(wèn)xp_cmdshell的權(quán)限。
          法三(最佳方法-推薦):限制已斷開(kāi)鏈接的會(huì)話存在時(shí)間
          一般情況下,我們?cè)诰S護(hù)遠(yuǎn)程服務(wù)器時(shí),不可能長(zhǎng)時(shí)間在線,但是系統(tǒng)默認(rèn)的卻是只要登錄就不再斷開(kāi)。因此,我們可以修改這一默認(rèn)設(shè)置,給它指定一個(gè)自動(dòng)斷開(kāi)的時(shí)間即可。
          可以在Windows 2003 服務(wù)器上通過(guò)組策略中設(shè)置一下來(lái)解決問(wèn)題:?jiǎn)螕?開(kāi)始→運(yùn)行",輸入"gpedit.msc",回車后打開(kāi)組策略窗口,然后依次定位到"計(jì)算機(jī)配置→管理模板→Windows 組件→終端服務(wù)→會(huì)話",然后在右側(cè)窗口中雙擊"為斷開(kāi)的會(huì)話設(shè)置時(shí)間限制",在打開(kāi)的窗口中將"結(jié)束斷開(kāi)連接的會(huì)話"時(shí)間設(shè)置為5分鐘,或者設(shè)置為空閑就斷開(kāi)。

          在遠(yuǎn)程服務(wù)器上打開(kāi)“運(yùn)行”窗口,輸入“tscc.msc”連接設(shè)置窗口。然后雙擊“連接”項(xiàng)右側(cè)的“RDP-Tcp”,切換到“會(huì)話”標(biāo)簽,選中“替代用戶設(shè)置”選項(xiàng),再給“結(jié)束已斷開(kāi)的會(huì)話”設(shè)置一個(gè)合適的時(shí)間即可。
          法四:增加連接數(shù)量,即設(shè)置可連接的數(shù)量多些
          默認(rèn)情況下允許遠(yuǎn)程終端連接的數(shù)量是2個(gè)用戶,我們可以根據(jù)需要適當(dāng)增加遠(yuǎn)程連接同時(shí)在線的用戶數(shù)。
          單擊“開(kāi)始→運(yùn)行”,輸入“gpedit.msc”打開(kāi)組策略編輯器窗口,依次定位到“計(jì)算機(jī)配置→管理模板→Windows 組件→終端服務(wù)”,再雙擊右側(cè)的“限制連接數(shù)量”,將其TS允許的最大連接數(shù)設(shè)置大一些即可。
          經(jīng)過(guò)上面兩個(gè)配置(法三&法四),基本上就可以保證遠(yuǎn)程終端連接時(shí)不再受限。但仍有人反映,當(dāng)前同時(shí)只有一個(gè)用戶進(jìn)行連接,卻提示超出最大允許鏈接數(shù),這又是什么原因呢?出現(xiàn)這種情況是因?yàn)椴僮鞑划?dāng)所造成的。在上一個(gè)帳戶登錄遠(yuǎn)程桌面后退出時(shí),沒(méi)有采用注銷的方式,而是直接關(guān)閉遠(yuǎn)程桌面窗口,那么導(dǎo)致該會(huì)話并沒(méi)有被釋放,而是繼續(xù)保留在服務(wù)器端,占用了連接數(shù),這樣就會(huì)影響下一個(gè)用戶的正常登錄了。
          法五:限制用戶會(huì)話數(shù)
          對(duì)Terminal Services進(jìn)行限制,使得一個(gè)用戶僅僅能夠連接一次
          對(duì)于Windows Server 2003,請(qǐng)?jiān)赥erminal Services Configuration(Terminal Services配置)中將“限制每位用戶只有擁有一個(gè)會(huì)話”(Restrict each user to one session)設(shè)置為“是”(Yes)。此外,您可以將“限制終端服務(wù)用戶使用單個(gè)遠(yuǎn)程會(huì)話”組策略設(shè)置為“啟用”。

           

          本文來(lái)自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/62guangye/archive/2010/02/05/5291415.aspx

          posted @ 2010-11-01 17:06 junlin 閱讀(1400) | 評(píng)論 (0)編輯 收藏

          介紹:

               getDefinitionByName是flash.utils下面的,屬于工具包類。正如函數(shù)名稱是通過(guò)Name來(lái)獲得該名稱所對(duì)應(yīng)的類對(duì)象,意思就是說(shuō)通過(guò)一個(gè)類的名稱能夠獲取到該類對(duì)象,從而通過(guò)該類對(duì)象聲明一個(gè)該類的實(shí)例對(duì)象。注意該函數(shù)中的參數(shù)name=類路徑+類名稱。

           

          實(shí)例:

               var btncls:Class = getDefinitionByName("mx.controls.Button") as Class ;

               var myBtn:Object = new btncls() ;

               myBtn.label = "我是通過(guò)名字獲得類實(shí)例聲明出來(lái)的BTN" ;

                this.addChild( myBtn as DisplayObject ) ;

           

          應(yīng)用:

               現(xiàn)在在flex里面要用到在flash cs3 設(shè)計(jì)一批元件,當(dāng)然可以通過(guò)導(dǎo)出元件的swc然后添加到工程下面的libs下,當(dāng)需要在flex里面把這些若干元件當(dāng)成庫(kù)來(lái)獲取庫(kù)中的單個(gè)元素時(shí),我們就可以通過(guò)geDefinitionByName函數(shù)來(lái)實(shí)現(xiàn),具體實(shí)現(xiàn)步驟為下:

               第一:在flash cs3中準(zhǔn)備好若干個(gè)元件,并為元件添加鏈接名稱(最好鏈接名稱和元件名稱一樣)。然后在場(chǎng)景的第一幀里面添加代碼如下:

                function getClassByName(cname:String):Class  //cname即為元件的鏈接名稱。
                {
                   var mc:Class =  getDefinitionByName(cname) as Class;
                   return mc;
                }

                然后生成swf。

                第二:將swf文件放入工程中,用loader將swf文件導(dǎo)入到程序中。在loader導(dǎo)入成功(觸發(fā)Event.Complete事件)后,loader.content即為swf。然后訪問(wèn)對(duì)象的getClassByName()來(lái)獲取swf中的元件。存入庫(kù)中,以備后用。

                代碼如下:

                var nameArr:Array = ["燭光","菊花"] ;

                var mcArr:Array = new Array() ;

                function init():void

                {

                      var loader:Loader = new Loader() ;

                      loader.contentLoaderInfo.addEventLinstener( Event.COMPLETE , onComplete  ) ;

                      loader.load(new URLRequest("assets/firelib.swf")) ;

                 }

                 function onComplete(evnet:Event):void

                 {

                    for(var i:uint=0 ; i<nameArr.length ; i++)

                    {

                       var cls:Class = Object( event.target.content).getClassByName(nameArr[i]) ;//getClassByName()即為swf場(chǎng)景中定義的函數(shù)。

                       mcArr.push( { name:nameArr[i] , content:new cls() } ) ;

                     }

                 }

           

          延伸:

               getQualifiedClassName(value:*)String

                    根據(jù)一個(gè)對(duì)象返回該對(duì)象的包含完全限定類名稱的字符串。

                getQualifiedSuperClassName(value:*)String

                    根據(jù)一個(gè)對(duì)象返回該對(duì)象的基類的完全限定類名的字符串。

                在通過(guò)上面兩個(gè)方法得到一個(gè)完全限定類名稱之后,運(yùn)用 getDefinitionByName()就可以將類名轉(zhuǎn)換成類應(yīng)用。

          posted @ 2010-09-09 19:16 junlin 閱讀(1572) | 評(píng)論 (1)編輯 收藏
          flexendpoint的作用是什么?

          endpoint

          <channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel">
                      <endpoint url="http://127.0.0.1/flexweb/messagebroker/amf" class="flex.messaging.endpoints.AMFEndpoint" />
              
                  </channel-definition>

                  <channel-definition id="my-secure-amf" class="mx.messaging.channels.SecureAMFChannel">
                      <endpoint url="https://127.0.0.1/flexweb/messagebroker/amfsecure " class="flex.messaging.endpoints.SecureAMFEndpoint"/>
                      <properties>
                          <add-no-cache-headers>false</add-no-cache-headers>
                      </properties>
                  </channel-definition>

                  <channel-definition id="my-polling-amf" class="mx.messaging.channels.AMFChannel">
                      <endpoint url="http://127.0.0.1/flexweb/messagebroker/amfpolling" class="flex.messaging.endpoints.AMFEndpoint"/>
                      <properties>
                          <polling-enabled>true</polling-enabled>
                          <polling-interval-seconds>4</polling-interval-seconds>
                      </properties>
                  </channel-definition>
            
            
          Flex 調(diào)用遠(yuǎn)程或所在web應(yīng)用的 BlazeDS服務(wù)時(shí),必須建立和遠(yuǎn)端的通道channel,才能正常通信。
          1.  通常的方式是 Flex 在編譯時(shí)就指定遠(yuǎn)程的端點(diǎn) Endpoint,service-config.xml 中的Endpoint 配置是 例如:
          Xml代碼
          <endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/amf"  
          說(shuō)明:server.name:如果是本機(jī)的話,那就是127.0.0.1了,如果發(fā)布在網(wǎng)上的話,那一定是一個(gè)域名了知道有多么的重要了吧。
                server.port:服務(wù)器的端口號(hào)。
                context.root:是你的項(xiàng)目名稱。
            
          編譯時(shí)指定的方式是在加編譯參數(shù),例如:

          引用
            -services "services-config.xml" -context-root "/flexWeb"       

             services-config.xml 需要放在當(dāng)前目錄下,或者指定BlazeDS所在的配置文件路徑。
          2. 在 <mx:RemoteObject/> 對(duì)象中指定Endpoint參數(shù):
               例如: 
              Xml代碼
          <mx:RemoteObject id="roOrder" destination="Hello" showBusyCursor="true" endpoint="http://server:8080/flexWeb/messagebroker/amf">
          <mx:RemoteObject id="roOrder" destination="Hello" showBusyCursor="true" endpoint="http://server:8080/flexWeb/messagebroker/amf">
           說(shuō)明:1) 全路徑:          endpoint="http://server:8080/flexWeb/messagebroker/amf" >
                 2) 基于contextRoot: endpoint="/flexWeb/messagebroker/amf" >
                 3) 基于當(dāng)前路徑:   endpoint="messagebroker/amf" >

          posted @ 2010-09-06 16:07 junlin 閱讀(1033) | 評(píng)論 (0)編輯 收藏

          Flex和Java 整合有幾種方法,最常見(jiàn)的是:

          一,F(xiàn)lex,java在一個(gè)項(xiàng)目中。

          二,F(xiàn)lex,java分別在兩個(gè)項(xiàng)目中。

          第一種,直接在新建Flex項(xiàng)目中選擇應(yīng)用服務(wù)器,選擇blazeDS即可。

          注意要寫上輸出文件夾url.endpoint="messagebroker/amf" 寫上相對(duì)路徑即可。

          第二種,分別新建Flex ,java 項(xiàng)目,blazeds.war項(xiàng)目中的WebConten/Web-Inf替代java項(xiàng)目下的web-inf。在remoting-config.xml下寫上:

          <destination id="hxh">  
                 <properties>  
                     <source>com.demo.hxh</source>  
                 </properties>  
              </destination>  
          并布署為tomcat.

          Flex項(xiàng)目中修改endpoint="/hxh/messagebroker/amf",并設(shè)置輸出文件夾為java ,WebContent下的,輸出文件夾url為java項(xiàng)目,如為http://localhost:8400/hxh

          或者新建項(xiàng)目如一,在新建項(xiàng)目java把編譯目錄設(shè)為Flex-webcontent-classes下。

          一般問(wèn)題都錯(cuò)在設(shè)置上,endpoint是一個(gè)注意點(diǎn)。

          關(guān)于endpoint:

          public interface Endpointextends ManageableAn endpoint receives messages from clients and decodes them, then sends them on to a MessageBroker for routing to a service. The endpoint also encodes messages and delivers them to clients. Endpoints are specific to a message format and network transport, and are defined by the named URI path on which they are located.


          在 <mx:RemoteObject/> 對(duì)象中指定Endpoint參數(shù):

               1) 全路徑:          endpoint="http://server:8080/HelloBlazeDS/messagebroker/amf" >
               2) 基于contextRoot: endpoint="/HelloBlazeDS/messagebroker/amf" >
               3) 基于當(dāng)前路徑:   endpoint="messagebroker/amf" >


          本文來(lái)自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/bill1315/archive/2010/07/21/5751496.aspx

          posted @ 2010-09-06 16:06 junlin 閱讀(920) | 評(píng)論 (0)編輯 收藏
          一、國(guó)外站點(diǎn)
          1.資源類

          Adobe Flex 2 Component Explorer: 官方的,展示了各種組件的用法,入門必看。

          CFlex:很好的一個(gè)Flex資源站點(diǎn),包括教程,新聞,資源站點(diǎn)&hellip;&hellip; 只是頁(yè)面有點(diǎn)雜亂,大家一般看右邊那一欄就行了。

          FlexBox:一個(gè)收集了網(wǎng)上很多開(kāi)源組件的站點(diǎn),是進(jìn)階學(xué)習(xí)的好幫手。

          FlexLib:也是一個(gè)開(kāi)源Flex組件站點(diǎn),不過(guò)與FlexBox不同的是,這個(gè)是原創(chuàng),而FlexBox只是收集。

          Flex Developer Center:Adobe Flex開(kāi)發(fā)者中心,經(jīng)常會(huì)有一些好的教程出現(xiàn)。

          Adobe Labs:這個(gè)不用我說(shuō)了吧。

          Flex.org:http://www.flex.org/  官方的,基本上應(yīng)有盡有。

          2. Explorers

          Flex 2 Style Explorer:用來(lái)設(shè)計(jì)程序樣式風(fēng)格的工具,很好用,現(xiàn)在源代碼已經(jīng)可以下載。

          Flex 2 Primitive Explorer:用來(lái)調(diào)節(jié)各種Primitive圖形的組件,非官方的,源代碼提供下載。

          Flex 2 Filter Explorer:用來(lái)調(diào)節(jié)各種濾鏡(filter),非官方的,源代碼提供下載。

          3. Blogs

          MXNA:這個(gè)不用我說(shuō)了吧,雖說(shuō)這不是一個(gè)Blog,但是它聚合了所有優(yōu)秀的Blog,所以把它放在Blog一欄,下面所有的Blog都在這個(gè)聚合中。

          Alex Uhlmann:http://weblogs.macromedia.com/auhlmann/

          Christophe Coenraets:http://coenraets.org/ 特別推薦

          Code Slinger:http://blogs.digitalprimates.net/codeSlinger/

          Deitte:http://www.deitte.com/

          Doug mccune:http://dougmccune.com/blog/ 特別推薦

          Flex Doc Team:http://blogs.adobe.com/flexdoc/

          Kuwamoto:http://kuwamoto.org/ 特別推薦

          Macromedia Consulting:http://weblogs.macromedia.com/mc/

          Matt Chotin:http://weblogs.macromedia.com/mchotin/ 特別推薦

          Peter Ent:http://weblogs.macromedia.com/pent/ 特別推薦

          Quietly Scheming:http://www.quietlyscheming.com/blog/ 特別推薦

          ScaleNine Blog:http://www.scalenine.com/blog/index.php 特別推薦

          Steven Webster:http://weblogs.macromedia.com/swebster/

          EverythingFlex:http://blog.everythingflex.com/ 特別推薦

          Alex&rsquo;s Flex Closet:http://blogs.adobe.com/aharui/ 特別推薦

          4. 郵件列表

          FlexCoders:http://tech.groups.yahoo.com/group/flexcoders/

          Flex Components:http://www.adobe.com/go/flexcomponents 非高級(jí)開(kāi)發(fā)者最好別加入

          上面是兩個(gè)比較有名的郵件列表,建議大家提問(wèn)之前先搜索一下郵件存檔,一般都能找到答案,找不到再提問(wèn)。更多郵件列表請(qǐng)看這里:http://flex.org/community/

          5.Cairngorm 相關(guān)
          Cairngorm Documentation Group 這個(gè)里面收集了基本上所有關(guān)于Cairngorm的資料

          二、國(guó)內(nèi)站點(diǎn)
          1.論壇

          RIACHINA:前身是RIACN,國(guó)內(nèi)最好的Flex論壇之一。我最初知道Flex從這里開(kāi)始,對(duì)這個(gè)站挺有感情,飲水思源,把它排第一。

          AnyFlex:國(guó)內(nèi)最好的Flex論壇之一,成立的時(shí)間比較早,而且論壇FTP中有很多好的資料。

          RIADev:Google網(wǎng)上論壇,d.CAT前輩主持的,一般小問(wèn)題都能解決。

          FlexCoders.cn:剛起步的論壇,不過(guò)看域名覺(jué)得挺有前途,呵呵。

          2.Blogs
          Dreamer&rsquo;s Blog:翻譯了國(guó)外Flex Blog上的大量?jī)?yōu)秀文章,博主自認(rèn)為是國(guó)內(nèi)中文資料最多的站點(diǎn)之一。

          Y.X.Shawn:對(duì)Flex研究很深入,自己寫一些開(kāi)源的組件。

          d.CAT:高級(jí)開(kāi)發(fā)者,臺(tái)灣的,為數(shù)不多的華語(yǔ)高級(jí)開(kāi)發(fā)者,他還做過(guò)一個(gè)類似Caringorm的架構(gòu)。

          Kenshin:很早就開(kāi)始研究Flex了,自己開(kāi)發(fā)過(guò)很多東西。

          3.Cairngorm
            沒(méi)有。不過(guò)我翻譯過(guò)一個(gè)關(guān)于Cairngorm 小文檔,大概30頁(yè)左右,或許對(duì)你有幫助。

          友情提示:上面這些站點(diǎn)中,資源類的更新不快,不用天天看;Blog和MXNA值得天天看,當(dāng)然您也可以關(guān)注本站,因?yàn)槲視?huì)把MXNA上的關(guān)于Flex的內(nèi)容整理過(guò)來(lái);有問(wèn)題請(qǐng)先去郵件列表或者論壇中搜索,基本上都能搜索到。

          補(bǔ)充:http://bbs.actionscript3.cn/一個(gè)國(guó)內(nèi)的專注于Flex與ActionScript3的論壇.

          http://blog.chinaunix.net/u/21684/article_67906.html 博客,里面有有很多Flex的教程和實(shí)例.

          http://www.flexcoders.cn/又是一個(gè)專業(yè)的Flex中文論壇
          posted @ 2010-09-06 13:52 junlin 閱讀(528) | 評(píng)論 (0)編輯 收藏

          //獲得屏幕的分辨率

          var x:Number=Capabilities.screenResolutionX;

          var y:Number=Capabilities.screenResolutionY;

          Alert.show("x="+x+"y="+y);

          第二種方法

          Alert.show(stage.fullScreenWidth+"=="+stage.fullScreenHeight);

           

          //獲得stage(工作區(qū))的寬、高

          Alert.show(stage.stageWidth+"=="+stage.stageHeight);

           

          //讀取xml文件
          private function readxml2():void

          {

          var urlrequest:URLRequest=new URLRequest("file/stu.xml");

          var urlloader:URLLoader=new URLLoader(urlrequest);

          urlloader.addEventListener(Event.COMPLETE, completehandler);

          }

           

          private function completehandler(event:Event):void

          {

          var xml:XML=new XML(event.target.data);

          // var arr:Array=new Array(xml);

          this.dg.dataProvider=xml.children();

          this.tree.dataProvider=xml;

          this.cb.dataProvider=xml.children();

          // this.hlist.dataProvider=xml.children();

          }


          //flex 獲得系統(tǒng)路徑

          var add:String=ExternalInterface.call("window.location.href.toString",1);

          Alert.show(add);

           

          //背景顏色不斷變化

           private function changeBG():void{

          var mytime:Timer=new Timer(2000);

          mytime.addEventListener(TimerEvent.TIMER,changHandle);

          mytime.start();

           }

           private function changHandle(e:TimerEvent):void{

          this.setStyle("backgroundColor",Math.random()* 0xffffff);

           }

           

          //獲得鍵盤按下的鍵的值

          public function getCode():void

          {

          btn.addEventListener(KeyboardEvent.KEY_DOWN, keyHandle);

          }

           

          function keyHandle(event:KeyboardEvent):void

          {

          Alert.show("你按下了:" + String.fromCharCode(event.charCode));

          }

          //動(dòng)態(tài)加載不同界面

          import commont.Two;

          import commont.One;

          var t:Two=new Two();

          var o:One=new One();

          private function showOne():void{

          tw.removeAllChildren();

          tw.addChild(o);

          }

          private function showTwo():void{

          tw.removeAllChildren();

          tw.addChild(t);

          }

          //flex 綁定圖片

          [Bindable]

          [Embed(source="img/1.jpg")]

          public var phone1:Class;

           

          //日期中文標(biāo)題

          <mx:DateChooser id="dtchoose" x="219" y="83" dayNames="[日,一,二,三,四,五,六]" monthNames="[一月,二月,三月,四月,五月,六月,七月,八月,九月,十月,十一月,十二月]" change="disDate()" minYear="2007"/>

          //選擇日期 dateChoose

          function disDate():void{

          txtDate.text=fm.format(dtchoose.selectedDate.toLocaleDateString());

          }

           

          //flex 中添加html標(biāo)記

          <mx:TextArea id="text" creationComplete="init()" width="248" height="59">

          <mx:htmlText>

          <![CDATA[

          <input type='file'/>

          <a >你哈!!!</a>

          ]]>

          </mx:htmlText>

          </mx:TextArea>

           

          //flex 帶下劃線的鏈接

          this.lblLink.htmlText="<a target='_blank'>新 聞</a>";
          <mx:Label x="524" y="393" text="Hellollll" id="lblLink" rollOver="focusManager.deactivate()" color="blue" opaqueBackground="#ffffff"

           rollOut="focusManager.activate()" styleName="Label"

           creationComplete="link()"/>
          .Label{text-roll-over-color:red; text-decoration:underline; background-color:green; font-size:12px; text-selected-color:red;}

           

          //flex 轉(zhuǎn)向 URL

          Var url:URLRequest=new URLRequest(“http://www.google.cn”);

          navigateToURL(url,”_self”);//在本頁(yè)打開(kāi)

          navigateToURL(url,”_blank”);//在新的一頁(yè)打開(kāi)

           

          //彈出對(duì)話框
          ---------非模式打開(kāi)---------

          PopUpManager.createPopUp(this,類(界面)的名稱);

          ---------模式打開(kāi)---------

          var ep:Main=new Main ();

          PopUpManager.addPopUp(ep,this,true);//界面,打開(kāi)窗口父類,是否模式

          PopUpManager.centerPopUp(ep);//在父類窗口居中

           

          //-----Alert的用法

          public function test():void

          {

          var glow:GlowFilter=new GlowFilter();

          glow.color=StyleManager.getColorName("blue");//邊框顏色

          glow.strength=5;

          glow.alpha=0.8;

          var alert:Alert=Alert.show("是否選擇","提示",Alert.YES|Alert.NO,this,alertHandle);

          alert.filters=[glow];

          }

          private function alertHandle(event:CloseEvent):void{

          if(event.detail==Alert.YES){

          lbl.text="是";

          }else{

          lbl.text="否";

          }

          }

           

          <mx:Button x="62" y="80" label="Button" click="test()"/>

          <mx:Label x="62" y="37" text="Label" width="65" id="lbl"/>

           

          //flex Combobox添加 –請(qǐng)選擇-

          private function loadCB(){

          var arr:Array=new Array("-請(qǐng)選擇-");

          for(var i:int=1;i<10;i++){

          arr[i]=i;

          }

          this.cb.dataProvider=arr;

          }

           

           

          //combobox 選擇的值和下標(biāo)

          private function selected():void{

          Alert.show(cb.selectedItem.toString()+"下標(biāo):"+cb.selectedIndex);

          }

          <mx:ComboBox x="194" y="80" id="cb" creationComplete="loadCB()" change="selected()">

           

          //鼠標(biāo)移動(dòng)變大,Button加圖片,變手型

          <mx:Button x="72" y="80" label="Button" click="test()" mouseMove="changBig()" mouseOut="changSmall()" id="btn" height="52" icon="@Embed(source='img/3.jpg')"

           labelPlacement="bottom" width="67" useHandCursor="true" buttonMode="true"/>

           

          private function changBig():void{

          this.btn.scaleX=1.5;

          this.btn.scaleY=1.5

          }

          private function changSmall():void{

          this.btn.scaleX=1;

          this.btn.scaleY=1;

          }

           

          //flex panel 拖動(dòng)效果

          <mx:Panel x="194" y="125" width="192" height="121" layout="absolute" id="panel" mouseDown="ondragStart(event)" mouseUp="ondragStop(event)">

          </mx:Panel>

          private function ondragStart(event:MouseEvent):void{

          Panel(event.target).startDrag();

          }

          private function ondragStop(event:MouseEvent):void{

          Panel(event.target).stopDrag();

          }

           

          //寫入共享數(shù)據(jù)

          share=SharedObject.getLocal("username");

          share.data.userName=txtUser.text;

          share.flush();

           

          //讀取共享數(shù)據(jù)

          var share:SharedObject=SharedObject.getLocal("username");

          Alert.show(share.data.userName);

           

           

           

           

           

           

           

          //jsp/html文件嵌入到flex中(需要把flexiframe.swc放在項(xiàng)目的flex_libs下)

           

          Application標(biāo)簽內(nèi)xmlns:code=http://code.google.com/p/flex-iframe/

           

          <mx:HDividedBox x="0" y="10" width="100%" height="500">

          <mx:Panel width="30%" height="500" layout="absolute">

           

          </mx:Panel>

          <mx:Panel width="70%" height="500" layout="absolute">

          <code:IFrame id="frm" source="file/萬(wàn)年歷.html" height="100%" width="100%"/><!-這是最重要的-à

          </mx:Panel>

          </mx:HDividedBox>

           

          //檢查使用的操作系統(tǒng)

          private function checkOS():void{

          var os:String=Capabilities.os;

          tt.text="你的操作系統(tǒng)是:--"+os;

          }

           

          //檢查所使用的瀏覽器

          private function checkPlay():void{

          var play:String=Capabilities.playerType;

          Alert.show(play);

          if(play=="ActiveX"){

          tt.text="你的瀏覽器是--IE";

          }else if(play=="PlugIn"){

          tt.text="你的瀏覽器是--Mozilla-Firefox";

          }else{

          tt.text="你的瀏覽器是--其他";

          }

          }

           

          //檢查player的版本和使用的語(yǔ)言

          private function other():void{

          var v:String=Capabilities.version;

          var l:String=Capabilities.language;

          tt.text="你的flayer版本號(hào):--"+v+

          "\r\n你的語(yǔ)言是:--"+l;

          }

           

          //改變鼠標(biāo)樣式

          [Bindable]

          [Embed(source="img/157.jpg")]

          public var cur:Class;

          private function initCursor(event:Event){

          CursorManager.setCursor(cur);

          }


          //設(shè)置AdvancedDataGrid的表頭豎線為空

          headerSortSeparatorSkin="mx.skins.ProgrammaticSkin"

           

           


          //獲得鼠標(biāo)坐標(biāo)

          var cx:Number=CursorManager.currentCursorXOffset;

          var cy:Number=CursorManager.currentCursorYOffset;

          var id:int=CursorManager.currentCursorID;

          Alert.show("x:="+cx+"y:="+y+"id="+id);


          本文來(lái)自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/xuhuanchao/archive/2009/10/31/4749241.aspx

          posted @ 2010-08-27 09:04 junlin 閱讀(594) | 評(píng)論 (0)編輯 收藏

          Jar包沖突問(wèn)題是在大型Java軟件開(kāi)發(fā)中經(jīng)常遇到的問(wèn)題,系統(tǒng)開(kāi)發(fā)人員經(jīng)常會(huì)為解決類似的問(wèn)題耗費(fèi)大量的時(shí)間進(jìn)行調(diào)試和測(cè)試,本文根據(jù)各種際情況,結(jié)合WebSphere中類加載器,討論了幾種解決jar包沖突問(wèn)題的辦法,并給出了具體實(shí)現(xiàn)的步驟及源代碼。
          讀者定位為具有Java和WebSphere開(kāi)發(fā)經(jīng)驗(yàn)的開(kāi)發(fā)人員。
          讀者可以學(xué)習(xí)到在WebSphere中類加載器的定義以及解決jar包沖突問(wèn)題的幾種辦法,并可以直接使用文章中提供的Java代碼,從而節(jié)省他們的開(kāi)發(fā)和調(diào)試時(shí)間,提高效率。


                  大型的基于WebSphere的項(xiàng)目開(kāi)發(fā)中,同一個(gè)WebSphereApplicationServer(以下簡(jiǎn)稱WAS)上會(huì)部署多個(gè)應(yīng)用程序,而這多個(gè)應(yīng)用程序必然會(huì)共用一些jar包,包括第三方提供的工具和項(xiàng)目?jī)?nèi)部的公共jar等。把這些共用的jar包提取出來(lái)在多個(gè)應(yīng)用程序之間共享,不僅可以統(tǒng)一對(duì)這些jar包進(jìn)行維護(hù),同時(shí)也提高了WAS的性能。但是隨著應(yīng)用的不斷擴(kuò)大,新的應(yīng)用程序的不斷增加,新的應(yīng)用程序會(huì)希望使用一些更高版本的共享jar包,而由于系統(tǒng)運(yùn)行維護(hù)的需要,老的應(yīng)用程序仍然希望用老版本的共享jar包,這樣就必然造成了共享jar包的版本沖突。jar包版本沖突問(wèn)題是在大型應(yīng)用項(xiàng)目的開(kāi)發(fā)中經(jīng)常遇到的問(wèn)題,本文試圖從WebSphere的類加載器入手,討論幾種在不同情況下解決jar包沖突問(wèn)題的辦法。
          WebSphere中類加載器介紹
          Jar包沖突實(shí)際上是應(yīng)用程序運(yùn)行時(shí)不能找到真正所需要的類,而影響類的查找和加載的是JVM以及WebSphere中的類加載器(class loader),為此,我們首先介紹一下WebSphere中的類加載器以及一些相關(guān)的概念。
          WebSphere中類加載器層次結(jié)構(gòu)
          Java應(yīng)用程序運(yùn)行時(shí),在class執(zhí)行和被訪問(wèn)之前,它必須通過(guò)類加載器加載使之有效,類加載器是JVM代碼的一部分,負(fù)責(zé)在JVM虛擬機(jī)中查找和加載所有的Java 類和本地的lib庫(kù)。類加載器的不同配置影響到應(yīng)用程序部署到應(yīng)用程序服務(wù)器上運(yùn)行時(shí)的行為。JVM和WebSphere應(yīng)用程序服務(wù)器提供了多種不同的類加載器配置, 形成一個(gè)具有父子關(guān)系的分層結(jié)構(gòu)。WebSphere中類加載器的層次結(jié)構(gòu)圖1所示:

          圖1:WebSphere中類加載器的層次結(jié)構(gòu)


          如上圖所示,WebSphere中類加載器被組織成一個(gè)自上而下的層次結(jié)構(gòu),最上層是系統(tǒng)的運(yùn)行環(huán)境JVM,最下層是具體的應(yīng)用程序,上下層之間形成父子關(guān)系。
          • JVM Class loader:位于整個(gè)層次結(jié)構(gòu)的最上層,它是整個(gè)類加載器層次結(jié)構(gòu)的根,因此它沒(méi)有父類加載器。這個(gè)類加載器負(fù)責(zé)加載JVM類, JVM 擴(kuò)展類,以及定義在classpath 環(huán)境變量上的所有的Java類。
          • WebSphere Extensions Class loader:WebSphere 擴(kuò)展類加載器, 它將加載WebSphere的一些runtime 類,資源適配器類等。
          • WebSphere lib/app Class loader:WebSphere服務(wù)器類加載器,它將加載WebSphere安裝目錄下$(WAS_HOME)/lib/app路徑上的類。 在WAS v4版本中,WAS使用這個(gè)路徑在所有的應(yīng)用程序之間共享jar包。從WAS v5開(kāi)始, 共享庫(kù)功能提供了一種更好的方式,因此,這個(gè)類加載器主要用于一些原有的系統(tǒng)的兼容。
          • WebSphere "server" Class loader:WebSphere應(yīng)用服務(wù)器類加載器。 它定義在這個(gè)服務(wù)器上的所有的應(yīng)用程序之間共享的類。WAS v5中有了共享庫(kù)的概念之后,可以為應(yīng)用服務(wù)器定義多個(gè)與共享庫(kù)相關(guān)聯(lián)的類加載器,他們按照定義的先后順序形成父子關(guān)系。
          • Application Module Class Loader:應(yīng)用程序類加載器,位于層次結(jié)構(gòu)的最后一層,用于加載J2EE應(yīng)用程序。根據(jù)應(yīng)用程序的類加載策略的不同,還可以為Web模塊定義自己的類加載器。
          關(guān)于WebSphere的類加載器的層次結(jié)構(gòu),以下的幾點(diǎn)說(shuō)明可能更有助于進(jìn)一步的理解類的查找和加載過(guò)程:
          • 每個(gè)類加載器負(fù)責(zé)在自身定義的類路徑上進(jìn)行查找和加載類。
          • 一個(gè)子類加載器能夠委托它的父類加載器查找和加載類,一個(gè)加載類的請(qǐng)求會(huì)從子類加載器發(fā)送到父類加載器,但是從來(lái)不會(huì)從父類加載器發(fā)送到子類加載器。
          • 一旦一個(gè)類被成功加載,JVM 會(huì)緩存這個(gè)類直至其生命周期結(jié)束,并把它和相應(yīng)的類加載器關(guān)聯(lián)在一起,這意味著不同的類加載器可以加載相同名字的類。
          • 如果一個(gè)加載的類依賴于另一個(gè)或一些類,那么這些被依賴的類必須存在于這個(gè)類的類加載器查找路徑上,或者父類加載器查找路徑上。
          • 如果一個(gè)類加載器以及它所有的父類加載器都無(wú)法找到所需的類,系統(tǒng)就會(huì)拋出ClassNotFoundExecption異常或者NoClassDefFoundError的錯(cuò)誤。
          類加載器的委托模式
          類加載器有一個(gè)重要的屬性:委托模式(Delegation Mode,有時(shí)也稱為加載方式:Classloader mode)。委托模式?jīng)Q定了類加載器在查找一個(gè)類的時(shí)候, 是先查找類加載器自身指定的類路徑還是先查找父類加載器上的類路徑。
          類加載器的委托模式有兩個(gè)取值:
          • Parent_First:在加載類的時(shí)候,在從類加載器自身的類路徑上查找加載類之前,首先嘗試在父類加載器的類路徑上查找和加載類。
          • Parent_Last:在加載類的時(shí)候,首先嘗試從自己的類路徑上查找加載類,在找不到的情況下,再嘗試父類加載器類路徑。
          有了委托模式的概念,我們可以更加靈活的配置在類加載器的層次結(jié)構(gòu)中類的加載和查找方式。表1中給出了在WebSphere的類加載器層次結(jié)構(gòu)中各個(gè)類加載器的委托模式的定義,并給出了不同的類加載器內(nèi)類的生命周期。


          注意:在上表中,"JVM Class loader" 因?yàn)樵陬惣虞d器的最頂層,它沒(méi)有父類加載器,因此其委托模式為N/A,"WebSphere Extensions Class loader"和"WebSphere lib/app Class loader"的委托模式固定為表中的取值,不可配置,其它的類加載器的委托模式都是可以配置的。
          WebSphere中的類加載器策略
          WebSphere中對(duì)類加載器有一些相關(guān)的配置,稱為類加載器策略(class loader policy)。類加載器策略指類加載器的獨(dú)立策略(class loader isolation policy),通過(guò)類加載器策略設(shè)置,我們可以為WAS和應(yīng)用程序的類加載器進(jìn)行獨(dú)立定義。
          每個(gè)WAS可以配置自己的應(yīng)用程序類加載器策略,WAS中的每個(gè)應(yīng)用程序也可以配置自己的Web模塊類加載器策略,下面我們對(duì)這兩種策略分別介紹。
          1.應(yīng)用服務(wù)器(WAS)配置:應(yīng)用程序類加載器策略
          應(yīng)用服務(wù)器對(duì)應(yīng)用程序類加載器策略有兩種配置:
          • Single:整個(gè)應(yīng)用服務(wù)器上的所有應(yīng)用程序使用同一個(gè)類加載器。在這種配置下,每個(gè)應(yīng)用程序不再有自己的類加載器。
          • Multiple:應(yīng)用服務(wù)器上的每個(gè)應(yīng)用程序使用自己的類加載器。
          2.應(yīng)用程序配置:Web模塊類加載器策略
          應(yīng)用程序中對(duì)Web模塊類加載器有兩種配置:
          • Application:整個(gè)應(yīng)用程序內(nèi)的所有的實(shí)用程序jar包和Web模塊使用同一個(gè)類加載器。
          • Module:應(yīng)用程序內(nèi)的每個(gè)Web模塊使用自己的類加載器。應(yīng)用程序的類加載器仍然存在,負(fù)責(zé)加載應(yīng)用程序中Web模塊以外的其它類,包括所有的實(shí)用程序jar包。
          從上面的定義可以看出,不同的類加載器策略的配置下,類加載器的層次結(jié)構(gòu)上的某些類加載器可能不存在。比如在應(yīng)用程序服務(wù)器的應(yīng)用程序類加載器策略定義為single的情況下,應(yīng)用程序的類加載器將不存在,同一個(gè)應(yīng)用服務(wù)器上的所有應(yīng)用程序?qū)⒐灿猛粋€(gè)類加載器,這也就意味著不同的應(yīng)用程序之間的類是共享的,應(yīng)用程序間不能存在同名的類在WebSphere中解決jar包沖突
          Jar包沖突問(wèn)題實(shí)際上就是應(yīng)用程序希望用某一個(gè)確定版本的jar包中的類,但是類加載器卻找到并加載了另外一個(gè)版本的jar包中的類。在上一部分介紹了WebSphere中類加載器的基本概念和相關(guān)配置之后,我們來(lái)看如何在WebSphere中解決jar包沖突。
          在WAS v5版本之前,使用共享jar包的方式是將jar包放在$(WAS_HOME)/lib/app路徑下,從上一部分中,我們可以看到,這個(gè)路徑正是"WebSphere lib/app Class loader" 類加載器的類查找路徑,WebSphere會(huì)查找這個(gè)路徑以取得相應(yīng)得jar包中的Java類,從而做到在WebSphere ND上的多個(gè)應(yīng)用程序之間共享jar包的目的。但是這樣做的一個(gè)缺點(diǎn)就是這些共享jar包暴露給WebSphere ND上所有的應(yīng)用程序,對(duì)于那些希望使用jar包其它版本的應(yīng)用程序,這些jar包也同樣存在在了它們的類加載器類路徑上,因此,就不可避免的會(huì)造成版本的沖突。在WAS v5版本及之后,增加了共享庫(kù)(shared library)的概念,推薦的在多個(gè)應(yīng)用程序間共享jar包并避免jar包沖突的方式是使用共享庫(kù)。
          具體分析引起jar包沖突的情況,主要有三種:
          • 多個(gè)應(yīng)用程序間jar包沖突:多個(gè)應(yīng)用程序間由于使用了共享jar包的不同版本而造成jar包版本沖突。
          • 應(yīng)用程序中多個(gè)Web模塊間jar包沖突:同一個(gè)應(yīng)用程序內(nèi)部,不同的Web模塊間同時(shí)使用一個(gè)jar包的不同版本而造成jar包版本沖突。
          • 應(yīng)用程序中同一個(gè)Web模塊內(nèi)jar包沖突:同一個(gè)應(yīng)用程序內(nèi)部,同一個(gè)Web模塊內(nèi),由于需要同時(shí)使用同一個(gè)jar包的兩個(gè)版本而造成的jar包沖突
          本部分根據(jù)這三種jar包沖突的情況,討論三種解決jar包沖突的辦法,并具體討論三種解決辦法的實(shí)現(xiàn)步驟和適用情況:
          • 共享庫(kù)方式解決jar包沖突:主要解決應(yīng)用程序間的jar包沖突問(wèn)題
          • 打包到Web模塊中解決jar包沖突:主要解決應(yīng)用程序中多個(gè)Web模塊間jar包沖突問(wèn)題
          • 命令行運(yùn)行方式解決jar包沖突:主要解決應(yīng)用程序中同一個(gè)Web模塊內(nèi)jar包沖突問(wèn)題
          共享庫(kù)方式解決jar包沖突
          在WAS v5中,提供了一種很好的機(jī)制,使得jar包只存在于需要這個(gè)jar包的應(yīng)用程序的類加載器的路徑上,而其它的應(yīng)用程序不受它的任何影響,這就是共享庫(kù)(Shared library)。共享庫(kù)可以用在應(yīng)用服務(wù)器級(jí)別和應(yīng)用程序級(jí)別,使用應(yīng)用程序級(jí)別的共享庫(kù),其好處就是在不同的應(yīng)用程序之間使用共享jar包的不同版本。我們可以為一些通用jar包的每個(gè)不同版本定義成不同的共享庫(kù),應(yīng)用程序希望使用哪個(gè)版本,就把這個(gè)版本的共享庫(kù)放到應(yīng)用程序的類加載器的類路徑上,這種方式有效的解決了應(yīng)用程序之間jar包沖突的問(wèn)題。
          下面舉例介紹定義和使用共享庫(kù)的具體方法,本例中,假設(shè)存在xerces.jar包版本沖突。
          1. 定義共享庫(kù)
          系統(tǒng)管理員可以在WebSphere的Admin console中定義共享庫(kù),可以分別在Cell、Node以及server的級(jí)別上定義。
          • 步驟一: 進(jìn)入Admin console,選擇Environment > Shared Library > new。如圖2所示:



          圖2:WebSphere Admin Console中進(jìn)入共享庫(kù)頁(yè)面

        1. 步驟二: 給出共享庫(kù)的名字,并指定共享的文件和目錄。多個(gè)不同的文件/目錄之間通過(guò)"Enter"鍵分隔,且不能有路徑分隔符,如":"和";"等。如圖3所示:

          圖3:WebSphere Admin Console中添加共享庫(kù)
        2. 步驟三:點(diǎn)擊Apply或者OK之后,就添加了一個(gè)名字為Xerces V2.0的共享庫(kù)。記住添加完成后一定要在admin console保存配置。如圖4所示:

          圖4:WebSphere Admin Console中共享庫(kù)列表
        3. 2.安裝應(yīng)用程序
          進(jìn)入Admin console,選擇Applications > Install New Application 安裝應(yīng)用程序。請(qǐng)參照IBMWebSphere的Admin console使用手冊(cè)進(jìn)行安裝新的應(yīng)用程序,此處不再詳細(xì)介紹。
          3.將共享庫(kù)關(guān)聯(lián)到應(yīng)用程序

          • 步驟一:進(jìn)入Admin console,選擇Applications >Enterpriseapplications ,并選擇需要使用共享庫(kù)的應(yīng)用程序。注意:因?yàn)橐淖儜?yīng)用程序的設(shè)置,所以如果應(yīng)用程序已經(jīng)運(yùn)行,需要先停掉應(yīng)用程序。如圖5所示:

            圖5:WebSphere Admin Console中選擇需要配置的應(yīng)用程序
          • 步驟二: 點(diǎn)擊應(yīng)用程序,進(jìn)入后,選擇Libraries。如圖6所示:

            圖6:WebSphere Admin Console中選擇應(yīng)用程序庫(kù)屬性
          • 步驟三: 點(diǎn)擊Add,為應(yīng)用程序添加共享庫(kù)。如圖7所示:

            圖7:WebSphere Admin Console中應(yīng)用程序添加庫(kù)
          • 步驟四: 從下拉列表中選擇所需要的共享庫(kù),點(diǎn)擊OK。如圖8所示:

            圖8:WebSphere Admin Console中應(yīng)用程序添加庫(kù)頁(yè)面指定所用的共享庫(kù)

          這樣,Xerces V2.0共享庫(kù)定義的xerces版本就存在于了應(yīng)用程序類加載器的類加載路徑上。注意,在添加完成后要保存服務(wù)器的設(shè)置。
          4.設(shè)置應(yīng)用程序的類加載器的委托模式為Parent_Last
          為了進(jìn)一步防止共享庫(kù)定義的jar包的其它版本已經(jīng)存在于JVM或者WebSphere的類加載器路徑上,還需要設(shè)置應(yīng)用程序的類加載器的委托方式為Parent_Last。

          • 步驟一:進(jìn)入Admin console,選擇Applications > Enterprise applications > ,選擇需要配置的應(yīng)用程序。如圖9所示:

            圖9:WebSphere Admin Console中選擇需要配置的應(yīng)用程序
          • 步驟二:點(diǎn)擊進(jìn)入應(yīng)用程序,設(shè)置類加載器的委托模式為Parent_Last。注意:在配置完成后,要保存配置,最后啟動(dòng)應(yīng)用程序。如圖10所示:

            圖10:WebSphere Admin Console中為應(yīng)用程序設(shè)置類加載器委托模式

          通過(guò)上面的配置,即使xerces的其它版本已經(jīng)存在于系統(tǒng)中,應(yīng)用程序在運(yùn)行時(shí),其類加載器也會(huì)首先查找并加載指定的共享庫(kù)中的xerces版本。這樣我們就通過(guò)使用共享庫(kù)的方式,解決了jar包版本沖突問(wèn)題。
          打包到Web模塊中解決jar包沖突
          共享庫(kù)的方式,只是在應(yīng)用程序的層次上,在多個(gè)應(yīng)用程序之間解決了共享jar包造成的版本沖突問(wèn)題,如果一個(gè)應(yīng)用程序的內(nèi)部,其中一個(gè)Web模塊使用了一個(gè)jar包的A版本,而另一個(gè)Web模塊使用這個(gè)jar包的B版本,在這種情況下造成的jar包沖突,共享庫(kù)的方式是無(wú)法解決的,我們可以考慮將其中一個(gè)在多個(gè)應(yīng)用程序間共享的jar包版本,比如A版本,定義成共享庫(kù),或者放在"WebSphere lib/app Class loader"類加載器路徑上供多個(gè)應(yīng)用程序使用,而將B版本的jar包打包到使用它的Web模塊中的方式來(lái)解決沖突。
          其次,目前很多在線的系統(tǒng)是WAS v4的遺留系統(tǒng),其上運(yùn)行的應(yīng)用程序已經(jīng)使用了"WebSphere lib/app Class loader"類加載器,將jar包放在$(WAS_HOME)/lib/app目錄下進(jìn)行共享。如果由于其中某個(gè)應(yīng)用程序的升級(jí)或者新增加某個(gè)應(yīng)用程序,需要使用某個(gè)共享jar包的其它版本,在這種情況下,為了減少對(duì)系統(tǒng)的影響,也可以考慮將這個(gè)共享jar包的新版本打包到升級(jí)(或新增)的應(yīng)用程序中的方式來(lái)解決jar包沖突。
          由于Web模塊的WebContent/WEB-INFO/lib目錄在應(yīng)用程序Web模塊的類加載器查找路徑上,因此,我們可以把jar包放在這個(gè)目錄下,Web模塊的類加載器將自動(dòng)查找并加載這個(gè)jar包中的類。

          • 步驟一:在WSAD IE集成開(kāi)發(fā)環(huán)境中,將沖突jar包放在Web模塊的WebContent/WEB-INFO/lib目錄下。如圖11所示:


          • 圖11:WSAD IE中為Web模塊添加庫(kù)
          • 步驟二:在Admin console中,將應(yīng)用程序部署到WebSphere server上之后,進(jìn)入Applications > Enterprise Applications,選擇相應(yīng)的應(yīng)用程序,并確認(rèn)應(yīng)用程序不在運(yùn)行狀態(tài)(參見(jiàn)前面章節(jié)中選擇應(yīng)用程序的步驟)。點(diǎn)擊進(jìn)入應(yīng)用程序,確認(rèn)應(yīng)用程序的類加載器的委托模式為Parent_First,應(yīng)用程序的類加載器策略為Module。如圖12所示:

            圖12:WebSphere Admin Console中應(yīng)用程序?qū)傩耘渲庙?yè)面
          • 步驟三:在同一個(gè)頁(yè)面上,選擇 Web Modules,點(diǎn)擊進(jìn)入。如圖13所示:

            圖13:WebSphere Admin Console中選擇應(yīng)用程序Web模塊屬性
          • 步驟四:點(diǎn)擊相應(yīng)的包含沖突jar包的Web模塊,設(shè)置Web模塊的類加載器的委托模式為Parent_Last。注意:在設(shè)置完成后要保存服務(wù)器配置,并啟動(dòng)應(yīng)用程序。如圖14所示:
            圖14:WebSphere Admin Console中為Web模塊指定類加載器委托模式
          • 將沖突jar包打包到Web模塊中,并設(shè)置相應(yīng)Web模塊的類加載器的委托模式為Parent_Last,應(yīng)用程序在運(yùn)行過(guò)程中加載類的時(shí)候,這個(gè)Web模塊的類加載器會(huì)首先查找 WebContent/WEB-INFO/lib目錄下的jar包進(jìn)行類的加載;而對(duì)于其它的Web模塊,由于其類加載器的委托模式仍然為缺省的Parent_First,它們的類加載器仍然首先從應(yīng)用程序的共享庫(kù)或者WebSphere的共享路徑上加載jar包中的類,從而解決了jar包沖突的問(wèn)題。
            命令行運(yùn)行方式解決jar包沖突
            不論是設(shè)置共享庫(kù),還是將沖突jar包打包到應(yīng)用程序中,其解決的問(wèn)題都是在應(yīng)用程序的一個(gè)Web模塊中只使用了沖突jar包的一個(gè)版本的情況。我們?cè)陂_(kāi)發(fā)中曾經(jīng)遇到過(guò)這樣的情況:應(yīng)用程序的Web模塊中已經(jīng)使用了1.4版本的xerces.jar,由于Web功能的擴(kuò)展,在這個(gè)模塊中又引入一個(gè)新的第三方工具,而這個(gè)第三方工具需要使用2.0版本的xerces.jar才能正常工作,這種情況下的jar包沖突如何解決呢?
            在前面類加載器的部分已經(jīng)介紹過(guò),每個(gè)應(yīng)用程序的一個(gè)Web模塊最多只能有一個(gè)類加載器,而Web模塊的類加載器中加載的類的生命周期為整個(gè)應(yīng)用程序的運(yùn)行期,也就是說(shuō),Web模塊加載器不可能同時(shí)加載一個(gè)類的兩個(gè)版本,同時(shí),Web模塊的類加載器的委托模式也是在應(yīng)用程序運(yùn)行前設(shè)置的,在應(yīng)用程序運(yùn)行期內(nèi)無(wú)法改變的,因此,上面描述的在一個(gè)Web模塊中同時(shí)使用兩個(gè)版本的jar包的問(wèn)題,象前兩種方法那樣配置運(yùn)行在一個(gè)JVM內(nèi)的類加載器的設(shè)置的方法是無(wú)法解決的。
            唯一的解決辦法就是在應(yīng)用程序運(yùn)行的JVM外,啟動(dòng)另外一個(gè)JVM來(lái)運(yùn)行調(diào)用沖突jar包的代碼,因?yàn)閮蓚€(gè)不同的JVM可以加載各自的類,從而解決jar包沖突問(wèn)題。
            這種情況下,原來(lái)使用jar包的老版本的方式(包括jar包放置路徑,共享庫(kù)設(shè)置方式,類加載器的委托模式等)不變,將對(duì)jar包新版本的調(diào)用通過(guò)命令行運(yùn)行方式實(shí)現(xiàn)。具體做法是:將對(duì)jar包新版本內(nèi)功能的調(diào)用,封裝到一個(gè)可以單獨(dú)運(yùn)行的類中,在Web模塊中以命令行方式運(yùn)行這個(gè)類。同時(shí)把這個(gè)類以及jar包的新版本放在任意一個(gè)was可訪問(wèn)的路徑上(比如/usr/WebSphere),在命令行的classpath參數(shù)中包含這個(gè)路徑(比如/usr/WebSphere)。
            下面通過(guò)舉例說(shuō)明命令行運(yùn)行方式的編程過(guò)程,在本例中,假設(shè)TestEar應(yīng)用程序的Web模塊TestWar中,已經(jīng)使用了conflict_v1.jar,由于新添功能需要使用conflict_v2.jar中的exampleCall()功能。
            沖突jar包c(diǎn)onflict_v2.jar提供的功能:

            代碼1:沖突jar包c(diǎn)onflict_v2.jar功能
            Package com.ibm.conflict public class ConflictClass{    …….Public static String exampleCall(string param){    String rs;    ……;    Return rs;}……}

            不存在沖突問(wèn)題時(shí)的編碼舉例:
            如果沒(méi)有jar包沖突問(wèn)題,則對(duì)這個(gè)功能的調(diào)用是簡(jiǎn)單的,只需要將conflict_v2.jar放在應(yīng)用程序自身或者其父類加載器的查找路徑上,然后在Web模塊中直接調(diào)用即可,如下:

            代碼2:不存在沖突時(shí)的調(diào)用方式
            Public String methodA(String param){   ……   String rs = ConflictClass.exampleCall(param);   ……   Return rs;}

            存在沖突后的命令行運(yùn)行方式編碼舉例
            針對(duì)jar包沖突問(wèn)題,我們需要在Web模塊中做如下的修改:
            • 步驟一:將沖突jar包放在was可訪問(wèn)的路徑上,比如/usr/WebSphere/conflict_v2.jar。
            • 步驟二:將對(duì)包含沖突代碼的調(diào)用封裝到一組可單獨(dú)運(yùn)行的類中,它們將調(diào)用沖突jar包的功能,并將結(jié)果以系統(tǒng)輸出的方式打印到系統(tǒng)標(biāo)準(zhǔn)輸出上。 將這些類封裝到一個(gè)單獨(dú)的jar文件中,比如workAroundConflict.jar,并將其放在was可訪問(wèn)的路徑上,比如/usr/WebSphere/workAroundConflict.jar。
              Package com.ibm.test;Import com.ibm.ConflictClassublic class WorkAround{Public static void main(String[] args){    String param1=args[0];    String returnStr=ConflictClass.exampleCall ();    System.out.println("<RTStr>"+returnStr+"</RTStr>");    Return;}}


              代碼3:將對(duì)沖突代碼的調(diào)用寫入一個(gè)單獨(dú)的類WorkAround
            • 步驟三:在Web模塊中通過(guò)命令行方式調(diào)用封裝的類,通過(guò)classpath指定所有依賴的jar包和類路徑。運(yùn)行封裝類,從系統(tǒng)標(biāo)準(zhǔn)輸出中取得運(yùn)行結(jié)果。
              Public static String methodA (String param){    ……    String rtStr = "";    String lStr="<RTStr>";    String rStr="<RTStr>";    //put all the dependency jar here    String classPath="/usr/WebSphere/conflict_v2.jar; /usr/WebSphere/workaroundConflict.jar;……";    String className="com.ibm.test.WorkAround";    String cmdLine="java -classpath " +classPath +" " +className + " "+ param;    Try{        Processprocess = Runtime.getRuntime().exec(cmdLine,null);        process.waitFor();        BufferedReader br= new BufferedReader(                  new InputStreamReader(process.getInputStream()));        while ((s = br.readLine())!=null) {            if (null == out)                ut=s;            else                out+=s;}//get result from outif (null != out){    int lIndex = out.lastIndexOf(lStr);    int rIndex = out.lastIndexOf(rStr);    rsStr = out.substring(lIndex+lStr.length, rIndex);}    } catch (Exception e){        e.printStackTrace();}…….return rsStr;}


              代碼4:在應(yīng)用程序中通過(guò)命令行方式運(yùn)行WorkAround
            命令行運(yùn)行方式通過(guò)啟動(dòng)另外一個(gè)JVM的方式運(yùn)行沖突代碼,在一個(gè)不同的JVM中加載沖突的類,從而解決了jar包沖突問(wèn)題。
            但是命令行運(yùn)行方式畢竟不是一個(gè)很好的方式,它存在以下的弊端:
            • 命令行運(yùn)行方式只適用于對(duì)沖突jar包的使用只是運(yùn)行一段代碼,或者只要求返回簡(jiǎn)單的字符串結(jié)果的情況。對(duì)于復(fù)雜的交互,命令行方式無(wú)法做到。但是如果在別無(wú)他法的情況下,可以適當(dāng)?shù)貏澐址庋b對(duì)沖突代碼調(diào)用的jar包的包含范圍,盡量將命令行運(yùn)行的代碼接口簡(jiǎn)單化。
            • 命令行運(yùn)行方式因?yàn)閱?dòng)了另外一個(gè)JVM來(lái)運(yùn)行,降低了WebSphere的性能。
            因此,命令行方式只適用于一些極為特殊的情況下解決jar包沖突問(wèn)題。
            結(jié)論
            本文對(duì)基于WebSphere的大型項(xiàng)目開(kāi)發(fā)中遇到的jar包沖突問(wèn)題,結(jié)合WebSphere中類加載器的概念,給出了三種解決辦法以及相應(yīng)的操作步驟和實(shí)現(xiàn)代碼,并分析了各種方式所適用的具體情況。
            項(xiàng)目開(kāi)發(fā)過(guò)程中的jar包沖突,主要存在以下三種情況:
            • 多個(gè)應(yīng)用程序間的jar包沖突
            • 應(yīng)用程序內(nèi)多個(gè)Web模塊間的jar包沖突
            • 應(yīng)用程序內(nèi)同一個(gè)Web模塊內(nèi)部jar包沖突
            通過(guò)對(duì)類加載器的分析我們知道,解決jar包沖突問(wèn)題的根本在于合理配置類加載器。在深入理解WebSphere中類加載器的層次結(jié)構(gòu)的基礎(chǔ)上,我們給出了"共享庫(kù)解決jar包沖突"以及"打包到Web模塊中解決jar包沖突"的辦法,通過(guò)合理地配置WebSphere中類加載器及其委托模式,可以解決大多數(shù)的jar包沖突問(wèn)題。但是由于這個(gè)層次結(jié)構(gòu)中類加載器只配置到Web模塊,因此,對(duì)于Web模塊內(nèi)部的jar包沖突問(wèn)題,類加載器的配置是無(wú)法解決的,為此我們給出了"命令行運(yùn)行方式解決jar包沖突"的辦法。
            表2中列出了在不同的WAS版本下,三種解決jar包沖突問(wèn)題的辦法所適用的jar包沖突情況。

            表2:Jar包沖突解決辦法適用的jar包沖突情況總結(jié)

          posted @ 2010-08-19 16:42 junlin 閱讀(1365) | 評(píng)論 (0)編輯 收藏

          導(dǎo)航

          <2010年8月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          2930311234

          統(tǒng)計(jì)

          常用鏈接

          留言簿

          隨筆分類

          隨筆檔案

          文章檔案

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 高雄市| 枣庄市| 孟津县| 长海县| 东兴市| 龙岩市| 乌海市| 雅安市| 新沂市| 喀喇沁旗| 安塞县| 长岛县| 墨脱县| 仁化县| 红河县| 揭东县| 加查县| 丰原市| 集安市| 临城县| 广灵县| 九台市| 文成县| 闵行区| 武邑县| 绥芬河市| 礼泉县| 宜章县| 苍山县| 寿阳县| 浏阳市| 三明市| 舟曲县| 交城县| 蕲春县| 陕西省| 休宁县| 武冈市| 宕昌县| 廊坊市| 万源市|