2009年12月29日 星期二

PLT-Scheme and Apache

結合 PLT-Scheme Web server 和 Apache 時,使用以下的 Rewrite Rule 於 Apache 的 VirtualHost 中。

        RewriteLog /home/ccwu/rewrite.log
        RewriteLogLevel 9
        RewriteEngine on
        RewriteRule ^/play(.*)$ http://localhost:8000/play$1 [P]

其中的 RewriteLog 及 RewriteLogLevel 是為了除錯。RewriteEngine on 是必須的,每個 VirtualHost 的 Rewrite engine 都必須各別致能,這是基於安全考量。

但是 Apache 告訴我我沒有權限使用 http://localhost/play。
檢查 apache 的 error log ,參考網上的討論後,將 mod_proxy 及 mod_proxy_http 致能後問題得以解決。

2009年12月27日 星期日

sysctl IPV6_V6ONLY

前些日子在我的 Debian 機器上無法以 Java 連上網路。上網查詢後原來更新 netbase 後增加了一個新的 sysctl 選項。

cat /etc/sysctl.d/bindv6only.conf 
可以見到 net.ipv6.bindv6only = 1
這選項使得 ::ffff::ip 不再被接受,而 ::ffff::ip 卻是 java 
的預設。

2009年12月25日 星期五

Continuation 之不可或缺

Continuation web server 真的比較好嗎?依我最初使用 Javascript 加 Helma NG 及後來使用 PLT Scheme 的感覺來看,使用 Continuation 的確使得我不必太去操心網路 stateless 的本質,從而提升了程式開發的流暢感。

這只是模模糊糊的隱約覺得...

這幾日,遇到了問題,瀏覽網頁時常過期。這可嚴重了,使我從新思考是否要放棄 Continuation style。我改寫了部份程式,使用當初以 Helma NG 撰寫的方式。起初容易,最後困難,原本不關心伺服器和瀏覽器間要傳送什麼資料的,現在開始必須歩歩為營,考慮哪些資料需要 serialization 。

而目前這伺服程式還算簡單 ...,如果繼續發展下去,不使用 Continuation 恐會使得這遊戲的開發工作超出我一個人休閒時的工作份量了。

這使得我體會到 Continuation 對我這類網路應用的不可或缺。

2009年11月1日 星期日

Scratch 和 Google App Inventor

一種為小孩子設計的語言:Scratch

這樣的語言,及發展環境,也是我的夢。

Google 的 App Inventor 也提供了類似 Scratch 的開發環境,但是內部使用的語言是 Scheme。

Kawa

以 Java 寫成的 Scheme,可以在 JVM 上執行。因此我忍不住將它和 plt-scheme 及 rhino 比較,以瞭解它的優劣定位。

相較於 rhino:
  1. 同樣可在 JVM 上執行。
  2. 援用 java 的 class 時,沒 rhino 那麼方便,必須定義要使用的 method,若使用某個 method 眾多的類別如 JOGL 時,會帶來一些困擾。
  3. 因為是 scheme,比 rhino 更適用於開發 Domain specific language (DSL)。
相較於 PLT-SCHEME
  1. 可在 JVM 上執行,因此,可以和使用 rhino 的程式整合在一起,提供 rhino 欠缺的 DSL 能力。
  2. 缺少 PLT-SCHEME 的龐大功能及其健康的社群。
Kawa 被用於 Google 的 App Inventor,被使用的原因就是因為 Scheme 的 DSL 能力。

依我的觀點,Scheme 的 DSL 能力最適合用在當 Domain specific language 尚未定型,正在成長時。

javascript 和 OpenGL

在學習使用 javascript 透過 java 執行 OpenGL 時,我採用 Wikipedia 中 "Java OpenGL" 這一條文的例子。但是執行時出現了以下錯誤訊息:

Exception in thread "main" java.lang.UnsatisfiedLinkError: no gluegen-rt in java.library.path

參考網路上的說明,UnsatisfiedLinkError 意指少了某個 .so 檔,在此為 libgluegen-rt.so。查詢結果這檔案位於 /usr/lib/jni 中,在 java 命令後加上 -Djava.library.path=/usr/lib/jni 後問題得到了解決。

2009年10月31日 星期六

rhino-debugger

目前我的網路遊戲是以 plt-scheme 寫成,有以下兩個原因使得 plt-scheme 難以被取代:
  1. 它的 at-exp 容易讓我描述遊戲的劇本。
  2. 它的 continuation based web server 使得我容易撰寫遊戲的流程。
