2013年12月29日 星期日

GWT 的 AutoBean

AutoBean 是目前打算拿來在 GWT 中處理 JSON 的工具。 不過在講正事之前,先扯兩段雜談 [毆飛]

雜談 1:這樣也可以?

要不是要弄 web API,其實也不會想碰 JSON, GWT RPC 好好的幹麼弄什麼 JSON [遠目]。 不過 server side 要處理 JSON 其實有 GSON, 正常 encode / decode 真的都還蠻簡單的, 簡單到不知道能介紹什麼 XD。 是說 LaPass(ptt.cc)因為有一個我覺得有點詭異的需求, 結果挖出了 TypeAdapterFactory 的用法, 看起來真的很乾淨很炫(炫到都快看不懂了 [遮臉]), 只能說好 library 如當是也。

理所當然的,會想看看有沒有 GWT 版的 GSON, 結果看到 bGwtGson 這玩意差點噴出來。 因為他的作法是用 GWT RPC 把東西丟到 server side, 這樣 server side 就有 GSON 可以用了… 揪咪…

我都不知道該說牛逼還是坑爹,這世界果然很廣大阿 [握拳]

喔對,順帶一提,GSON 在 AppEngine 上也可以使用。

雜談 2:謎樣裏技?

我搞不太懂 AutoBean 在 GWT 當中扮演什麼樣的角色? 彷彿還蠻多人在用的(因為大家都炸同樣的問題… Orz), 但是官方指南似乎沒有這個東西(JavaDoc 當然還是有), 教學文件只有出現在 google code 的 wiki 上, 所以這是裏技嗎?

我比較怕這是即將被拋棄的裏技 Orz

畢竟要在 GWT 裡頭處理 JSON 並不是太麻煩。 官方指南建議的 JSNI / Overlay Types 寫起來堪稱簡單直覺, 尤其是跟 AutoBean 相比的話 [死]。 再不然 GWT-Jackson 好像也是種選擇?

剛好兩者的風格我都不愛 [淚目]

最大的哏在於 AutoBean 並沒有辦法直接處理 List<T> 這種東西, 這個 bug 在 2011.10 被提出之後, 2012.11 最後一個 comment 之後就無聲無息了, 目前最新的 GWT 2.5.1 還是有同樣的問題 Zzzz,只能靠 workaround。 後頭會詳述這些事情 [死]。

怎麼用?

好了,終於要進入正題了。 [握拳]

GWT 已經內建 AutoBean,所以不用另外掛 jar 檔, 但是要在 gwt.xml 當中補上:

<inherits name="com.google.web.bindery.autobean.AutoBean"/>

如果你要把下面這個 JSON 字串轉成 Foo 的 instance

{
    "uid":"cde6c847-d072-4d33-82bd-93fa4710dc9b",
    "limit":50,
    "deleted":true,
    "update":1388157386000
}

首先… Foo 得是個 bean 的 interface,定義一堆 getter/setter, 名稱得跟 JSON 裡頭的一致:

interface Foo {
    public void setUid(String uid);
    public void setLimit(int limit);
    public void setDeleted(boolean deleted);
    public void setUpdate(Date update);
    public String getUid();
    public int getLimit();
    public boolean isDeleted();
    public Date getUpdate();
}

轉換的時候需要先建立一個 factory,通常會這樣寫

interface MyFactory extends AutoBeanFactory {
    AutoBean<Foo> foo();
}
MyFactory factory = GWT.create(MyFactory.class);

然後… 終於可以 decode 了:

String foo = "{" +
        "\"uid\":\"cde6c847-d072-4d33-82bd-93fa4710dc9b\"," +
        "\"limit\":50," +
        "\"deleted\":true," +
        "\"update\":1388157380000" +
    "}";
Foo instance = AutoBeanCodex.decode(factory, Foo.class, foo).as();

encode 的話就是:

String fooJson = AutoBeanCodex.encode(
    AutoBeanUtils.getAutoBean(instance)
).getPayload();

如果願意在 MyFactory 裡頭加一個 method:

interface MyFactory extends AutoBeanFactory {
    AutoBean<Foo> foo();
    //下面這個是新增的
    AutoBean<Foo> genFooBean(Foo foo);
}

那不用 AutoBeanUtils.getAutoBean() 而是

String fooJson = AutoBeanCodex.encode(
    factory.genFooBean(instance)
).getPayload();

有沒有比較快樂就見仁見智,不過後面會需要用到後面這招, 或著這麼說比較實在: 「請忘記 AutoBeanUtils 吧」。

注意事項

