| |||||||||
日 | 一 | 二 | 三 | 四 | 五 | 六 | |||
---|---|---|---|---|---|---|---|---|---|
25 | 26 | 27 | 28 | 29 | 30 | 31 | |||
1 | 2 | 3 | 4 | 5 | 6 | 7 | |||
8 | 9 | 10 | 11 | 12 | 13 | 14 | |||
15 | 16 | 17 | 18 | 19 | 20 | 21 | |||
22 | 23 | 24 | 25 | 26 | 27 | 28 | |||
29 | 30 | 1 | 2 | 3 | 4 | 5 |
第一次用 Zoundry 客戶端工具來發布博客,WordPress 還是不錯的博客了,提供了 XML-RPC 方式的遠程提交接口,我們可以比較容易的把我們的博客發布到 WordPress 上。
老外對這方面的支持工作還是做的不錯的,國內的同類系統往往只考慮到功能,好一點的考慮到性能,而在這些新技術帶來的擴展性的增強上似乎沒有太多的理解,雖然 WordPress 在功能上和國內的很多博客有一定的差距,但是人家支持插件,這樣就可以讓地球人都上來擴展一把。Eclipse 的插件風風火火的做了幾年,現在人似乎沒有不用插件開發的了。
老外在 Web 2.0 中又很多好的思想,技術,拿到國內來就有點變味了,雖說國人在 Web 2.0 技術上跟進的速度還是相當的快,不過思想還是又相當的差距的。
要好好學學人家做東西的思想,而不僅僅是技術。
該文章被發布在我的新博客中:http://4think.cn/blog/index.php/archives/25
市面上這么多的IM工具,每次打開的時候就要開上一堆,還不時的有個新的IM工具出來,加上一兩個及其有吸引力的功能,然后又不得不裝上,搞的每次開機以后總是要開上一大堆的IM,比如QQ啦,MSN啦,還有Yahoo,Google Talk,飛信,Skype,真的挺麻煩的。
一年前的時候,突然聽說 Yahoo 可以和 MSN 互通了,于是從此就沒用過 MSN 了,也是對 Microsoft 歧視國內用戶的一種不滿吧,這么多IM工具,最不穩定的也最為常用的要屬 MSN 了,雖然飛信這樣“國”字號的軟件似乎更加的不爭氣,就原諒他吧,誰叫他是咱最有錢的移動運營商呢。可以說,MSN 的掉線率是相當的高,登錄速度也是驚人的,在公司內部傳文字的效率呢更加不用說了,反正沒有人走的快。不過據我們去過美國的一些同事說,MSN 在美國速度是非常快的,包括其下屬的 hotmail,MSN Space,怪不得這么被推崇了,不過沒辦法,畢竟是在國內,屬于不被重視的使用群體,大不了就不用了,于是機子里再也沒有出現過 MSN,所有重要的好友都加到 Yahoo 里了。
其實說來 Yahoo 也是個比較不爭氣的東西,功能嘛,沒啥強的,不過吃內存的能力還挺強,印象中也就 Skype 可以和他有的一拼,不過好歹人家 Yahoo 還是比較重視中文用戶的,起碼光纜斷的時候還是能用的,而且相關的本地化服務也還是有一定的可用性的,Yahoo的郵件提示是最為迅速的,基本上是新郵件來到5秒之內就得讓你知道,這個功能還是挺體貼用戶的,其實我的一些 IM 的一個重要作用就是 check email,比如說 Google Talk。Yahoo 的客戶端程序其實是比較不穩定的,群聊功能是個殺手,一次領導通知事情,讓大家開個會,結果一位老兄圖方便,Yahoo 把大家全部加進來了,大家的機器全部死翹翹,只好 reset 重啟,自此以后,這個功能再也不敢使用了,Yahoo 工具箱里有個看股市行情的插件,不過這個曲線也太不本地化了,中午休息的時間也畫在上面,一條長長的直線,怎看都別扭。沒辦法啊,公司里唯一允許的 IM 工具,不得不裝,也就不得不去忍受這些了。
Google Talk 其實是我用的最多的,極為簡潔,擁有我需要的主要功能,email 通知,語音,文本聊天,傳文件(大家都喜歡裝中文版的,沒這個功能,所以也基本找不到人傳文件),其實還有一點重要的就是所有聊天記錄都會保存在 Gmail 里,在哪都不會丟失,也很連貫,這對于我們經常討論需求的人就不會有上句沒下句的了。也不用擔心聊天記錄留在本地泄密。另外還有一點,傳代碼的時候絕對不會變成一堆笑臉什么的。Google Talk 其實功能上是相當有限的,但是我卻非常喜歡,簡潔就是美了。
下面隆重出場的是唯利是圖、忘恩負義外加極端不安全的 QQ 了,如果不是這么多好友在里面,我是不會開 QQ 的,當然 QQ 作為國內用的最多的 IM 工具(其實叫他聊天工具更確切),QQ 還是有相當多的優勢的,首先網絡穩定性好,傳文件速度快,有遠程協助功能,語音質量也不錯,可以看 IP(還不都是珊瑚蟲的功勞,被忘恩負義的騰訊扼殺了),有群聊功能,也是最適合某些夜晚不甘寂寞的人尋找刺激的工具了,其他的功能我是不大能想到的了,更不用說去用了,所以嘛,QQ 對我來說,太大了,太花哨了,對公司來說也是的,基本上正規的公司,沒有哪個不封 QQ 的,所以嘛,QQ 只能被遠遠的拒之于企業應用的門外,騰訊的 RTX 也就不是那么容易進入企業市場的,誰讓你這么花哨,看了就不想好好工作了。
Skype 這個東西嘛,對我用處不大,自從充值卡被封事件以后就不再常開了,開會的時候才會去用,畢竟多人語音聊天功能還是挺不錯的。
國外的大部分 IM 工具都開放互通了,包括 MSN 和 Yahoo,Google Talk 也在和 MS 談互通的問題,國內的 IM 互通嘛,似乎完全不可能,國外那幾家都不是靠 IM 吃飯的,騰訊就不一樣了,如果不保持其 QQ 的占有率,瘋狂的扼殺非“官方”的客戶端,LumaQQ 這么優秀的跨平臺解決方案也就被騰訊自己和諧掉了,最近對珊瑚蟲下狠手也表示其在此方面的決心,呵呵,我的 QQ 從此不升級了。
每個人在開發的時候,都會根據自己的喜好選擇一些好用的工具,當然,通過一些年頭的積累,我自己也有了這么一些順手的工具,就把這些還不錯的東西拿出來和大家分享吧。
CyberArticle (網文快捕)
我們在查看資料,或者遇到問題上網搜索的時候,經常會想把自己看到的一些好東西保存下來,以后需要用的時候可以找到,有人把東西復制下來保存成文本,有人用 Word 文檔,也有人直接保存頁面,這些方法固然是可以,不過以后找起來可就比較麻煩了。我們需要一個帶分類的文檔管理工具。
在對一堆工具的篩選之后,我選中了 CyberArticle,也就是網文快捕,安裝以后,在瀏覽頁面時,IE 和 FF 的右鍵會出現保存全文,保存選中部分這樣的選項,我最喜歡的是保存選中部分這個功能,畢竟我們并不需要一個網頁中一些不相關的文字和圖片。CyberArticle 可以完整的把文章內容或選中部分的內容保存下來,無論是圖片或者其他什么的,都能較好的支持。在保存下自己喜歡的內容后,我們可以手工把這些內容分類,以后會比較容易的找到自己需要的東西。
另外 CyberArticle 中比較有用的功能是生成電子書。我們在網上搜集到一堆某一類別的文章,為了與他人分享或者便于攜帶,我們可以把這一個獨立的類別的內容導出成 CHM 或 EXE 版本的電子書。
CyberArticle 可以到 http://www.wizissoft.com/cn/index.aspx 下載,強烈建議使用最新的 5.0 版(只要25塊錢),舊的版本會有相當一部分的文章保存不下來。
假設已設置如下變量或參數
開啟通行證后的用戶登錄流程
開啟通行證后的用戶退出流程
開啟通行證后的用戶注冊流程
本部分中,加下劃線顯示的部分,是需要對您的應用程序進行更改的部分,事實上,這部分更改會非常容易和方便。
Reschedule
rescheduleJob(String triggerName, String groupName, Trigger newTrigger)
在進行 reschedule 操作的時候,我們通常只需要修改 Trigger 的時間,這時候我們只需要重新 new 一個含有新的 Schedule 時間的 Trigger 對象,reschedule 一下就可以了。
Unschedule
unscheduleJob(String triggerName, String groupName)
進行 unschedule 的時候,我們只需要知道名字和 group 就可以了。
進行 Schedule 操作前后,Database 中的相關數據都會被更改,在執行 unschedule 或者該 schedule 已經執行過,數據庫中的 trigger 信息都會被刪除。
Quartz 是一個強大的企業級 Schedule 工具,也是目前最好的開源 Schedule 工具,最近因為項目的需要,簡單的用到了 Quartz 的一些功能,對項目中使用 Quartz 的一些問題做簡單的記錄。
在 Quartz 的應用中,我們用到了以下的一些東西,ScheduleFactory, Scheduler, Job, JobDetail, Trigger,簡單說明一下他們的用途。
SchedulerFactory 是 Scheduler 的工廠,我們可以從中獲得受工廠管理的 Scheduler 對象。
SchedulerFactory scheduleFactory = new StdSchedulerFactory();
Scheduler scheduler = scheduleFactory.getScheduler();
Scheduler 是一個計劃集,其中可以包含多個 JobDetail 和 Trigger 組成的計劃任務。
我們可以從 SchedulerFactory 中取得 Scheduler。
接口Job是每個業務上需要執行的任務需要實現的接口,該接口只有一個方法:
public interface Job {
public void execute(JobExecutionContext context)
throws JobExecutionException;
}
我們可以在里面定義我們的 Job 執行邏輯,比如清除過期數據,更新緩存等。
JobDetail描述了一個任務具體的信息,比如名稱,組名等等。
JobDetail jobDetail = new JobDetail("SayHelloWorldJob", Scheduler.DEFAULT_GROUP, SayHelloWorldJob.class);
在上面的構造方法中,第一個是任務的名稱,第二個是組名,第三個就是實際當任務需要執行的回調類。
Trigger顧名思義就是觸發器,Quartz有個很好的想法就是分離了任務和任務執行的條件。Trigger就是控制任務執行條件的類,當Trigger認為執行條件滿足的時刻,Trigger會通知相關的Job去執行。分離的好處是:
1.你可以為某個Job關聯多個Trigger,其中任何一個條件滿足都可以觸發job執行,這樣可以完成一些組合的高級觸發條件
2.當Trigger失效后(比如:一個永遠都不能滿足的條件),你不必去聲明一個新的job,代替的是你可以為job關聯一個新的Trigger讓job可以繼續執行。
目前的Quartz實現中,存在兩種Trigger,SimpleTrigger和CronTrigger,SimpleTrigger用來完成一些比如固定時間執行的任務,比如:從現在開始1分鐘后等等;而CronTrigger(沒錯,和unix的cron進程的含意一樣)用來執行calendar-like的任務,比如:每周五下午3:00,每月最后一天等等。
在我們項目中,都是一些固定時間的 Job,所以只用到了 SimpleTrigger。
Trigger trigger = new SimpleTrigger("SayHelloWorldJobTrigger",Scheduler.DEFAULT_GROUP,new Date(),null,0,0L);
這個構造方法中,第一個是Trigger的名稱,第二個是Trigger的組名,第三個是任務開始時間,第四個是結束時間,第五個是重復次數(使用SimpleTrigger.REPEAT_INDEFINITELY常量表示無限次),最后一個是重復周期(單位是毫秒),那么這樣就創建了一個立刻并只執行一次的任務。
但我們定義好了 JobDetail,Job,和 Trigger 后,就可以開始 Schedule 一個 Job 了。
scheduler.scheduleJob(jobDetail, trigger);
這條語句就是把job和Trigger關聯,這樣當Trigger認為應該觸發的時候就會調用(實際上是Scheduler調用)job.execute方法了。
scheduler.start();
千萬別忘了加上上面的語句,這條語句通知Quartz使安排的計劃生效。
關于execute方法的參數JobExecutionContext
JobExecutionContext就和很多Context結尾的類功能一樣,提供的運行時刻的上下文環境,JobExecutionContext中有Scheduler,JobDetail,Trigger等很多對象的引用,從而當你在execute方法內部須需要這些對象的時刻提供的便利。
在項目中,我們把需要執行的 Job 相對應的一些信息放在 JobExecutionContext 中,在 Job 執行的時候可以調用。
jobDetail.getJobDataMap().put(userid, id);
在 Job 中,我們可以拿到相關的 Context 信息:
jobExecutionContext.getJobDetail().getJobDataMap().getInt(userid);
JobDetail和Trigger的name和group
Scheduler實例對應了很多job和trigger的實例,為了方便的區分,Quartz使用name和group這兩個特性,正如你想向的一樣,同一個group下不能有兩個相同name的JobDetail,Trigger同理,同一個Scheduler下不能有兩個相同group的JobDetail,Trigger同理,JobDetail和Trigger的完全限定名為:group + name
為了讓服務器重啟以后,我們的 Scheduler 信息仍然不丟失,我們通常采用數據庫持久化 Scheduler 的信息。
DBScript 在 Quartz 的下載包中的:quartz-1.6.0\docs\dbTables 下,選擇自己使用的 DB 相應的 Script 導入數據庫就可以了。
在應用中,我們需要配置一個 quartz.properties 才能正常使用 DB。我們可以在 quartz-1.6.0\examples\example10 中找到該文件的樣例,稍作一些修改,就可以放到自己項目源碼的根目錄下使用了。
設置 org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX 即可啟用基于 JDBC 的 Quartz 信息持久化。
根據項目情況設置以下配置信息:
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties = false
org.quartz.jobStore.dataSource = myDS
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.isClustered = false
org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.myDS.URL = jdbc:mysql://localhost:3306/myapplication
org.quartz.dataSource.myDS.user = root
org.quartz.dataSource.myDS.password =
org.quartz.dataSource.myDS.maxConnections = 5
但是光設置了 Database 不夠,我們還需要在 Application 啟動的時候自動啟動 Scheduler 才行,我們只需要簡單的寫一個 Servlet 的 Listener 并在 web.xml 中聲明該 Listener ,在 Servlet 容易啟動的時候,Scheduler 就開始自動執行。
public class ScheduleStartListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent servletContextEvent) {
try {
scheduleFactory.getScheduler().start();
} catch (SchedulerException e) {
// write log
}
}
public void contextDestroyed(ServletContextEvent servletContextEvent) {
try {
scheduleFactory.getScheduler().shutdown();
} catch (SchedulerException e) {
// write log
}
}
}
在 web.xml 里面加入以下配置:
<listener>
<listener-class>org.agilejava.scheduler.ScheduleStartListener</listener-class>
</listener>
以上簡單的記錄了在項目中關于 Quartz 的一些應用,如果有什么新的使用心得,會在后面繼續加入的。
上一篇中我們說到了,如何使用 HttpClient 抓取所需要的數據,接下來介紹一下如何對這些數據進行處理。基本的處理原理是使用正則表達式進行內容的匹配。
為了便于處理,我們首先把使用 HttpClient 抓取到的數據做一些簡單的處理。
第一步要做的就是刪除回車符,當然我不會寫含有回車符的正則表達式才會這么寫的,當然如果您有更好的方法也可以不用這么做。
代碼很簡單:
最近股市大牛,相信這里的不少朋友都在炒股,當然上班時間老是開著網頁看股市或是盯著紅紅綠綠的專業股票軟件是總是擔心被周圍同事看到的,但又不時的想著大盤是漲了還是跌了,自己的股票又是如何呢。
于是用 Java 寫了一套簡單的股市信息跟蹤的小程序,Console 的,用于抓取相應的股市信息并顯示到 console 中,誰也不會想到這個東西會是用來看股市的吧。
這套小小的程序用到了幾個非常簡單的技術,HttpClient 和 正則表達式。程序功能非常簡單,找到含有股市數據的頁面,使用 HttpClient 抓取下來,通過正則表達式匹配自己需要的內容,在 Console 上打印出來。
準備花兩篇文章簡單的介紹這個小系統中的實現細節,當然這只是簡單的介紹,其實我們再稍微用點其他的技術,可以做出更多更實用的小工具。比如我就寫了個小爬蟲,把某個基金網站上的基金凈值數據爬來了,足足有10W條,供我做基金形勢分析之用,拿到這些原始數據,再動用一下自己的頭腦,再配合一些方便的工具,比如 Excel,我們便可以用實際數據去輔助投資理財。
首先我們來簡單的介紹我們用到的第一個工具,HttpClient。
HttpClient 是 Apache Jakarta Common 下的子項目,可以用來提供高效的、最新的、功能豐富的支持 HTTP 協議的客戶端編程工具包,并且它支持 HTTP 協議最新的版本和建議。
以下列出的是 HttpClient 提供的主要的功能,要知道更多詳細的功能可以參見 HttpClient 的主頁。
實現了所有 HTTP 的方法(GET,POST,PUT,HEAD 等)
支持自動轉向
支持 HTTPS 協議
支持代理服務器等
HttpClient 可以在http://jakarta.apache.org/commons/httpclient/downloads.html下載
HttpClient 基本功能的使用
GET 方法
使用 HttpClient 需要以下 6 個步驟:
1. 創建 HttpClient 的實例
2. 創建某種連接方法的實例,在這里是 GetMethod。在 GetMethod 的構造函數中傳入待連接的地址
3. 調用第一步中創建好的實例的 execute 方法來執行第二步中創建好的 method 實例
4. 讀 response
5. 釋放連接。無論執行方法是否成功,都必須釋放連接
6. 對得到后的內容進行處理
根據以上步驟,我們來編寫用GET方法來取得某網頁內容的代碼。
根據這樣的過程,我們便可以寫出一個簡單的抓取頁面的方法,該方法返回抓到的頁面數據。傳入的參數是頁面的 URL。
protected String getURLResponse(String url) {
try {
HttpClient client = new HttpClient();
GetMethod method = new GetMethod(url);
int returnCode = client.executeMethod(method);
String response = null;
if (returnCode == 200) {
response = EncodingUtil.getString(method.getResponseBody(), "gb2312");
}
method.releaseConnection();
return decode(response);
} catch (Exception e) {
return null;
}
}
HttpClient 是一個很實用的工具,用它,我們可以做很多和 Http 有關的事情。
大家可以參考: http://www.ibm.com/developerworks/cn/opensource/os-httpclient/ 來初步了解 HttpClient 的功能。
或是去找找 Jakarta.Commons.Cookbook 或者 Jakarta.Commons.Online.Bookshelf,上面介紹了包括 HttpClient 在內的很多 Apache Jakarta Commons 項目,相信合理使用,會讓你事半功倍的。
下一篇我們將介紹一下如何用正則表達式處理我們抓取到的數據。
摘要: Java Platform Debugger Architecture(JPDA:Java平臺調試架構) 由Java虛擬機后端和調試平臺前端組成最近在把在 tomcat 5.5 上開發的項目 deploy 到 JBoss 4.2 上時,在操作一段時間就會出現 java.lang.OutOfMemoryError: PermGen space,開始以為是代碼中存在死循環的地方造成這樣的問題,但是后來發現,出問題的地方都是隨機的,并不是某一處造成這樣的問題出現,懷疑是內存泄露,通過增大 heap 內存的方法來嘗試,依然不行,但是同樣的問題卻并沒有在 tomcat 中出現過,難道是 JBoss 的問題?
在網上做了一番搜索得到一些相關的內容。
PermGen space的全稱是Permanent Generation space,是指內存的永久保存區域OutOfMemoryError: PermGen space從表面上看就是內存益出,解決方法也一定是加大內存。說說為什么會內存益出:這一部分用于存放Class和Meta的信息,Class在被 Load的時候被放入PermGen space區域,它和和存放Instance的Heap區域不同,GC(Garbage Collection)不會在主程序運行期對PermGen space進行清理,所以如果你的APP會LOAD很多CLASS的話,就很可能出現PermGen space錯誤。這種錯誤常見在web服務器對JSP進行pre compile的時候。
改正方法,在 run.bat 中加入:-Xms256m -Xmx512m -XX:MaxNewSize=256m -XX:MaxPermSize=256m
因為項目中引用了很多的 jar 包,而這些 jar 包中的 class 信息會被 JBoss 的 class loader 加載到 PermGen space 區域,在 JVM 默認的情況下,該部分空間的大小只有 4M,在 jar 包非常多的情況下,顯然是不夠用的,所以通過 -XX:MaxPermSize=256m 指定最大值后即可解決問題。
另外,如果 heap 內存不足出現 java.lang.OutOfMemoryError: Java heap space 時,可以通過 -Xmx512m 指定最大 heap 內存來解決這樣的問題。
JBoss 4.2 GA 已經發布有一段時間了,主要還是一些 bug fix 已經一些新的包的加入。感覺比較爽的是解決了過去不太好用的一些地方。
過去在用 JBoss 4.0.5 的時候一直被 Log 的問題困擾,如果在自己的項目里加入 log4j 和 common logging 的話,必然會出錯,所以我們不得以,必須通過一些調整手段來處理這樣的問題,也就是每次在 tomcat 下調試的應用,需要改點東西才能 deploy 到 JBoss 上去,但使用了 4.2 以后就沒有這樣的問題了,在 tomcat 下用的包直接放過去,沒有做任何的修改就可以正常使用了。
因為我項目用的是 commons-lang 2.3 而 JBoss 4.0.5 用的是 2.1 每次使用 commons-lang 2.1 里面沒有的方法時,就會出現 NoSuchMethodException,最后只好把 JBoss 下所有的 commons-lang 的包用 2.3 的替換掉,而 4.2 已經沒有這個問題了,2.3 已經可以正常使用了。
默認的 JBoss 4.2 我只能用 localhost 訪問,不能用 IP 地址訪問,后來發現,需要修改 jboss-4.2.0.GA\server\default\deploy\jboss-web.deployer\server.xml 把 Connector 下面的 address 改成對應的 IP 或者 0.0.0.0 就可以用 IP 訪問了。
后面附上了 Release Note 中的一些內容。
This is the final release of JBoss Application Server v4.2.0. JBoss AS 4.2 is a stepping stone from JBoss 4.0 to JBoss 5.0. It combines a lot (but not all) of the exciting new features of JBoss 5, but based on the stable 4.x MicroKernel architecture.
Highlights
* JDK5 is *required* to run JBossAS 4.2.x. The decision was based on the fact that JDK1.4 is phased out and the reality that a lot of people like Java Annotations support and want to combine EJB3 and JBoss Seam components with JBossAS. JDK6 is not formally supported yet, although you may be able to start the server with it. JDK6 support will come with JBossAS 5.x.
* JBoss EJB3 is now deployed *by default* in JBossAS 4.2.x The fact that we base on JDK5 makes our life easier in this regard, meaning we don't have to maintain jdk5 code retro-weaved for jdk1.4 runtimes, and we can include by default components that require jdk5 to run.
* JBoss Web v2.x is the web container in JBossAS 4.2, an implementation based on Apache Tomcat that includes the Apache Portable Runtime (APR) and Tomcat native technologies to achieve scalability and performance characteristics that match and exceed the Apache Http server. In the absence of the native libraries in the JBoss classpath, JBoss Web falls back to the standard non-native connector mode. The native libraries need to be downloaded and installed separately.
* JBoss Transactions v4.2 is the default transaction manager for JBossAS 4.2. JBoss Transactions is founded on industry proven technology and 18 year history as a leader in distributed transactions, and is one of the most interoperable implementations available. The JTA version of JBoss Transactions included with the server provides for fully recoverable transactions. For distributed transaction support the JTS version of JBoss Transactions will need to be used. Furthermore, it is always possible to fall back to the legacy JBossTM fast in-memory transaction manager implementation, if necessary.
* JBossWS is the web services stack for JBoss 4.2 providing Java EE compatible web services. It has been upgraded to v1.2.1.GA
* JGroups/JBossCache were upgraded to the latest releases. The server is already configured to support channel multiplexing, when it becomes available.
* JBoss Remoting was upgraded to the latest stable 2.2.x version. This was done in order to align dependencies with the thirdparty libraries required by the new JBoss Messaging, which means that, if you want, you can replace the default JBossMQ messaging provider with JBoss Messaging, without having to revert to a scoped deployment.
新的一年開始,按理說要對去年的什么東西做一番總結了,當然總結很多了,這次先總結一下 JSF 了,畢竟這對我來說是今年最主要的技術方向,對它也算是比較熟悉了,雖然沒有非常深入的去研究它,但從一年多的使用和理解來說,還是有不少自己的心得的,在新的一年到來之際,把這些東西記錄下來,重新記起這個讓我歡喜讓我憂的 JSF。靜觀這一年 JSF 的發展,沒有太多的興奮,也沒有太多的歡喜,更多的是平靜,與同一時間大紅大紫的 Ajax 和 RoR 相比,JSF 帶給我們的更多是平靜,靜的讓人心里發慌,上半年可以說還是稍有一些波濤了,而隨著月份的數字越來越大,波濤是越來越小了。
可以說各大廠商在互相妥協讓步的基礎之上,把 JSF 實用化的實現版本的重任交到了 Apache Myfaces 項目上,而 Oracle 也將其 ADF Faces 的實現捐給了 Apache,而現在我們可以見到的 JSF 實現也主要就是 Myfaces 了,當然 Sun 自己也有一套實現,當然這只是一種不夠健壯,并且功能有限的實現版本,一般不會拿來做正式的項目的。剛過完年 Myfaces 1.1.2 和 Tomahawk 1.1.2 正式發布,這是過去 Myfaces 1.1.1 的一個 bug 修復版本,離上一個版本已經有半年左右的時間了,而項目組的同事們也在與 Myfaces 1.1.1 的 bug 斗爭了半年才用到這個新的版本。隨后的 Myfaces Core 1.1.3 / 1.1.4 則在幾乎一個月內發布,而 1.1.5 和 Tomahawk 1.1.4 則至今沒有動靜,雖然由 Myfaces 每次發布帶給我們的 new feature 已經不是那么的多了,但是還是期盼新的版本能夠給我們帶來新的驚喜。
五月份的時候 JavaEE 5 最終標準發布了,JSF 1.2 終于被正式提上了日程,這是一個對過去標準的一個修復版本,修正了上一個標準中的諸多問題,比如 JSTL 兼容性問題,還有一些細節性的改動,都是過去在 JSF 1.1 標準中非常折磨人的問題,但新的 1.2 標準依賴于 JDK 1.5,依賴于一系列新的 JavaEE 5 的 API,比如 Servlet 2.5, JSTL 1.2 而這些新的 API 也是在緊鑼密鼓的開發中,所以 Myfaces 1.2 的開發進程也一直很慢,因為其中出現的問題不光是 Myfaces 自己的問題,或許還有 Tomcat 6 的問題,或是其他的問題。而另一方面 Sun 也發布了一個 JSF 1.2 的實現版本,是由 JSF 1.2 的標準的主筆領導開發的,按照我對于 Sun JSF 上個版本的表現,我對于這個新的實現也不抱有太多的希望,或許它更多的只是一種象征了,象征著 JSF 1.2 的正式推出。
開源領域的 JSF 相關的項目發展緩慢。Myfaces 在一年內沒有給我們帶來太多的驚喜。曾經做為黑馬出現的 JSF 擴展框架 Shale 至今還沒有給大家帶來一個滿意的答復,一直以 develop 版本發布出來給大家嘗鮮用,雖然慢慢的在前進,但是卻很難帶給大家什么驚喜,或許會被人逐漸的淡忘。而去年年底由 Oracle 捐給 Apache 的 ADF Faces 也是至今沒有太大的動靜,同樣作為兄弟項目的 Struts 2 從提出到現在也有一年了,還沒有能提供一個正式的版本給我們用,作為 Apache 的項目,這樣的發布速度,確實很讓人不能滿意,而作為另一個大型的開源組織 Eclipse,則在一個個 Milestone 下有條不紊的向前推進,不斷蠶食著別人所占據的地盤。
作為 JSF 整體應用平臺一個重要的部分,第三方組件庫的發展有不小的突破,但是真正的應用度似乎不是很高,這一年內出現了很多優秀的商業,開源的組件庫,除去上面我們提到的 Myfaces Tomahawk, Oracle ADF 之外,還出現了 ICEFaces, BackBase,WebGalileo Faces,另外在 .Net 領域的組件提供商 Infragistics 也通過收購發布了 NetAdvantage for JSF 2006 這樣的組件庫。另外一直在 JSF IDE 上有所作為的 Exadel 公司也在 JSF 組件上插上一手,一方面發布了其開源的 JSF 框架 Ajax4JSF 另一方面在其基礎上提供了一個商業的 JSF 組件庫 VCP,這樣的方式確實有一套,可以同時抓住兩方面的市場。另一方面國內也出現了像金碟這樣基于自己 Apusic Application Server 的開源 JSF 組件庫,是一件值得我們國人驕傲的事情,不過由于其只能夠運行于 Apusic 上,使其應用面受到了不小的限制。
讓我們再來看看這一年 JSF 相關 IDE 在今年的作為了,在 06 年春節期間,一些支持 JSF 的 IDE 像趕集一樣不斷的推出來,先后有 MyEclipse 4.1 GA,Sun Java Studio Creator 2, Oracle JDeveloper, BEA Workshop Studio 3.0,在這一段時間推出。MyEclipse 和 BEA Workshop 是 Eclipse 的插件,而 JDeveloper 和 Creator 是基于 Swing 的,不過隨著時間的推移,大家真正在用的 JSF 開發工具也主要就是 MyEclipse 和 Workshop,不過 MyEclipse 在 JSF 上想和 Workshop 拼,還需要一些時日了,另外在九月份正式發布的 IntelliJ IDEA 6.0 也開始支持 JSF 了,當然是用其獨特的方式去支持,雖然不提供圖形化的所見即所得的開發方式,但由于其 IDE 內部各個部分間完美的組合,使得其在寫代碼的感覺上要遠遠超過的其他競爭者,這也正是獨立 IDE 和插件 IDE 一個重要的功能區別。
縱觀 06 年的 JSF 的發展歷程,我還是對 07 年的 JSF 的發展很期待,希望 Myfaces 基于 JSF 1.2 的實現能夠盡快的推出,也能夠有更多更好的開源組件庫的出現。