但未來遊戲若要做成 GUI 的形式,我會期待用 javascript 完成。此時,我會選擇以下的工具:
  1. rhino, 以 JAVA 實現的 javascript interpreter。
  2. JAVA 的 Swing。因為它的無所不在,因為 Java Web Start。我不選擇 Eclipse 的 SWT,並不是有 JAVA 的地方就有 SWT。
 為未來做準備,我因此必須多瞭解一點 rhino,以及 JAVA。以下是我今日拜訪的連結:
Rhino + Javascript + Swing, Look Ma no Java ,很好,這樣短短的一篇,就給了我一個好開頭。

依據這篇文章,我寫了以下小小的 GUI 程式於 launch.js 中,以 rhino launch.js 成功地執行。

importPackage(Packages.javax.swing);
importPackage(Packages.javax.swing.border);
importPackage(Packages.java.awt.event);
importPackage(Packages.java.awt);
importPackage(Packages.java.util);

importClass(Packages.java.beans.EventHandler);

function runApp() {
        var lframe = new JFrame("MapaView");
        lframe.setSize(500, 400);
        lframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        var panel = new JPanel();
        panel.border = BorderFactory.createEmptyBorder(30, 30, 10, 30);
        panel.setLayout(new java.awt.GridLayout(0, 2, 10, 10));
        var exitButton = new JButton("Done");
        exitButton.addActionListener( function() {
                java.lang.System.exit(0);
        });

        panel.add(new JLabel("done yet?"));
        panel.add(exitButton);

        lframe.add(panel);
        lframe.pack();
        lframe.show();

}
runApp();

此外,我也瞭解了一下 rhino-debugger。rhino-debugger 這命令在 Debian Linux 下是一個 script 檔。閱讀後多多少少讓我知道要如何呼叫 Java。呼叫 Java?唉,是啊,我完全不懂 Java,我不屬於新生代的軟體工程師了。

2009年10月23日 星期五

Functional Programming

使用 PLT Scheme 撰寫遊戲至今,我完完全全體會到 functional programming 的表達力。在我的程式中,現在到處是 map 及 lambda。而且,setter 的使用也減少許多。
不過,我寫遊戲的方式是有點瞎子摸象方式的,沒什麼事先的設計規劃。完全是玩玩改改。目前這樣做的進展很快。但能持續到何時,可維護性如何,我還沒有把握。

2009年10月20日 星期二

Chat and Wiki for Scheme.

台灣很少有和 Scheme 這種語言有關的資訊。既然我目前使用 Scheme 做為我開發遊戲的語言,我就將這部落格做為我提供 Scheme 相關資訊的平台。

由於需要,我搜尋是否有以Scheme實現的 wiki ,發現了以下網頁。

http://practical-scheme.net/

在網頁中有個 WiLiKi 從開發的歷史來看,這 Wiki 從 2001 年到 2009 都有開發的活動。因此我粗淺地斷定這作者不會放棄這個 Wiki 軟體的開發,因此值得信賴。

在這網頁中還有個 chat room 的軟體,這也讓我頗感興趣。

2009年10月18日 星期日

Continuation Web Server works great!

將原本以 javascript 及 Helma NG 寫成的遊戲程式以 PLT Scheme 改寫,使用 PLT Scheme 的 Web server,我發覺 Scheme 的 continuation 真的是撰寫動態網頁的利器。使用 javascript 時,點選遊戲中某個容器的物件,必須將這物件的 id 變成網頁上連結的參數,這樣點選物件時才能將這 id 回傳給 server,server 才知道點選的是哪一個物件。這也使得網頁的設計和 model 密不可分。但是使用 continuation 時這件工作就省下來了。在網頁上的連結對應的就是處理那物件的 continuation。我在撰寫這部分程式時根本就很少關心網頁要傳什麼資料給 server 的問題。

Continuation 實在太神奇了!

2009年10月16日 星期五

Continuation or not continuation

在瞭解了 Continutaion 在 Web development 的應用後,我以為 continuation 只適用於部份的Web程式。這時,就不得不覺得 PLT Scheme 的文件中對不使用 continuation 的 Web development 方法討論太少了。

以下的文章反應了我的想法,也提供了另一種以 PLT Scheme 撰寫 Web applications 的 tutorial:

2009年10月15日 星期四

Model-View-Controller 及 Continuation II