如果到這邊你還能忍受 AutoBean, 那先講幾個我已經炸到,但可以理解的哏, 主要是跟 GSON 的差異。

  1. Gson.toJson() 遇到 false / null 值不會省略該 field, 但是 AutoBean 會。 也就是說,如果 foo.setDeleted(false);, 那麼 AutoBeanCodex.encode() 出來的字串不會看到 deleted

    當然,這其實不妨礙正常運作。 GSON 的作法可能有些人還會覺得怪?

  2. 日期(java.util.Date)的處理。 Gson.toJson() 會用 Date.toString() 作值(反之亦然), 但是 AutoBean 則是用 Date.getTime()(反之亦然)。 只能說還是統統用 long 表示日期就算了 (然後在 JSON 當中最好還把這數字當成字串, 免得像 32bit 的 PHP 還給你耍花招 [怨念ing])。 至於 Joda 要解決的議題… 遇到再說 XD

有遇到會再補上來 Orz

List 的炸點

如果你永遠不會 decode / encode 一個 array 或是 List, 那恭喜你,除了寫法稍稍扭曲一點之外, AutoBean 是可以接受、也算好用的(應該啦…)。

實際上… 別鬧了,怎麼可能不處理 List

於是 AutoBean 就成了茶几──上頭擺滿了悲劇。

decode

GSON 吐出來的東西來看,一個 List<Foo> 的 instance 會長這樣 (喔對,我把 update 的型態改成 long 了 XD):

[
    {"uid":"cde6c847-d072-4d33-82bd-93fa4710dc9b",
     "limit":50,"deleted":false,"update":"1388157380000"},
    {"uid":"a391dedf-1f81-4380-a712-59eac4d9aea3",
     "limit":50,"deleted":false,"update":"1388157380000"}
]

想依樣畫葫蘆比照辦理時… 等等,AutoBeanCodex.decode() 的第二個參數要給什麼? 然後於是有人弄出了這個 workaround

首先,要建一個 interface 來代表 List<Foo> 這玩意:

interface FooList {
    public void setList(List<Foo> list);
    public List<Foo> getList();
}

factory 的 interface 則是:

interface MyFactory extends AutoBeanFactory {
    //下面這個暫時用不到
    AutoBean<Foo> genFooBean(Foo foo);

    AutoBean<FooList> fooList();
}

最後,要對拿到的 JSON 字串動手腳,變成這樣:

    FooList fooList = AutoBeanCodex.decode(
        factory, FooList.class, "{\"list\":" + foo + "}"
    ).as();
    List<Foo> instance = fooList.getList();

簡單地說,就是 Java 的部份你要讓他有個 class 為依歸, 但是光這樣還不夠,因為 AutoBean 不知道要從何處理起, 所以 JSON 的部份你也要偽造一下……

等等,還沒完,好戲壓箱底、好酒沈甕底, encode 的部份那才叫經典。

encode

要把一個 List<Foo> 轉成 JSON,這到底是有多難? 不難,如果把剛剛 AutoBeanCode.decode() 出來的 fooList 再次轉成 JSON, 那麼只要 factory 加上

interface MyFactory extends AutoBeanFactory {
    //下面這個暫時用不到
    AutoBean<Foo> genFooBean(Foo foo);

    AutoBean<FooList> fooList();
    //下面這個是新增的
    AutoBean<FooList> genFooListBean(FooList instance);
}

立馬就轉,沒有問題!(也完全沒意義 ==”)

AutoBeanCodex.encode(
    factory.genFooListBean(fooList)
).getPayload();

如果是把既有的 List<Foo> instance 轉換, 依照上面的邏輯,得先實做那個毫無意義的 FooList

FooList fooList = new FooList() {
    List<Foo> list = new ArrayList<Foo>();

    @Override
    public void setList(List<Foo> list) {
        this.list = list;
    }

    @Override
    public List<Foo> getList() {
        return list;
    }
};

//FooImpl 就容許我跳過,反正就是 implements Foo 的東東
fooList.getList().add(new FooImpl());

AutoBeanCodex.encode(
    factory.genFooListBean(fooList)
).getPayload();

執行上面這段程式碼,你就會發現 AutoBeanCodex.encode() 快樂的炸了 NPE,而且完全搞不懂發生了什麼事情。

這是個已知的 bug(Issue 6904), 雖然不知道會不會有人去解…… Orz。 而世界還真的是很廣大,有人也找出了 workaround, 解法就是你不能直接丟 FooImpl 的 instance, 得用 MyFactory.genFooBean() 產生出 AutoBean<Foo>, 再藉由它(as())取得 Foo 的 instance 才可以…… 寫的我自己都亂了,看 code 比較實在:

