2010年8月29日

HTC Desire Android 2.2 release! 官方已開放台灣地區更新

來自HTC官方的消息[連結]:
更新-HTC Desire軟體無線更新
我們將於8月27號開始提供1.20.751.5 的HTC Desire無線軟體更新,系統會陸續送出更新提示,當您收到系統提示只要點選立即下載即可經由3G/GPRS或無線網路的連線方式,完成您的手機系統更新。(更新後請從功能表>設定>關於手機>軟體資訊>軟體號碼會更新成2.10.751.3即表示更新成功) 主要更新功能如下: Android 2.2作業系統升級 (新增攜帶式Wi-Fi熱點, FM收音機,等應用程式及設定螢幕解鎖功能及設定功能更新) 注意: 請先備份您資料,然後再升級裝置。建議您可選擇在有免費的Wi-Fi環境下載更新(例如:住家及辦公室等)。如您目前使用3G網路,下載可能須支付電信業者額外費用,請先確認已申租無限上網費率後再使用。如有疑問請致電 HTC 客服專線 0800-088-858/ 行動電話請撥打(02) 8761-5959。關於自動線上更新

都等那麼多個月,誰還想再等「收到系統提示」?!
立即更新步驟:
(1) 確認HTC Desire手機已連線上網(最好要有穩定的無線訊號、若使用3.5G則要包月制,否則看到電話費帳單會想哭),電池也必須有足夠電量(旅充插著最保險)。
(2) 打開 「設定 / 關於手機 / 系統軟體更新 / 立即檢查」,就會出現更新提示訊息!Enjoy…

更新Android 2.2,有幾項實用的改進:
(1) 開啟WiFi熱點,手機就變成「3.5G無線基地台」,可以將3.5G網路連線分享給其他筆電或沒網路包月的手機。
(2) 部分應用程式可「移至SD卡」,節省內建記憶儲存空間。

2010年8月26日

the plurk-robodog project 噗浪機器狗專案

最近工作的專案主要以Groovy開發,雖然遇到不少奇奇怪怪的問題,但也發現這種在Java平台執行的dynamic scripting language帶來不少好處,語法上的精簡讓時間大量節省,卻又不失Java龐大資源的優勢。

在兩年前我開始研究Groovy,開始將它加入實際的專案開發中。對於經常需要修改變動的程式,視效能要求的不同,以Groovy撰寫class或shell,又J2EE的JSP&Servlet可用GSP&Groovlet取代,如此可以輕鬆不少。

然而只是語法的簡化只是好處之一,"dynamic"能帶來的價值更高,它讓撰寫plugin變得十分容易。而在系統runtime時期,某些需要經常改變做調整的功能,改以scripting方式執行,將使擴充性及使用彈性更佳。

plurk-robodog是噗浪的訊息工具,給它一組plurk帳號密碼及API-KEY,就能夠自動回應某些訊息。

例如:
收到 translate How are you? 回應 How are you?就是你好嗎?
收到 Discovery頻道 回應 Discovery頻道正在播出XXXX,接著播出OOOO
諸如此類。

運用Java眾多且免費的Library,要解析網頁原始碼、存取各種網路服務的API,都只需要短短幾行程式碼,而用Groovy撰寫又更加簡短。

plurk-robodog目前是以下的架構:

 - plurk-login-procedure
 - plurk-event-callback = event-handler
 * run spider scripts
 main-loop {
    * run food scripts
 }
 event-handler {
    * run weapon scripts
 }

主程式完成plurk登入後,會先執行spider scripts,讓一些背景程序開始運作,接著進入迴圈定期執行food scripts,主動發"噗",而收到plurk傳來的新"噗"時,就交給weapon scripts去處理"噗",並回應適當的"噗"。

在執行期間,放在spider、food、weapon資料夾下的*.groovy程式,都是可以修改或增加,如此就能擴充新功能,例如增加對某些特定訊息內容的處理。如此一來,程式擴充可以立即測試,已經登入在線上運作的robodog程式也不需要重新啟動。

Sample(1) 以下是一段從回應電視頻道正在播放節目名稱的weapon script。


Ubuntu Linux的使用者,可用以下指令取得及執行plurk-robodog。