重新思考 WEB 程式開發中使用 Continuation 和 Model-View-Controller 之間的關係。我決定回到物件導向設計的基礎,Robustness,不再勉強套用 MVC 這隻鞋子。為了 Robustness,Model/View/Controller 的區分還是有價值的。但是使用 Callback 及 Event-loop 實現 View 這個概念就不一定有價值。

Model-View-Controller 及 Continuation

PLT Scheme Web Server 是一種 Continuation based Web Server。HTTP 的 stateless 特性使得某類網路應用程式難以撰寫。而 Continuation 可以解決這類的問題。

但是初次接觸 Continuation based Web Server 的我對這種程式的寫法不無疑問。在當初以 javascript 及 Helma NG 撰寫我的遊戲軟體時,我採用的是 page oriented 的撰寫方式,這樣的撰寫方式很自然地和 Model-View-Controller 的理念對應。但是當我以 Continuation 來撰寫時,還摸索不出如何做到 Model-View-Controller 的方法。

以我游戲中的一個場景為例。這場景秀出一段文字,之後給玩家三個選項,玩家點了選項後會跑到另一個場景,因此網頁上和這選項對應的連結必須指出將要到哪一個場景。如果使用 Continuation,產生 html 的 function (View) 必須知道這連結要執行哪一個 function (Controller),以產生那個 function 的 continutaion。但這使得 View 必須知道 Controller。再者,如果那個被連結的 function 會使用到產生 html 的 function 的 local 資料或引數,則那被連結的 function 還必須在產生 html 的 function 的 local 中定義。結果 View 和 Controller 無法分開放在兩個不同的 modules。

在 GUI 還不盛行的時代,撰寫交談式程式的概念十分簡單,就是先印出問題等待使用者回答,使用者回答後再根據使用者的回答進行處理。GUI 的複雜度使得我們必須使用 MVC 這樣的概念。程式流程的控制權轉到了使用者的手裡。但至少 VIEW 和 Controller 都還在同一台電腦上,資料得以互通。到了網路時代,WEB 程式的撰寫更為困難,因為人機界面落在另一台電腦,在伺服端的程式並不知道使用者正在觀看哪一個畫面。當使用者下命令時,伺服端程式只能從 request 來猜出使用者的要求,沒有 continuation 的設計時,request 內只有這次要求的資料,看不出過去要求的歷史,無法處理複雜的,必須依據使用者過去瀏覽的歷史處理的運算。

這樣說來,如果 Continuation 能把事情簡化到最早期的程式撰寫方法,則 MVC 的概念並不是一定必要的。

2009年10月11日 星期日

Macro 的不可或缺

原本我的遊戲是以 javascript 寫成。在研讀過 PLT Scheme手冊後,我開始以 scheme 改寫我的遊戲軟體。 這樣做的原因主要是我欣賞 PLT scheme 中提供的 @-exp 語法。這語法類似 XML,適合用來描述遊戲的劇本,又和 scheme 完美整合。

將劇本以 @-exp 改寫後,我發現 macro 的重要性。以下是我劇本的一個片段:

@novel["家變"]{
  @room["書房"]{
    @scene["牆壁"]{
      你面對一面白色牆壁。牆壁上有條裂縫。向上直達天花板。
      @next["檢查裂縫" #:scene "裂縫"]
      @next["檢查天花板" #:scene "天花板"]
    }
    @scene["天花板"]
      天花板有點潮溼。
    }
    @scene["裂縫"]{
      裂縫中有隻螞蟻。
    }
  }
}

面對這樣的劇本,有兩種作法:
  1. novel 是 scheme function。此時,因為 room 會比 novel 早執行,因此,在執行 novel 前必須先建造一個名為 current-novel 的物件,或是使用一個 global 的物件,以存放 room 產生的資料。這使得劇本必須做小修改,而撰寫劇本的人,很可能不是一位程式設計師,必須操心這些小修改。
  2. novel 是 scheme macro。由於使用 macro,可以將建造 current-novel 的工作包括在 macro 的設計中,因此,撰寫劇本的人就不必操心這些問題。
我沒想到的是,單單劇本撰寫這樣原本以為簡單的工作,竟然也涉及到 macro 的撰寫,也因此體會了 macro 強大的能力。

在設計劇本的描述語言時,我也感受到 scheme 的 keyword 帶來的好處,以以上的劇本為例,在 next 中我使用了 #:scene 這個 keyword,它使得劇本更容易閱讀。

一個讓我驚訝的事是,我目前感受不到 PLT-Scheme 的 define-struct 的好處。原本我使用 (define-struct novel (name)) 來建立 novel 這結構,但最後我改成如同我原本使用 javascript 的作法,使用 hashtable,同時參考 SICP 的作法 來解決。

2009年9月17日 星期四

PLT-Scheme Contracts

一歩一歩讀著「Guide: PLT Scheme」,讀到 PLT Scheme 的 Contracts。我使用 Eiffel 的 Design by Contract 多年。感到 PLT Scheme 的 Contracts 設計過於瑣碎。缺少 Eiffel 的簡單明瞭容易使用。

但是 PLT Scheme 的支持者說 PLT Scheme 的設計是健全的。我不禁好奇又感到懷疑。Behavioral Contracts and Behavioral Subtyping 嘗試說明 Eiffel 的問題。但顯然文章的作者不瞭解 DbC。DbC 的設計,在繼承的子類別處,precondition 可以放寬, postcondition 則必須更緊縮。這文章不同意 DbC 的看法。舉了以下例子:J 繼承 I。J 和 I 都有一個函式 m (x)。m 的引數 x 在 I 中的要求是 x>0。在 J 中的要求是 x > 10。於是 Eiffel 的 DbC 認為使用 J 的 m 時 x 可以為 5。但這篇文章認為不行,使用 J 的 m 時 x 必須大於 10。我同意 DbC 的作法。J 是 I  的繼承者,必須繼承 I 的責任和義務。在 I 中認為只要 x > 0 就有資格使用 m 這個函式時,J 的函式設計就必須滿足這條件,否則,J 不應該繼承 I。J 中的 m 寫著 x > 10。只是說明 J 中的 m 承諾在 x > 10 時可以使用 m。透過繼承 J 還同時承諾了 x > 0 時也可以使用 m。因此,雖然 x > 10 這條件有點多餘,但不表示它是錯的。

這讓我對 PLT scheme 的 contracts 設計感到失望,也許這就是為何 PLT Scheme 一直無法推出 Class 的 contracts 的原因:他們根本想錯了。

2009年9月6日 星期日

風雨將至?Scheme 來援?

出於興趣,工作之餘,我撰寫網路游戲,透過這努力,我吸收新的,工作以外的專業技術。這是必須的,因為,工作的內容常一成不變,以致於人無法單靠工作成長。在技術瞬息萬變的軟體世界,不成長就等著被淘待。在休閒時撰寫網路游戲,使我能任意選擇我想要學習的技術,也沒有工作上必須完成的壓力,能依自己的狀況或快或慢,漸進地成長。

雖說技術瞬息萬變,但值得學習的常常是那些老舊的東西,那些老舊但又能持續推陳出新的東西。在此我指的是一種古老的語言:Scheme。我在前幾天發現 PLT Scheme 提供了 Web Server。

對於 Scheme 這語言,我早充滿好奇。一直沒能派它上用場,只能止於欣賞,無緣深入。我開始撰寫網路游戲時,未曾考慮它。我使用 Javascript,另一個我以為值得學習的語言。我以 Helma NG 為我開發的平台。在這過程中,我停歩了。我發覺自己需要一個 DSL以撰寫游戲的腳本。我考慮自行設計,或直接用 Javascript,前些時決定用 jLINQ+JSON。這組合總算初歩滿足我的需求。不幸,撰寫工作還是一停在停。

「一定是在哪兒有問題,讓游戲的撰寫工作少了一種流暢感。」我心想,「可能游戲複雜度將至的警訊。」

這流暢性的缺乏來自我的游戲中需要有能和資料完美結合的 DSL。但 Javascript 或 jLINQ 或 JSON 並不適合。

這時發現 PLT Scheme 提供了 Web Server 讓我十分開心。我打算以 Scheme 改寫游戲,評估它的實用性。希望這次能讓我進入 Scheme 的領域。

2009年7月28日 星期二

AWS 的 EBS 和 snapshot

EBS 相當於 RAID,提供比一般硬碟還可靠的儲存能力。
使用 EBS 的一個好習慣是:
  1. 結束一個 instance 時,就做一次 EBS 的 snapshot。同時,刪除 EBS。
  2. 要啟動一個 instance 時,從 snapshot 重建一個 EBS 來使用。
  3. 要做 snapshot 前要先停止 application, umount EBS, 以免在產生 snapshot 的過程中 EBS 上的資料還在變動。
如此的好處是:
  1. 不必在未使用時佔用一個 EBS。省錢。
  2. 新建的 EBS 可以配合 instance 的 availability zone。

2009年7月26日 星期日

Domain Setup with DNSMadeEasy

依以下指示在 DNSMadeEasy 設好給 Elastic IP 用的 DNS Server。
Domain Setup with DNSMadeEasy
在 DNSMadeEasy 使用我在 Yahoo 的 email 名為 user name。

第二個 AMI

建了第二個 AMI,以 alestic/ubuntu-8.10-intrepid-base-20090614.manifest.xml 為基礎。並安裝以下軟體:

apt-get install sun-java6-jdk ant git-gui rhino user-setup

安裝後移除了 package cache 以簡省空間。

不安裝 Destop 軟體,它只是一個單純的 server。

這次學乖了,並未以 user-setup 建立任何 user。保持 AMI 的乾淨,只在起動 instance 後才臨時建立一個 user。這臨時建立的 user 名稱和密碼可以隨便給。因為它用一次即丟。

建立了第一個 AMI

閱讀 EC2 的 Getting Started Guide

學到以下:
  • 閱讀了Web Services Tutorial。Web Services 的基礎是 XML+HTTP。Web Services 的平台是 SOAP、UDDI、WSDL。
  • 下載了 ec2 api tools 及 ec2 ami tools。
  • 以 ssh 連上時要檢查 finger print 是否和起動 AMI 時 instance output 顯示的 ssh host finger print 相同,以避免 "man-in-the-middle" 攻擊。
  • 設 JAVA_HOME=/usr/lib/jvm/java-6-sun/
  • 設定 .ec2 環境。
  • 最後,建立了自己的第一個 AMI ami-novplay/myimage.manifest.xml

2009年7月25日 星期六

更簡單的安裝 EC2 AMI 中文的方法

在 ssh 及 apt-get update 及 user-setup 之後,以NX登入。
再選擇 Language support。

之後可以以 sudo 執行以下命令執行 helma ng:
apt-get install sun-java6-jdk ant git-gui
git clone git://github.com/hns/helma-ng.git
cd helma-ng; ant jar
export PATH=$PATH:`pwd`/bin
helma apps/demo/main.js

建立 中文 AMI

在起動了一個 AMI 後:

ssh -i xxx.pem ec2-user@public_DNS
user-setup

以下的命令可以以透過新的 user 使用 sudo 執行。

apt-get update && apt-get -y upgrade
apt-get install language-pack-gnome-en language-pack-en
apt-get install language-pack-gnome-zh language-pack-zh
dpkg-reconfigure locales
vim /etc/default/locale; set LANG=zh_TW.UTF-8
vim /etc/environment; set LANGUAGE=zh_TW:en_US:en, LANG=zh_TW.UTF-8, PATH
apt-get install scim-chewing scim-tables-zh
apt-get install sun-java6-jdk ant git-gui user-setup
user-setup
git clone git://github.com/hns/helma-ng.git
cd helma-ng
ant jar
export PATH=$PATH:`pwd`/bin
helma apps/demo/main.js

如此,可以顯示中文了。

部份需要 root 權限的工作可由自建的 user 使用 sudo 來做。

2009年7月24日 星期五

EC2 的下一步

下一步工作是:

製作一個 AMI。
和 EBS 結合。

EC2 中文

中文問題部份解決。

首先我將 /etc/default/locale 中的內容改為 zh_TW.UTF-8。

同時安裝輸入法 apt-get install scim-chewing scim-tables-zh

在編譯時我按右鍵選擇輸入法為 SCIM。

但是如此仍不能使許多應用程式的顯示改為中文。同時,Helma NG 也一樣不能處理中文。

執行 apt-get install language-pack-gnome-zh language-pack-zh 之後,大多數的應用程式都顯示中文了。同時,似乎也不必再按右鍵來選輸入法。而且,Helma NG 也可以正確顯示中文了。

在以下文章中說明 ubuntu 的中文安裝方法。但文中的 dpkg-reconfigure locales 似乎必須在安裝好 language-pack 後做才有效。

http://www.linuxdiyf.com/bbs/thread-87072-1-1.html

EC2 and NX

遵照以下文章起動一個 ubuntu EC2 instance。並且使用 NX 連上。和文章中唯一不同之處是我找不到 “AMIs and Instances” tab ,因此使用 AWS Management Console 來起動。

How to run a quick-throwaway ubuntu EC2 instance

還必須學會如何安裝中文,並且自定 AMI。

此外,以下文章也給我很大的鼓舞。
Amazon's AWS: EC2, EBS, S3, etc.


第一次登入還沒密碼時使用
ssh -i keypair.pem ec2-user@ec2-public-DNS

之後要執行 apt-get update 才能有完整的 package list,之後才能安裝 jdk。

比較 ubuntu 和 debian ,也許是因為 ubuntu 的更新較頻繁,upgrade的時間明顯短了許多。同時,為了和我自己的 desktop 區別,我打算在 AWS 上安裝 ubuntu。這也能減少傳輸的費用。

在安裝了 jdk, ant 及 helma-ng 後,可以執行 http://localhost:8080/。如果要能從外界透過 port 8080 連上,還必須在 security group 中開啟 tcp port 8080。

apt-get install sun-java6-jdk ant git-gui user-setup
user-setup
git clone git://github.com/hns/helma-ng.git
cd helma-ng
ant jar
export PATH=$PATH:`pwd`/bin
helma apps/demo/main.js


慢慢來。

2009年7月23日 星期四

App Engine 的 _ah/admin 無法秀中文

App Engine 在 local 的資料可以透過 http://localhost:8080/_ah/admin 來觀察。
問題是,當資料是中文時,無法正確顯示。這使得在開發初期要瞭解程式是否正確變得困難。這個問題不是我能解決的。

在面對這麼多 App Engine 的中文化問題後,我開始思考 EC2 是不是更好的選擇。至少在開發的初期,它可以做得和我的系統完全一致。

和 App Engine 不同。Scalability 和 Load balancing 是我走 EC2 這條路要克服的問題。

2009年7月22日 星期三

Javascript 的 Google trend

使用 Google trend 瞭解了一下 javascript 的情況。
Javascript 的 Google trend
有趣,在新聞中,Javascript和PHP的報導率從今年初開始已經併駕齊驅了。雖然查詢 PHP 的人的數量仍遠多於 Javascript 。結論:有人在炒作 javascript 。難怪我會在今年學 javascript 。

哈哈。

2009年7月21日 星期二

從 Helma NG 到 Jack

為了瞭解為何 Helma NG 無法顯示中文,我繼續走在探索道路上。

我必須瞭解 Jack 。因為 Helma NG 架構在 Jack 上。

我試著執行一下 Jack。只是修改它的 jack/examples/example.js ,加幾個中文字。結果 Jack.Lint 告訴我 Error: Content-Length header was 24, but should be 20 。

我想是 Jack.Lint 的 bug 。

不禁嘆息。看來 javascript 的中文之旅還在初階段呢。

有趣的是,看 jack 的寫作風格和 Helma NG 是完全不同的。

Helma NG 0.4 在 App Engine 上無法顯示中文

很不幸的。無法顯示中文。這迫使我必須瞭解原因。為了瞭解原因,我必須學很多本來不必學習的東西。

本來,我的計劃只要使用 Helma NG 和 javascript 就能搞定。現在,我必須探就 Helma NG 的底層,瞭解到底發生了什麼事,為何 java 可以正確顯示中文,而建立在 Java 之上的 Helma NG 卻不可以。

我先瞭解 rhino 及 app engine 的關係。以免被 Helma NG 的複雜性嚇到。以下這篇文章,給了我一個不錯的開始。

Javascript on Rhino on Java on App Engine

這時開始感到困難了。

我不會 Java。

又回到了年輕時什麼都不會的時候。

努力之後,我學會了:
  1. 使用 Eclipse 的 Project->Property 來增加一個 jar file。
  2. 在 src 中增加一個新的 .java 檔。
  3. 如何 embeds rhino
  4. 使用 FileInputStream 及 InputStreamReader 來讀取 .js 檔,以便設定 encoding。FileReader 雖然較容易用但無法設定 encoding 。
  5. ContentType 要加上 charset=UTF-8。
It works!! 我寫的小小的 Rhino Servlet 可以在 App Engine 上顯示中文了。

核對 Helma NG 的程式,其 file.js 及 MarkdownProcessor.java 都使用 FileReader。這應該就是 Helma NG 無法在 App Engine 顯示中文的原因。

2009年7月17日 星期五

Helma NG 和 Javascript

=== 2009/07/17 ===
檢視去年的文章,今年的發展有很大的不同:
我開始學習 javascript ,並且使用 Helma NG來設計我的第一個網站。一個文字遊戲網站。