interface MyFactory extends AutoBeanFactory {
    AutoBean<Foo> genFooBean(Foo foo);
    AutoBean<FooList> fooList();
    AutoBean<FooList> genFooListBean(FooList instance);
}

fooList.getList().add(
    //原本是 new FooImpl()
    factory.genFooBean(new FooImpl()).as()
);

AutoBeanCodex.encode(
    factory.genFooListBean(fooList)
).getPayload();

套最近流行的句型: 「如果這不叫脫褲子放屁,我還真他媽的不知道什麼才叫脫褲子放屁」

喔對,無論 genFooBean() 還是 genFooListBean() 都不能用官方文件用的 AutoBeanUtils.getAutoBean()。 如果拿他替換 genFooBean(),一樣噴 NPE; 如果拿它替話 genFooListBean(),不會噴 NPE, 而是轉換出來的 JSON 字串會是 null。

WTF

結尾 murmur

GSONAutoBean 相比是很有趣的。 一個是完美到不需要瞭解內部到底發生什麼事情, 一個則是太糟糕了,所以根本不想瞭解。

短時間之內,我可能還是不會放棄 AutoBean, 除非 GWT 2.6 就遺棄 AutoBean, 或是找到更好的 tool(而不是 GWT-Jackson 那種 style)。 都花了這麼多時間了,就看看能被炸到走到什麼程度。

寫到後來,都不知道到底是在介紹推廣還是在吐槽。 只能說,嗯… 我對 GWT 真的很有愛…… [遠目]

2013年12月15日 星期日

2013 年 GWT 調查報告中文摘要

原始報告請到 http://vaadin.com/gwt/report-2013 下載(要輸入 EMail 帳號)。 除了序言之外,其餘都只翻譯數據跟(個人認定的)重點,非逐句翻譯。


序言

在 2012 年第一次作 GWT 狀況調查 時,收到的回覆數量淹沒了我們。 我們把調查報告取名為《The Furture of GWT》(譯名:GWT 調查報告), 因為我們想知道「GWT 衰老中」這個謠言到底有多少可信度。 在超過 1300 個回應裡,我們、以及全世界都看到了 GWT 活蹦亂跳的樣子。 許多大型企業用 GWT 來建構大型的 application, 對 GWT 投注的資源也在增加。

在《GWT 調查報告 2013 版》中, 我們想要知道 GWT 未來該如何發展?(第六節) 開發團隊在用什麼 Java 跟 GWT 的版本?以瞭解 哪些地方需要支援?(第四節) 你們需要哪些 extension、在找哪些 framework?(第五節) 為了取得背景以及人口統計學的資料, 我們也問了關於你的團隊(第一節)、 你在寫的 application(第二節)、 以及你如何開發 application(第三節)。 有了這些資訊整合成這份報告, 我們覺得這是最綜合性的調查,可以引領 GWT 很長一段路。

在 2013 年,有 12 月的研討會(gwtcreate.com), 有令人興奮的 GWT 3.0 的計畫、 還有許多大公司投入 GWt 作為他們未來的技術; 我們知道 GWT 跨出了不只一大步。 2013 年 GWT 委員會也決定了未來的 release 步調: 每年一個大改版以及一個小改版。

這份調查是由 Vaadin、 Ray Cromwell(Google 代表、現任委員會主席)、 Daniel Kurka(mGWT 與 GWT-phonegap 的 Google 開發者)、 Artur Signell(Vaadin 代表)、 Bhaskar Janakiraman(Google)、 Colin Alworth(Sencha)、 Christian Goudreau(Arcbees)、 Konstantin Solomatov(Jetbrains)、 Mike Brock(RedHat)、 Stephen Haberman(Bizo)、 Joonas Lehtinen(Vaadin)以及 Thomas Broyer。 你可以在這份報告中看到他們的意見與反應。

這份調查報告在 GWT.create 2013 發表, 友超過 600 個熱心的 GWT 開發者出席這個年度最大的 GWT 活動。 我們同樣感謝超過 1400 位受訪者所花的時間與坦白, 期待看到你們的意見!

1. 關於開發團隊

團隊大小

GWT 開發團隊的平均人數是 12.5 人,而中位數則是 8 人。這跟去年的調查相同。 我們也問了過去 12 個月團隊大小的變化。

  • 47%:一樣
  • 41%:擴編
  • 10%:縮編
  • 3%:我只是小員工,不確定…

(兩張團隊大小的統計分佈圖)

團員組成