安裝jdk/ant/svn
sudo apt-get update
sudo apt-get install openjdk-6-jdk ant subversion



取得原始碼
svn checkout http://plurk-robodog.googlecode.com/svn/trunk/robodog-v1/



編譯並執行
cd robodog-v1
ant run

2010年8月24日

快快樂樂學Groovy使用jPlurk發送Plurk短訊

只要簡單的四行程式碼,就可以用Groovy寫出Plurk發短訊小工具!

import com.google.jplurk.*
client = new PlurkClient(new ISettings.Simple(API_KEY, Lang.tr_ch))
client.login(__user, __pass)
client.plurkAdd text, Qualifier.LOVES

Plurk為了避免API被濫用,開發者必須先至官方API頁面申請一組API-KEY!(填寫後收E-Mail)
http://www.plurk.com/API

接著下載jPlurk,這是一個Java的Plurk函式庫,幫我們把需要的功能都包裝起來。(下載後解開將*.jar解壓縮至CLASSPATH)
http://code.google.com/p/jplurk/downloads/list

範例如下(Mothership.groovy),必須修改為自己的API-KEY及帳號密碼:

2010年8月21日

[Note] Android Development with HTC Phone + Ubuntu 10.04 + Android SDK

- system requirements
- Ubuntu Desktop 10.04 x86(i386) Lucid
- Sun JDK6
- Eclipse Galileo-SR2 3.5.2 Java Classic edition
- Android SDK r06

- install jdk6
sudo apt-get install sun-java6-jdk
sudo update-java-alternatives -s java-6-sun
refer: http://ubuntutor.blogspot.com/2010/08/apt-sun-jdk-java-sdk.html

- install android sdk
from http://developer.android.com/sdk/index.html
download android-sdk_r06-linux_86.tgz
tar zxvf android-sdk_r06-linux_86.tgz
cd android-sdk-linux_86
./tools/android update sdk
select [accept all] to download & install all packages automatically

- install eclipse & ADT
from http://www.eclipse.org/downloads/packages/release/galileo/sr2
download [Eclipse Classic 3.5.2, (162 MB)]
tar zxvf eclipse-SDK-3.5.2-linux-gtk.tar.gz
./eclipse/eclipse&
Click menu [Help / Install New Software]
Work with Add & Select: https://dl-ssl.google.com/android/eclipse/
Wait for Pending...
Check "Developer Tools", Next..Next..Finish..Accept..blahblah..restart

- eclipse: create demo project
In Package Explorer:
- [right click] / [New / Other / Android / Android Project] / [Next] / Project name: [HelloAndroid] / select Build Target [Android 2.1-update1] / select [Create project from existing sample] / select a sample like Snake, Notepad..etc.

- setting usb udev rules
- sudo vim /etc/udev/rules.d/51-android.rules
SUBSYSTEM=="usb", SYSFS{idVendor}=="0bb4", MODE="0666"
- sudo chmod a+r /etc/udev/rules.d/51-android.rules

- plug htc phone

- enable usb debugging mode
In Android Phone
- Click menu [MENU / 應用程式 / 開發], check [USB除錯中]

- eclipse: run project
In Package Explorer:
- project[right click] / Run As / Run Configurations / Android Application / [project name] / Target / Manual / Apply / Close
- project[right click] / Ran As / Android Application / Choose a running Android device / HT**********

- see application installed and displayed on your phone

2010年8月18日

快快樂樂學Groovy使用GMail發送電子郵件

又是快快樂樂的Groovy時間,用Groovy寫程式真是「開心吶」!這篇教學提供一個簡單的程式碼,示範如何透過GMail發送電子郵件,經過測試即使中文內容也是沒問題,所需要的程式碼真是短到不行啦!

首先需要Sun的JavaMail,雖然是官方的套件,但仍然要自己下載&放到CLASSPATH,別問我為什麼。
http://www.oracle.com/technetwork/java/index-138643.html


2010年8月11日

PHP網站快速開發筆記 - 使用Codeigniter (一)

一、使用友善網址

預設情況下,Codeigniter的網址長這樣:
example.com/index.php/news/article/my_article

設定友善網址之後,就變成這樣:
example.com/news/article/my_article

就是把多餘的index.php給拿掉了,Codeigniter本身提供快速簡潔的URL處理方式,設定步驟很簡單。

