2010年1月19日 星期二

Here Document與Java程式的搭配使用

這幾天一直百思不得其解,從前利用Here Document來傳值給C++/Fortran程式都能夠輕易完成;昨天寫了一個小小的轉換格式的程式想搭配shell script完成任務卻出現了NoSuchElementException 的尷尬問題,怎麼嘗試都不成功。

所謂Here Document,意思就是在子process裡傳入參數。在父process還在運行的時候,預先把參數值寫好,等到運行到子process的時候,不必等待使用者提示即可傳值。舉個例子:

假設someprog是一個C++/Fortran程式,過程中會提示,輸入兩個字串兩個數值:

#!/bin/sh
/usr/local/bin/someprog << END
vespa.env.out
vespa.ent.OUT
23.5
2.0
END

這種在script裡就先把要傳入的參數先寫好的方法,便是常被使用的Here Document。然而,今天我也寫了一個落落長的java互動式程式,卻拋出了NoSuchElementException 的例外。為了檢查到底是哪裡出問題,我寫了一個更簡單的程式來代替:

假設這個程式稱為TestString:

import java.util.*;

public class TestString{
  public static void main(String[] args){
    System.out.println("1st enter:");
    String tmpstr = new Scanner(System.in).nextLine();

    System.out.println("1st enter is "+tmpstr+". Now enter 2nd :");
    tmpstr = new Scanner(System.in).nextLine();

    System.out.println("2nd enter is "+tmpstr);
 }
}

編譯他並包成jar檔:
jar -cmvf menifest.mf TestString.class
當然,你的menifest.mf在預設套件的情況下可能會長這樣:
Main-Class: TestString

由於java程式是byte-code而非native-code,因此需要jvm去驗證並啟動他;想要模擬C++程式直接呼叫binary這樣的方法,只需要一個小小的script來解決:首先建立一個跟java程式同檔名的文字檔,以此例即為TestString,其內容如下:

#!/bin/bash
#Program TestString
[ -e `which java` ] && java -jar /home/maxsolar/bin/TestString.jar

exit 0;

當然別忘記把這個script加上可執行屬性,並放在你的PATH範圍裡。
執行以下的script來試試看!

#!/bin/bash
TestString << END
string1
string2
END

結果卻出現了下列錯誤訊息:
1st enter:
1st enter is string1. Now enter 2nd :
Exception in thread "main" java.util.NoSuchElementException: No line found
    at java.util.Scanner.nextLine(Scanner.java:1516)
    at TestString.main(TestString.java: 9)

對還不太能掌握java的我,實在不清楚究竟是為了麼值會傳不進去。困擾我一整天之後,決定到台灣最大的JavaWorld@TW論壇去爬文,卻沒有跟我的情況有類似的問題。後來在版上發問,沒想到很快的就有高手來解決我的問題:

Scanner 在某些操作上會有 buffering 的行為,如果要透過 Scanner 來處理 standard input 裡的數據,應只使用一個 Scanner instance。

import java.util.*;
public class TestString {

    public static void main(String[] args) {
        System.out.println("1st enter:");
        final Scanner scanner = new Scanner(System.in);
        String tmpstr = scanner.nextLine();

        System.out.println("1st enter is " + tmpstr + ". Now enter 2nd :");
        tmpstr = scanner.nextLine();

        System.out.println("2nd enter is " + tmpstr);
    }
}

如此一來,我使用的Scanner物件將會是唯一。先前我所使用的是anonymous的方法產生物件並直接傳到tmpstr這個字串物件接收,但是根據Dunkan前輩的建議,要使用一個唯一的Scanner物件來接收我的標準輸入,才能擺脫被buffered在記憶體的問題。

非常感謝Dunkan前輩精確且迅速的解答,因此把這篇作成筆記,好讓自己跟需要的Java與linux同好可以有機會參考。

參考連結:
[請益]shell script呼叫java程式並傳入值的問題

2009年12月22日 星期二

XP theme for GNOME

最近再討論版上看到有網友分享一個XP theme for GNOME環境的套件,看起來很方便,點兩下script就可以變成XP主題,另外也還有還原的script,看起來真的很屌,真的可以魚目混珠呢!
請參考這個網站:
http://ubuntu.online02.com/node/14

不過我沒有去嘗試這個就是了,因為我一點也不覺得XP的佈景好看@_@
不過喜歡XP佈景的朋友可以試試看,順便告訴人家這是一個不會中毒的XP@_@

2009年12月21日 星期一

Gantt chart(甘特圖) on Linux

甘特圖(Gantt chart)是一種描述各項目隨時間開始與結束的一種表達方式,專案管理方面的人可能對於這個東西比較熟悉。我第一次聽過甘特圖是幫老闆修改氣象局計畫細節的時候用的。
很幸運瀏覽Wekey-wiki時發現原來甘特圖已經被透過GanttProject計畫用java寫成一個跨平台的軟體。他是自由軟體,但並不是用GPL來宣告;她上面也聲明可以修改他的原始碼,也可以修改後作商業用途,不過找了一下還是沒看到source code。如果只關心binary的話,我們可以到這裡下載便於安裝GanntProject的版本,或是直接下載最新的版本(2.0.10):
wget -c http://ganttproject.googlecode.com/files/ganttproject-2.0.10.zip
壓縮後放到任何地方都可以,可以發現他是靠著script來啟動ganttproject的。由於java執行的方式跟環境比較特殊,用script來幫助執行java程式是非常常見的手法。我們來看看他的script:

這已經算是寫得很棒的script了!不過我還是想作一些修改:

我只是簡化了一些變數的宣告以及java環境的測試。不過很可惜的,由於作者啟動main方法需要讀取一個xml檔,這種呼叫方式我無法不切換目錄(cd $GP_HOME那行)來完成啟動Main class,而這也是我當初要改這個script的最主要原因。倘若所有環境都包在jar裡面,就不用額外宣告classpath,其實是減輕使用者許多負擔的。
作個軟連結,這個程式就可以上線啦!
chmod +x /opt/ganttproject-2.0.10/ganttproject.sh
ln -s /opt/ganttproject-2.0.10/ganttproject.sh /usr/bin/Ganttproject
這樣就可以直接呼叫Ganttproject來使用囉!
啟動GanttProject!!
新增一個專案來玩玩(其實我根本不知道怎麼用!!)
設定一些可以參考的資訊在上面。
拖曳以設定duration。
可以拖曳進度(黑色的bar)
也可以設定milestone以得知進度狀況。
上面的flash教學是用比較舊版的ganttproject所錄製下來的,我照著教學步驟去作,發現新版根本無法像舊版這樣快樂的使用拖曳來變化duration。
照著flash範例教學所做出來的甘特圖!(真不是普通的醜@_@)
把辛苦的成果匯出看看!(果然是WYSIWYG的醜!!!)

2009年12月17日 星期四

『中央』研究院

今天我跟一個中央畢業的同事聊到:
我: 哇!你們中央的人口還真多耶!我看10的研究助理有8個都是中央的!
同事:呵呵,對阿...
我: 而且一堆台大的研究生來這邊也都是中央畢業的耶!這裡真的是中央的天下耶!
同事:(淡淡貌)呵呵,不然怎麼叫『中央』研究院呢!
我: ....(想想還真有道理!)

2009年12月16日 星期三

SUN的電子證照

由於novell有寄給我電子證照,所以我一直以為所有的廠商都有提供電子證照;日前我寫信去sun總部問,總算遲遲的給了一封回信之後便石沉大海:

說要轉交給合適的處理人員,竟然就這樣沒有下文...真是太糟糕了,我就算不是大宗客戶,但還是客戶阿!後來我找上昇陽教育訓練中心,總算得到一個有或沒有的答覆:

所以如果您跟我一樣再找sun的電子證照,至少目前為止sun都沒有提供電子證書的喔!

2009年12月9日 星期三

Google Chrome beta release!!!

等待已久的Chrome for Linux終於釋出beta版了!!先前使用open source的chromine仍然還有許多問題,其中最為人詬病的就是flash支援的極差。Google釋出beta版大家可是睜大了眼睛在看呢!請各位看官到http://tools.google.com/chrome/?hl=zh-TW下載,或是到http://www.google.com/chrome/intl/zh-TW/w00t.html欣賞一下世界各地勞苦功高的開發人員開發chrome for linux的經過~

假設你常用的是firefox,第一次啟動chrome時會匯入firefox的所有設定,包含書籤、密碼、cache等等,非常貼心。

我迫不及待的想拿他來測試flash!!最好的方法就是拿一個swf來測試啦!玩起音速小子,真是超順暢的啦!!

那麼能不能偵測到我的JRE呢?測試看看便知道!

可以偵測到耶!真是方便!

如果預設的字型跟locale以及coding都不適合的話,也很方便做細部調整!

等待各位去發覺的extension!!

還有很多佈景主題喔!不過,當然沒有firefox多就是了!

目前為止還沒發現太多問題,我想請大家依起共襄盛舉測試beta版的chrome for linux,畢竟大家真的等了好久好久!!

我最常用的幾個extension!跟大家分享!!

我強力推薦使用chrome的原因是,chrome非常的輕巧,她可以一次開20多個分頁不會當機,然後關閉再開啟的這些分頁也很快的起來;相較之下,firefox就非常笨重且耗資源,光是開四個分頁cpu loading就超過50%!基於效率跟安全性,我會選擇google chrome。

延伸閱讀:
Chromium for Linux

2009年11月23日 星期一

日本中國

如果我說中國是日本的一部份。中國都該稱為日本中國,二次大戰沒有美國,中國早就是日本的領土,中國人你們做何感想?

清單上沒有我的國家,有一個歧視我國的字眼出現,我若選了就是自取其辱;我不像國民黨員,不會做這種不知廉恥的羞辱國家的行徑。

一個玩弄民族主義、堅持共產主義的貪婪政權,自以為經濟強大,殊不知自己人民的道德與操守跟經濟完全不能相提並論;原本要下載RHEL5來測試的,操你媽的中國,老子拒用Redhat Linux!