以八人團隊為例,任務分配為:

  • 2.7 人:後端開發者
  • 2.0 人:前端開發者
  • 1.3 人:測試人員
  • 0.9 人:PM(project / product)
  • 0.6 人:設計師
  • 0.6 人:死星上的人?

地理分佈

  • 58%:歐洲(上升 8%)
  • 25%:北美洲
  • 8%:亞洲(譯註:可惡,我應該去參加調查的 [毆飛])
  • 4%:南美洲
  • 2%:澳洲
  • 2%:非洲

2. GWT 用在哪裡

畫面數量

  • 48%:超過 20
  • 22%:11~20
  • 21%:5~10
  • 10%:1~4

20 是一個魔術數字。調查大型 app 的畫面數量應該很有趣。

Christian:少於 5~7 個畫面的 app 實在太小了,為什麼會用 GWT 呢? 這是個有趣的問題。

compile 時間

  • 1~3 分鐘:27%(去年 31%)
  • 3~10 分鐘:46%(去年 48%)
  • 10~30 分鐘:20%
  • 超過半小時:7%

對照去年的數據,可以代表 project 的規模越來越大。

Ray 與 Bhaskar:要改善 compile 時間有點難、需要一點時間來克服。 不過我們已經開始嘗試 incremental / modular compilation system。

寫給誰用

  • 35%:內部使用
  • 17%:公開且免費
  • 43%:公開但收費
  • 5%:其他

用來寫什麼

  • 46%:商業內部 application
  • 33%:商業外部 application
  • 13%:content-rich 網站
  • 2%:Portlet
  • 1%:遊戲
  • 5%:其他

Ray:看到有人用 GWT 寫遊戲實在很棒。 GWT 可以讓你在 Web 與 Android 之間共用程式碼, 藉由 PlayN 這種 library 也可以拓展到 iOS 上。

browser 支援度