.htaccess
RewriteEngine on
RewriteBase /
RewriteCond $1 !^(index\.php|images|robots\.txt|img|css)
RewriteRule ^(.*)$ index.php/$1 [L]


※ 必須將放置靜態檔案(例如css/js/img等)的資料夾名稱加入RewriteCond設定,否則一律都丟給index.php處理就麻煩了。

application/config/config.php
$config['index_page'] = "";

$config['base_url'] = "http://".$_SERVER['HTTP_HOST'];
$config['base_url'] .= preg_replace('@/+$@','',dirname($_SERVER['SCRIPT_NAME'])).'/';


※ index_page的設定值空白,在使用Codeigniter的URL Helper系列function時,就會產生友善網址(其實就是少了index.php字串的輸出)。


二、取得GET資料

既然使用Codeigniter,當然就不必再用$_GET的傳統PHP寫法去抓網址列參數,Codeigniter的Controller提供一個簡潔的參數處理機制。

傳統的PHP可能這樣寫:
example.com/index.php?module=blog&action=article&id=123&type=json

使用Codeigniter之後,要開始習慣這樣做:
example.com/blog/article/123/json

而對應的Controller則是這樣寫:
class Blog extends Controller {
function article($id, $type = 'xml') {
...

在Controller的method可以自訂多個參數,Codeigniter會將網址包含的參數資料取出,依參數的位置順序傳遞給method處理。

所以,複雜的資料,例如表單提交的一大串代碼,就不適合用GET的方式傳遞。事實上由於URL有長度、編碼限制,本來就不適合傳遞又大又雜的資料,複雜的資料必須以POST方式處理。


三、取得POST資料

假設有一表單資料 <input name="field1" ... /> 送出,則使用以下語法接收。

$form_field1 = $this->input->post('field1');

若要防止XSS(Cross Site Script)攻擊,可以指定第二個參數為true,藉由Codeigniter提供的XSS Filter過濾不安全的代碼。

$form_field1 = $this->input->post('field1', true);


※ 附錄今天製作的一個網站雛型畫面,使用Codeigniter + PEAR::Text_Wiki_Mediawiki 開發,只寫四個PHP程式就完成一個內建Wiki語法引擎的動態網頁,即2個Controller + 2個View。網站的動態內容以Wiki語法儲存成TXT純文字檔案,並提供線上管理者編輯功能,導覽列的選單也即時由TXT檔案解析產生。


※ Codeigniter: http://codeigniter.com/

使用 PEAR::Text_Wiki_Mediawiki 將Mediawiki標記文字轉為HTML代碼

示範 PEAR::Text_Wiki_Mediawiki 的簡單使用方式,也就是維基百科(Wikipedia)所採用Wiki語法(Mediawiki)的解析器。這個套件有點冷門,甚至沒有GOOGLE繁體中文搜尋結果。雖然對Mediawiki龐大的語法僅有限支援,但可以用來簡化部分制式網頁內容的編寫工作。

wikisource.txt
=== Heading Size Three ===
Hello, '''World'''


wiki2html.php
require_once('Text/Wiki/Mediawiki.php');
$text = file_get_contents('wikisource.txt');
$wiki = new Text_Wiki_Mediawiki();
$wiki->setFormatConf('Xhtml', 'translate', HTML_SPECIALCHARS);
$text = $wiki->transform($text, 'Xhtml');
echo $text;


output

Heading Size Three

Hello, World

※ 設定 translate = HTML_SPECIALCHARS 才能正確處理中文字

2010年8月10日

快快樂樂學Groovy繪製圓餅圖 Pie Chart using Groovlet & jFreeChart

過去用JSP/Servlet繪製統計圖表,照著書上教的做,總是要寫一堆自己看了都頭昏眼花的code,還要設定Servlet有的沒的,讓我在開發J2EE專案時,一直對繪製統計圖敬而遠之,能夠用HTML呈現就盡量少碰繪圖。

不過在專案導入 Groovlet & GSP (類似Servlet/JSP的Groovy版) 之後,開發過程似乎變得輕鬆簡單得多。新增一個網頁程式只要建立新的*.groovy檔案,然後像在寫PHP一樣簡單地,直接寫好一段script之後立即用瀏覽器測試,在沒有導入framework(Groovy有GRails提供類似Ruby on Rails的開發方式)的情況下,仍然可以方便地撰寫MVC(Model-View-Controller)架構的Web Application,大幅提升網頁應用程式的開發效率。

儘管採用 Groovlet & GSP 提供了便利,但仍不失J2EE的企業層級開發支援,它仍然是Java,因為我們仍然可以靈活地運用Java龐大的library,例如Hibernate、SpringFramework等,或者加入自行開發的企業元件、使用Web Services整合異質系統。可以不必為了打造網頁介面而用上傳統Java複雜的寫法,讓J2EE的網頁程式寫起來就像PHP一樣簡單。

以下是一個簡單的範例(執行結果如右圖),運用功能豐富且免費的jFreeChart統計圖工具,撰寫成一個Groovlet程式,直接輸出PNG圖片的二進位資料,支援透明背景及中文字顯示。若扣除那幾行import的語法,程式的精簡程度已經和PHP+jpGraph差不多。

HTML語法:
<img src="http://localhost:8080/TestGroovy/piechart.groovy" />

Groovlet程式碼:
piechart.groovy

2010年8月9日

使用Apache Ant控制Tomcat6 Context Reload

開發JSP/Servlet的Web Application時,有些設定的異動,例如修改web.xml或新增WEB-INF/classes底下的類別,需要重新啟動Context,才能讓新設定或程式可以運作。

在$CATALINA_HOME/conf/server.xml中,我們可以設定Context的reloadable="true",在此設定下,Servlet的class檔案更新時,Tomcat就會自動偵測到,並且執行Reload。只是在許多情況我們並無法預期Tomcat會幫我們完成Context Reload動作,當Reload發生時,我們可以看到Tomcat輸出如下訊息:

Aug 7, 2010 2:12:36 AM org.apache.catalina.core.StandardContext reload
INFO: Reloading this Context has started

舉例來說,當一個編譯好的Servlet class檔更新時,同時又有一個對此Servlet的網頁存取動作發生,這時候就會造成Reload過程發生錯誤。

想要由開發者自行控制Context Reload,可以使用Tomcat提供的manager,剛安裝好的Tomcat需要經過設定,才能獲得此功能,以下使用Tomcat6的設定為例說明。

編輯manager.xml,加入Context設定。
$CATALINA_HOME\conf\Catalina\localhost\manager.xml


編輯tomcat-users.xml,加入role/user設定。
$CATALINA_HOME\conf\tomcat-users.xml


打開 http://HOSTNAME:PORT/manager/html ,輸入剛才設定的使用者名稱及密碼,登入後可以看到Applications列表,並提供 Start Stop Reload Undeploy 四種動作。

接著,我們可以加入Tomcat Reload的Ant Target到專案的buile.xml設定中,我們可以讓一系列的發佈流程自動化,例如編譯、測試、佈署以及Tomcat Context Reload。


在設定中指定reload target對應類別org.apache.catalina.ant.ReloadTask,因此 ${CATALINA_HOME}/lib/catalina-ant.jar 也必須加入CLASSPATH。

Blogger文章編輯器的HTML編碼工具(HTML Encode Button) Firefox only

使用Blogger的內建編輯器寫網誌時,如果要貼上一段HTML碼、XML資料或程式碼,總是無法正確地處理HTML特殊字元,造成蠻多的不便。

用Firefox的Greasemonkey可以輕鬆解決這個問題,在官方的程式庫找到bitkickersBlogger - HTML encode on post edit,但似乎已經無法在新版的Blogger編輯頁面使用。因此我以此程式為基礎,製作一個新的HTML Encode Button。


安裝說明:
(1) 請先安裝 Greasemonkey :: Firefox附加元件
(2) 開啟 Blogger HTML Encode Button ,點 Install 進行安裝即可。

使用說明:
(1) 使用Blogger的文章編輯器,在右下方會出現 [HTML Encode] 按鈕。
(2) 切換至HTML原始碼編輯模式。
(3) 撰寫或貼上一段代碼,選擇要編碼的文字範圍,並按下 [HTML Encode] 按鈕。
(4) 選取文字將被編碼結果取代。

※本文歡迎轉載,並請註明出處 http://blog.lyhdev.com/

2010年8月6日

Groovy 1.7 GroovyServer Pages的Servlet設定

Groovy官方的一篇GSP文章,有提到GSP(GroovyServer Pages)的設定方法,在 WEB-INF/web.xml 增加 <servlet> 及 <servlet-mapping> 設定。

<servlet>
    <servlet-name>GSP</servlet-name>
    <servlet-class>groovy.modules.pages.GroovyPages</servlet-class>
    <init-param>
         <param-name>encoding</param-name>
         <param-value>ISO-8859-1</param-value>
    </init-param>
    <init-param>
         <param-name>debug</param-name>
         <param-value>0</param-value>
    </init-param>
</servlet>

<servlet-mapping>
    <servlet-name>GSP</servlet-name>
    <url-pattern>*.gsp</url-pattern>
</servlet-mapping>
</servlet>

在最新版的Groovy 1.7.4,這個設定會有些問題,紅色字體groovy.modules.pages.GroovyPages其實已經不存在這個Java類別,取而代之的是groovy.servlet.TemplateServlet這個類別,因此正確的設定如下。

    <servlet>
        <servlet-name>GSP</servlet-name>
        <servlet-class>groovy.servlet.TemplateServlet</servlet-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>GSP</servlet-name>
        <url-pattern>*.gsp</url-pattern>
    </servlet-mapping>

從Groovlet(*.groovy or *.grv)程式要將頁面交給GSP(*.gsp)處理,可以用如下的程式碼。
def forward(page, req, res){
    def dis = req.getRequestDispatcher(page);
    dis.forward(req, res);
}

forward("html_template.gsp", request, response)

技嘉過保固主機板免費換電容

我的Gigabyte GA-K8NE主機板,在Linux伺服器服務已經超過三年,在我退伍前一個月,它掛點了,時常自動重新開機,或出現Kernel異常導致當機。把主機板檢視一下,結果又是電容爆掉惹得禍,這已經是我第二張電容爆漿的技嘉主機板。

為了死馬當活馬醫,我把它送到台中公益路的技嘉直營服務中心,那邊駐店的都是年輕美眉,幸好我不是阿宅,不然應該會常常藉故主機板顯示卡故障。服務人員聽到是電容壞掉,很迅速地告訴我過保固的主機板只換電容不檢測,其他故障原因就不檢測也不維修,原來我在想甚麼她都知道,這種過保的舊主機板都剩沒幾百的價值了,再花個幾百元修它豈不是當冤大頭嘛!

送修回來,看到小小高興一下,原本CPU附近那排阿撒布魯的電容,居然變成一排固態電容,看來這塊版子又可以繼續服役一段時間了。


Windows環境執行Groovy/Groovlet/GSP的編碼問題

在正體中文的Windows系統,預設編碼格式為MS950,Groovy會參考這個預設值,並假設所讀到的Groovy/Groovlet/GSP程式碼都是MS950編碼,基本上儲存成BIG5/ASCII的程式碼檔案,大致上都可以順利讀取,但遇到UTF-8編碼的程式碼檔案,有中文字出現的地方,Groovy還是當作MS950來處理,這時候會出現類似以下的錯誤訊息:

2010/8/6 下午 02:17:18 org.apache.catalina.core.ApplicationContext log
資訊: groovy.util.ScriptException: Could not parse scriptName: /register.groovy
2010/8/6 下午 02:17:20 org.apache.catalina.core.ApplicationContext log
嚴重的: An error occurred processing the request
java.lang.RuntimeException: groovy.util.ScriptException: Could not parse scriptName: /register.groovy
at groovy.servlet.GroovyServlet$1.call(GroovyServlet.java:123)
at org.codehaus.groovy.runtime.GroovyCategorySupport.use(GroovyCategorySupport.java:147)
at groovy.servlet.GroovyServlet.service(GroovyServlet.java:128)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:619)
Caused by: groovy.util.ScriptException: Could not parse scriptName: /register.groovy
at groovy.util.GroovyScriptEngine.updateCacheEntry(GroovyScriptEngine.java:318)
at groovy.util.GroovyScriptEngine.createScript(GroovyScriptEngine.java:398)
at groovy.util.GroovyScriptEngine.run(GroovyScriptEngine.java:385)
at groovy.servlet.GroovyServlet$1.call(GroovyServlet.java:119)
... 15 more
Caused by: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed, /register.groovy: 133: expecting ''', found '\n' @ line 133, column 23.
1 error
at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:296)
at org.codehaus.groovy.control.ErrorCollector.addFatalError(ErrorCollector.java:143)
at org.codehaus.groovy.control.ErrorCollector.addError(ErrorCollector.java:113)
at org.codehaus.groovy.control.ErrorCollector.addError(ErrorCollector.java:125)
at org.codehaus.groovy.control.SourceUnit.addError(SourceUnit.java:352)
at org.codehaus.groovy.antlr.AntlrParserPlugin.parseCST(AntlrParserPlugin.java:80)
at org.codehaus.groovy.control.SourceUnit.parse(SourceUnit.java:248)
at org.codehaus.groovy.control.CompilationUnit$1.call(CompilationUnit.java:143)
at org.codehaus.groovy.control.CompilationUnit.applyToSourceUnits(CompilationUnit.java:772)
at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:438)
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:277)
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:248)
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:243)
at groovy.util.GroovyScriptEngine.updateCacheEntry(GroovyScriptEngine.java:316)
... 18 more

看到紅色的那段字了嗎?Java的錯誤訊息一向都是這樣落落長,只要找重點即可,從錯誤訊息大致上可以""出,就是編碼問題惹得禍。

最快速的解決方法,也是個奧步,就是在啟動JVM之前,加個JAVA_OPTS環境變數設定。
JAVA_OPTS=-Dfile.encoding=utf-8 -Duser.language=en

用file.encoding將預設的檔案編碼指定為UTF-8,而這個奧步引發另一個問題,就是從終端機輸出的所有Java Log資料,有中文的部分就變成亂碼;這樣是另一個故事了,因為M$ Windows的終端機,也假設它執行的程式一定會輸出MS950編碼文字,所以這時候Java程式輸出的UTF-8編碼,又被誤認是MS950的終端機輸出成亂碼。所以再來一個奧步,乾脆將user.language設定為en(英文),Log的中文變少就看不到亂碼了。

其實Java對編碼系統的支援算是挺完善,只是在開發過程中,必須留意不同編碼混在一起可能造成的問題,經常有很複雜的情況,例如讀取BIG5編碼的檔案,在程式中轉為UTF-8處理,最後再輸出時又要以MS950顯示;對CJK(中日韓文)的開發者來說,編碼的問題比較棘手,所以通常在開發階段就會考慮到文字編碼的處理,而EN(英文)系的開發者,就可能忽略了在世界上還有其他使用複雜文字的人類,例如像Sakai這樣大的project,居然有一堆官方發布的程式,只要遇到中文就送你error msg。

身為中文世界的軟體開發者,不懂編碼系統是件誤人誤己的事,如果到了2010年還搞不懂編碼的處理,先讀讀約耳(他是位ABC)的這篇文章《The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)》。

解決Tomcat 6.0的This is very likely to create a memory leak.的錯誤訊息

從Apache Tomcat 5.5升級到6.0,通常不用太大的修改,原有的Web Application就能繼續運作。不過在server.xml中設定MySQL Datasource,卻出現一串惱人的警告訊息:

2010/8/6 下午 01:54:11 org.apache.catalina.loader.WebappClassLoader clearReferencesJdbc
嚴重的: The web application [/] registered the JBDC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
2010/8/6 下午 01:54:11 org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
嚴重的: The web application [/] appears to have started a thread named [Timer-0] but has failed to stop it. This is very likely to create a memory leak.
2010/8/6 下午 01:54:11 org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
嚴重的: The web application [/] appears to have started a thread named [MySQL Statement Cancellation Timer] but has failed to stop it. This is very likely to create a memory leak.

更新MySQL Connector/J至最新版也沒用,似乎是Tomcat 6.0對於Memory Leak的防範變得比較雞婆智慧,才會多了這樣的警告。

既然被列為嚴重程度的警告,當然就不能視而不見,解決的方法並不難,只是要把原本設定在區段中的搬到,修改方式如下。

1. 將<Resource name="jdbc/NAME" auth="Container" type="javax.sql.DataSource" ... /> 整塊剪下,再貼到 <GlobalNamingResources> ... </GlobalNamingResources> 之間。

2. 在原本Resource標籤的位置加入<ResourceLink global="jdbc/NAME" name="jdbc/NAME" type="javax.sql.DataSource" />

如此即可順利解決,其他設定不需要異動。

2010年8月5日

讓Eclipse支援Grails專案開發

安裝EclipseGroovyGrails很簡單,分別只需要幾分鐘時間,下載&解壓縮之後就可以開始用。

但是要讓Eclipse變成Grails的整合開發環境,卻耗費我這兩天不少個小時,找資料、等待慢吞吞的下載,宣告失敗,再重來,陷入無窮迴圈。

Eclipse有很方便的套件管理工具 「Help / Install New Software」 ,但困難點在於要找到合適的 Update Sites設定。

目前的Eclipse最新版本為Eclipse 3.6,代號Helios。

依據Grails IDE Setup官方文件,Eclipse建議的支援工具為STS Integeration,也就是下載SpringSource Tool Suite(STS)。STS目前的最新發行版2.3.2,是以Eclipse為基礎,有Windows/Mac/Linux的32/64位元不同版本,只要填寫那個讓人厭倦的問卷後,就可以下載安裝。

但這個工具並不符合我平日的開發習慣,我喜歡為一個計畫打造專屬的開發工具,好讓計畫中的每項專案都能使用同一套工具,節省不同工具間往返切換浪費的時間及記憶體空間。

目前我以Eclipse 3.6為基礎,已經設定好SVN版本控制、Issue Tracking整合機制等,可以用它來同時開發GUI、Web及Scripting的不同類型專案,自動化地進行編譯、測試、加密、佈署等日常工作,未來也還要再加入資料庫管理、UML及專案進度控管的功能。對我來說,再多一套STS實在很麻煩。

要找到正確的Update Sites設定,好讓我的Eclipse支援STS所提供的Grails Support,這條看似簡單的路似乎走起來滿佈荊棘。

Groovy-Eclipse的安裝比較單純,只要加入以下的Update Site:
GroovyEclipse update site for Eclipse 3.6.n (Helios)
http://dist.codehaus.org/groovy/distributions/greclipse/snapshot/e3.6/

安裝 Groovy-Eclipse \ Groovy-Eclipse Feature 即可。

STS這邊麻煩多了,官網沒啥資料可參考,好不容易找到一份PDF文件,提供幾個Update Sites。

照著做就好了嗎?噢!不。

文件中說只要下載這個XML檔案,Import到Available Update Sites就可以,但用一般的瀏覽器似乎打不開 :X
Eclipse 3.6: http://dist.springsource.com/snapshot/TOOLS/composite/e3.6/bookmarks.xml 

再繼續往下看,似乎又看到了點希望。

自己手動新增這些Update Site總行了吧!
Eclipse 3.6:
• Helios
(http://download.eclipse.org/releases/helios)
• SpringSource Update Site for Eclipse 3.6 (Snapshot)
(http://dist.springsource.com/snapshot/TOOLS/update/e3.6)

• SpringSource Update Site for Eclipse 3.6 (Snapshot, Dependencies)
(http://dist.springsource.com/snapshot/TOOLS/composite/e3.6)

只是結果再度令人失望,被刪掉的紅字就是無法使用的位址。

再SpringSource Team Blog的一篇網誌中,提供另一個for Eclipse 3.6的Update Site,似乎看到答案了。
SpringSource Update Site for Eclipse 3.6 (Milestone)
http://dist.springsource.com/milestone/TOOLS/update/e3.6

這一次順利找到 Extensions / STS \ SpringSource Tool Suite Grails Support ,安裝時下載雖然慢了點但最後是完成了。

安裝後再建立新專案時,會多出 Groovy \ Grails Project 選項。

這個不太順利的過程,領悟了兩件事,(1) 學網連結SpringSource網站的速度慢到讓人吐血,還時常連不上,Grails的網站也是同樣情況;(2) Java的資源真是讓人難以捉摸,討論區和網誌似乎才是真正的官網。
lyhcode by lyhcode
歡迎轉載,請務必註明出處!