(註:下列數據分別為 希望 2013 年有支援 / 希望 2014 年有支援

  • IE 6 跟 7:14% / 9%
  • IE 8:54% / 44%
  • IE 9:79% / 66%
  • IE 10:80% / 76%
  • IE 11:NaN / 70%
  • Safari:18% / 62%
  • Chrome:94% / 93%
  • Firefox:94% / 92%
  • iOS:NaN / 49%
  • Android:NaN / 50%

Joonas:IE6/7 終於快死光了,所以 GWT 3.0 可以不用鳥它們了。 不過看起來 2014 年還是要很痛苦地去支援 IE8/9, 因為需求量看起來還是蠻大的。

Ray:對於改進 GWT 核心而言,IE6/7/8 是可悲的毒藥, 有很多 API 沒辦法增強就是因為老一輩的 browser 沒辦法處理。 網頁正轉型為 mobile 跟 HTML5, 要整合過時的 browser 會讓這個轉型過程變得很困難。

Thomas:看到 IE6/7/8 加起來還不少,讓我很沮喪。

裝置支援度

(註:下列數據分別為 2012 年 / 2013 年

  • Desktop:98% / 99%
  • Tablet:36% / 45%
  • Phone:26% / 30%
  • 其他:2% / 2%

3. 如何用 GWT 建置 App?

怎麼作 UI?

  • 48%:用 Java 刻
  • 46%:UiBinder
  • 6%:GWT designer

Christian:我不懂為什麼這年頭還會有人想要 Java 刻 UI? 每個語言都有對應的 UI 描述方式。 ActionScript 有 MXML、 JavaScript 有 HTML、 .NET 有 XAML。

Daniel:看到這麼多人用 Java 刻 UI? 明明 UiBinder 就是比較好的方式。我們需要大力推廣 UiBinder。

Mobile App 開發環境

  • 27%:mGWT
  • 16%:gwt-phonegap
  • 16%:JS library
  • 15%:PhoneGap
  • 10%:Vaadin Touchkit
  • 17%:其他

後端通訊方式

  • 53%:GWT-RPC
  • 11%:Request builder
  • 7%:Request factory:
  • 7%:自製
  • 6%:Vaadin
  • 4%:RESTY
  • 3%:gwt-dispatch
  • 3%:gwt-platform

Ray:GWT-RPC 在小型 app、快速開發方面實在超有力的, 但是在 compile 時間以及 interoperability 上會花很多時間。 JAXRS 是 GWT 3.0 考慮的方法之一,可能會提供更好的中間層。

Daniel:在決定 GWT 3.0 以後的 RPC 系統時, 我們應該要記得「很多人喜歡 GWT RPC 的簡單好用」這件事。

IDE

  • 76%:Eclispe
  • 18%:IDEA:
  • 5%:Netbeans
  • 1%:其他

Christian:我個人最愛 IDEA 的 GWT plugin,是目前最成熟的。

Ray:我是 IDEA 的愛好者,它把寫 JSNI/JavaScript 程式碼這檔事做的很好。

如何作測試?

  • 49%:手動
  • 18%:Selenium
  • 13%:JUnit(GWTTest)
  • 13%:沒有測試 UI 這種事啦…

DevMode 還是 Super DevMode?

  • 74%:DevMode
  • 14%:兩個都用
  • 5%:Super DevMode
  • 5%:孟獲孟獲孟獲…

Thomas:看到 Super DevMode 成長真好。 未來要讓所有 browser 支援 DevMode 不太可能。 Super DevMode 的比例成長應該有部份會歸應於 mobile 平台。

Joonas:我們真的應該讓 Super DevMode 變成預設值。 用它來執行程式會比較接近實際的運算效能。 我覺得 DevMode 的優勢在於設定比較方便。

4. 用什麼版本?

GWT 版本

  • 79%:2.5
  • 11%:2.4
  • 3%:2.3
  • 3%:trunk 版
  • 2%:孟獲孟獲孟獲…
  • 1%:2.1
  • 1%:2.0

Thomas:看到有 3% 的人用 thunk 版真的超驚訝的。 我們計畫推出 nightly build,明年這個比率可能會增加。

JDK 版本

  • 37%:Java 6
  • 56%:Java 7
  • 8%:Java 8

Ray:我可以發布一個解法,只讓 client 的碼用 Java8。 但是 Java6 無所不在,希望多一點人可以願意去試試看。 Java8 的 lambdas 超好的, 讓 async callback 還有 collection 操作變得很愉快。

Joonas:Vaadin 7 已經支援 Java 8 了, 我希望我們可以在 GWT 3 當中用到 Lambdas 的優點。

會在 client 端的程式碼用 Java 8 的功能嗎?

  • 52%:不會讓 project 設定變複雜的前提下才會考慮
  • 27%:希望 client 跟 server 端用不同版本的 Java
  • 12%:沒興趣
  • 6%:其他
  • 2%:孟獲孟獲孟獲

Daniel:80% 的人會想要在 GWT 中用 Java8,這相當好。 我們必須找出一個好方法讓 server side 必須用 Java6 的人也能運作。

5. 外掛、framework…

GWT 用起來的產能如何?

  • 不想再用:2%
  • 不是很好:7%
  • 中規中矩:32%
  • 相當優秀:44%
  • 無可匹敵:15%

下一個 project 會用 GWT 嗎?

  • 84%:會
  • 16%:不會

不用 GWT 會用什麼 framework?

  • 5%:Play
  • 5%:JSF
  • 5%:Errai
  • 6%:SmartGWT
  • 8%:Dart
  • 11%:SpringMVC
  • 12%:Vaadin
  • 14%:JavaScript
  • 14%:Angular

Ray:GWT 3.0 會有一個新的 JS interop system, 銜接向 Polymar 或是 Angular 就不用寫 JSNI 的程式碼而變得更容易。 如此一來,想要用什麼 framework 就去用吧。

用哪方面的外掛?

回收的問卷中有 87% 的人使用了外掛,其中:

  • 23%:UI 功能(例如 GWT-dnd、GWT-fx)
  • 20%:application 架構(例如 GWT-presenter)
  • 15%:資料存取(例如 GWT-rpc、GWT-dispatch)
  • 12%:server 存取(例如 Google API、GWT-bootstrap)
  • 9%:application 功能(例如 GWT-platform)
  • 4%:data handling(例如 gilead)
  • 5%:其他
  • 13%:沒有用外掛

外掛去哪找?

  • 55%:就 google 嘛
  • 19%:自幹一個
  • 13%:GitHub
  • 11%:gwtproject.org
  • 2%:其他

你會整合既有 JS 到 project 中嗎?

  • 62%:會
  • 32%:不會
  • 3%:其他
  • 2%:孟獲孟獲孟獲…

6. GWT 的未來

GWT 的 bug

  • 73%:從來沒有回報過 bug
  • 13%:有
  • 14%:有,但是沒有修正

Thomas:GWT 真的夠好嗎?我不確定…… 到底是大家沒有被 bug 炸到,還是他們懶得回報 bug?

GWT 的光明面

每人兩票:

  • 60%:產能(cross-browser、不用弄一堆 JS)
  • 32%:執行速度(不是 compile 速度)
  • 24%:可模組化(可以團隊方式寫 GWT,不會互相影響) (掌控大型、很多功能的程式)
  • 19%:發現 bug 並解決的速度很快
  • 18%:ecosystem 中的開發工具
  • 17%:可靠度
  • 13%:可用度
  • 13%:產能(開始用 GWT 很容易)
  • 9%:DevMode 的重新整理速度
  • 7%:程式碼大小
  • 6%:有很多 widget 可以用
  • 5%:widget 品質很好
  • 5%:設計 application 風格 / application 外觀
  • 3%:有很多外掛
  • 2%:外掛品質很好
  • 2%:compile 時間
  • 3%:其他

GWT 的黑暗面

每人兩票:

  • 55%:compile 時間
  • 29%:DevMode 的重新整理速度
  • 19%:設計 application 風格 / application 外觀
  • 13%:有很多 widget 可以用
  • 13%:程式碼大小 (譯註:圖表的文字是 3%,但是長度是 13% 的大小。用後者。)
  • 11%:發現 bug 並解決的速度很快
  • 10%:產能(開始用 GWT 很容易)
  • 9%:widget 品質很好
  • 7%:ecosystem 中的開發工具
  • 6%:執行速度(不是 compile 速度)
  • 5%:可模組化(可以團隊方式寫 GWT,不會互相影響) (掌控大型、很多功能的程式)
  • 3%:可用度
  • 3%:有很多外掛
  • 2%:外掛品質很好
  • 2%:產能(cross-browser、不用弄一堆 JS)
  • 1%:可靠度
  • 6%:其他

Daniel:GWT 2.6 就已經有一些關於 compile 時間的改善。

Thomas:GWT 3.0 的重點會在改善 compile 時間以及 DevMode 的 refresh 時間上。

對委員會有什麼感覺?

  • 17%:GWT 感覺比以前有活力
  • 22%:對 GWT 的未來比以前有信心
  • 17%:roadmap 更清楚了
  • 28%:沒啥變化耶其實
  • 10%:現在對 GWT 比較沒信心
  • 6%:其他

2013年7月5日 星期五

GWT 與 WebSocket [上]

前言

這一陣子因為專案需要 server 與 browser 之間有即時雙向溝通的能力,所以就用了 websocket。 又由於 server 端綁定 PHP(還好 browser 也綁定 Chrome XD), 再加上傳輸的資料沒有很複雜,單純字串就可以解決, 所以沒有用現有的 GWT websocket library,統統自己來了...... [遮臉]

於是也就順便寫了這篇文章,借 websocket 介紹下面兩個主題:

  1. GWT 如何整合 JavaScript 程式碼(JSNI)
  2. EventHandler 的使用

(當然行有餘力的話也想涵蓋 GWT RPC,不過目前無法)

這三個主題在作〈GWT 版 GAE Channel API〉的時候都有用到 (但是 RPC 的部份只抄其 code、不明其理 [遮臉]), 不過拿 websocket 來介紹可能比較實在一點,GAE 的 channel API 可能太少人用了 [死]。

2013年4月11日 星期四

GWT 的優點與缺點

原文網址:http://www.gmarwaha.com/blog/2011/05/09/gwt-pros-and-cons/

註:原文寫於 2011.05.09


我愛 JavaScript。jQueryMooTools 出來之後, 讓我對 JavaScript 的愛又增加了好多倍。 如果要我對所有我開發的 web application 做出選擇, 我會從上面兩個 framework 當中選一個。 但是在這一行,我不得不一次又一次地屈服於客戶的壓力、 用他們選擇的技術來作業,無論他們的選擇對或錯 (付錢就是老大啊...... Orz)。 有一個客戶讓我接觸到 GWT 的世界。

幾年前當 GWT 剛發佈的時候,我曾經試了一下。 我不怎麼喜歡,所以我甩了 GWT 就再也沒回頭看過它一眼。 但是在過去六個月用 GWT 作業之後,我對這個 framework 有稍微不同的印象。 我仍然不會說 GWT 是什麼拯救世界的神兵利器, 但至少它沒有我想像的那麼糟糕。 我把對這個 project 的觀察結果紀錄下來,好的壞的都有, 對之後要導入 GWT 的開發人員來說可能有點用處。

2013年4月9日 星期二

網路開始「閃爍(Blink)」

原文網址:http://blog.oio.de/2013/04/05/the-web-starts-to-blink-chrome-drops-webkit-as-its-rendering-engine-announces-blink/

副標題:Chrome 捨棄 WebKit,改用 Blink 作為 rendering engine。

感謝 LPH66 與 chingfen 校正 Chrome 語源


最近 WebKit 可能變成新一代 IE6 (在偉大的 browser 戰爭前,大多數網頁開發人員只為了相容 IE6 所作的最佳化與測試) 的說法逐漸成型。

2013年4月3日 星期三

Java 8 取出 Collection element 的方式

原文網址:http://www.javacodegeeks.com/2013/03/extracting-the-elements-of-the-java-collection-the-java-8-way.html

譯文中的 Collection,代表 Collection API 或是屬於 Collection 的 class(List、Map...)。 如果是 collection,則代表某個 Collection 的 instance。


我們都廣泛使用 Collection, 像是 ListMap 以及延伸的 class。 每次我們用的時候,我們都得掃遍整個 collection 去找到某些 element、 更新它們、或是找出某個條件下不同的 element。 就像下面這個 PersonList

2013年4月1日 星期一

拆穿 Java StringBuilder 的謠言

這篇文章的陳述方式及內容有許多問題,可參閱 ptt.cc Java 版後續的討論


原文網址:http://skuro.tk/2013/03/11/java-stringbuilder-myth-now-with-content/

謠言......

用 + 號來連接兩個字串是萬惡的根源。 —— 不知名的 Java 開發人員

註:這裡討論用到的程式碼都可以在 Github 上找到。

在大學的時候,我學到在 Java 中用 + 號來連接字串是一種致命的效能罪惡。 最近在 Backbase R&D 有一個內部的 review, 這個 recurring mantra 變成了謠言, 因為當你使用 + 號來連接字串時,javac 會在底層使用 StringBuilder。 我要證明這件事情,並驗證在不同環境下的真實性。

2013年3月31日 星期日

Java 各種亂數產生器(PRNG)的弱點

原文網址:http://www.javacodegeeks.com/2013/03/weaknesses-in-java-pseudo-random-number-generators-prngs.html

這是 Kai Michaelis、Jörg Schwenk 還有我在 RA Conference 2013 的 Cryptographers' Track 發表論文的總結。 你可以取得我演講時的投影片、還有論文全文。 我們對常見 Java library 所產生的亂數序列進行分析, 這些 Java library 用了 PRNG(Pseudo Random Number Generator,通常是 SecureRandom), 我們發現在特定條件下有明顯的弱點。 為了讓這篇文章盡可能簡短,各種 PRNG 所用的演算法、詳細的 bug 描述、 統計檢驗的結果都略過不提,但是論文裡頭都有。 我們的調查涵蓋 PRNG 本身、以及它們用來作 seed 的 entropy collector (例如沒有可用的實數產生器時)。 底線:需要品質良好的亂數時,不要使用 PRNG!

2013年3月28日 星期四

Dart 會是 Web 的未來嗎?

原文網址:http://highscalability.com/blog/2013/3/20/dart-is-it-the-future-of-the-web.html

John McCutchan 有很長一段職場生涯是在 Linux kernel 領域, 現在以程式碼最佳化大師的身份被挖去 Google 的 Dart 團隊。 這轉折還蠻令人好奇的,直到你看到這個影片: 〈透過 Dart 將 SIMD 帶進 web 領域〉。 John 說了同行都能懂的理由,他喜歡 Dart 有三個原因: 效能、效能、還是他媽的效能。

2013年3月27日 星期三

簡介 Java 8 的 default method

原文網址:http://www.javacodegeeks.com/2013/03/introduction-to-default-methods-defender-methods-in-java-8.html

我們都知道 Java 裡頭的 interface 僅包含 method 的宣告、並沒有實作的部份, 任何 implement interface 但又不是 abstract class 的 class 必須提供這些 method 實作。 看看下面這個例子:

functional interface:Java 8 重新製作的概念

原文網址:http://www.javacodegeeks.com/2013/03/introduction-to-functional-interfaces-a-concept-recreated-in-java-8.html

下面這些 interface,全世界各地的 Java 開發人員至少用過一個以上: java.lang.Runnablejava.awt.event.ActionListenerjava.util.Comparatorjava.util.concurrent.Callable。 上述這些 interface 當中有一個共同的特點,就是它們只定義了一個 method。 JDK 當中有一堆這樣的 interface、Java 開發人員也製造了一堆。 這些 interface 也被稱為 Single Abstract Method interface(SAM interface)。 普遍常見的用法是產生一個 anonymous inner class 來使用這些 interface:

2013年3月22日 星期五

Java Collection API 的怪事

原文網址:http://www.javacodegeeks.com/2013/03/java-collections-api-quirks.html
感謝 tkcn 在 Java 技術上的協助。

在提到 Java Collection API 時,我們會認為已經了解全部的東西了, 像是 ListSetMapIterableIterator。 我們已經準備好 補強 Java8 的 Collection API

但在那之後,每隔一段時間我們就會偶然發現這些奇怪的怪事, 來自於 JDK 深處、以及向下相容的遙遠歷史。 讓我們來看一下這些不可修改(unmodifiable) 的 collection。

2013年3月20日 星期三

你懂 JIT compiler 了嗎?

原文網址:http://plumbr.eu/blog/do-you-get-just-in-time-compilation

還記得最後一次被寫 C 的人笑是什麼時候的事情嗎? Java 真的有夠慢、慢到他們打死也不會考慮用這樣的語言? 其實從很多方面來看,這種講法還是成立啦。 但是在大型企業的軟體骨幹中(這是 Java 的典型用途), Java 的效能絕對可以跟其他技術相抗衡。 這可能都要感謝神奇的 JIT。 在解說 JIT compile 技巧前,讓我們先多講一些它的背景。

2013年3月19日 星期二

Java 的 method call 要付出多少代價?

原文網址:http://plumbr.eu/blog/how-expensive-is-a-method-call-in-java

我們都遇到過這種場景: 看著設計不良的 code,聽著寫出這 code 的人辯稱:「你不能為了設計犧牲效能啊!」 而你就是無法說服那個人放棄那有 500 行的 method, 理由是一連串的呼叫有可能降低效能。

2013年3月18日 星期一

最流行的 application server

原文網址:http://www.javacodegeeks.com/2013/03/most-popular-application-servers.html

這是我們發表關於 Java 統計資料系列報導的第二篇。 所使用的數據是來自於免費版 Plumbr 安裝資料, 我們在過去六個月當中收集到 1024 種不同的環境。

本系列的第一篇文章分析的是底層——JVM 在什麼作業系統上執行、 是 32 還是 64 bit(譯註:原文打 62,應該是 typo)、 以及 JVM 供應商與版本號碼。 在這篇文章中,我們將焦點放在所使用的 application server。 這比預期的挑戰大一點,我們找到最好的解法是去解析 bootstrap classpath, 用類似 grep -i tomcat classpath.log 的查詢方式。 這還蠻簡單的,結果發現了一些相反的事情:

2013年3月16日 星期六

Agile 的 11 個謠言與 2 個真相

原文網址:http://www.javacodegeeks.com/2013/03/11-agile-myths-and-2-truths.html

我提供了許多 Agile 的訓練課程、也講了很多 Agile 的事情(BCS Bristol tonight)。 有些問題一再地出現,結果就是人們開始相信這些 Agile 謠言。 因此我一再地把時間花在拆穿這些謠言上。

我一直有一個小清單,上面有 11 個重複出現的謠言, 還有兩個對於一些團隊或公司比較難接受的真相。

2013年3月14日 星期四

web platform 這詞會取代 HTML5 嗎?

原文網址:http://www.2ality.com/2013/03/web-platform.html

當 web platform 出現在各平台、用來實作 application, 它看起來像是在加強替換 HTML% 的力道(已經很大程度地替換掉 Ajax 了 Ref.1)。 在這個脈絡下,這兩個術語都代表了 web browser 上的程式語言平台。 前者包含 JS;後者沒有,嚴格來說它包含了以 JS 為基礎的 API。

為甚麼 web platform 是個好選擇?

這是確實發展中的事情,原因有三: 第一,web platform 將實際平台描述的更好。 HTML5 當中的 HTML 暗示著「web browser 上除了 JS 的其他東西」, 但是 JS 是這個平台不可分割的一部分。 其次,一個不必要的版本號碼限制了 HTML5 的壽命。 再者,我們、以及知道什麼是 web 的人早就談論過 web apps 了。 所以「web apps 是奠基在 web platform 上」是很適合的用法。

因此,當 web 社群聚在一起讓 web 開發的文件更完善時, web platform 的名字就被選來撰寫文件。 感謝這些努力,web platform 也有一個 logo 了:

web platform logo

web platform 日益重要

越來越多的作業系統讓你使用 web platform 來撰寫一流的 apps。例如:

此外,Google 跟 Mozilla 都在研究如何讓 web apps 變成原生的桌機應用程式: [packaged apps](Google 的第一步:Chrome app launcher)與 Mozilla 的 Desktop WebRT

2013年3月13日 星期三

ECMAScript 6 的參數 destructuring 功能與 forEach()

原文網址:http://www.2ality.com/2013/02/foreach-es6.html

這篇文章會簡單介紹 ECMAScript 6(以下簡稱 ES6) 的 destructuring、 以及這個功能對 forEach() 這個 array method 的好處。