Jenkins 初用心得

這本來算是我在前公司要弄的項目,種種原因下搞到最近我才敢講我有玩過一輪。實務部分,大概從 jenkins 建立到整合 git / svn ,成功 build 完一個 jar / android apk。理論的部分則是翻完了下面這本名字落落長的書(有機會在寫心得)。

本文記錄一下,我在 jenkins 建構完這兩個專案的想法。


Continuous Delivery中文版:利用自動化的建置、測試與部署完美創造出可信賴的軟體發佈

如果你是主管,我建議要強迫導入。

原因很簡單,下面人放假了或是人跑了,只要其他人有能力拉 code 下來修改重新 commit 回 Version Control Server,jenkins 就能直接從 Version Control Server 拉下來建立要部署的檔案。

寫的很夢幻,前面該做的苦工還是要做,比如怎麼在 linux 上包出 apk(所有 IDE 幫你做的事情你都要自己搞一次)...

如果你已經懂 ant / maven / gradle,可以看情況。

會這樣說是因為,如果專案只有你在寫,也沒 Q 要測你的東西,那我覺得只要 unit test / 整合測試在開發環境做好一套即可,多在 jenkins 搞一套,除非你時間多想多學習,要不之後對專案幫助不大。

如果別人有要測你的東西,導入 jenkins 讓大家都是在同一個地方抓檔案,不會有搞不清楚再測哪一版的狀況(我是測你昨天下午五點半給我的那一版 --> 有沒有很熟悉的感覺)。
如果有人跟你一起開發,加上單元測試,每次整合完就能知道初步結果,你的主管也能在 jenkins 上看到專案最近幾次的整合結果,大家對於整合完的結果也會有更多信心,而不是憑感覺發佈。

接下來的工作

目前已經是來當作發佈檔案(war / jar / apk)的網站使用,接下來會加入單元測試來加強整合後的驗證工作,後續會試看看整合 asp.net 和自動發佈的功能,有機會的話會寫第二篇。

[讀書心得] 少,但是更好



人生定期總是要買些洗腦書來看才有動力,這本書濃縮一句話當作心得就是,一次把一件事好好做好。

p.36~39
又是從清除衣櫥開始,找出自己真正喜歡的衣服,不要捨不得丟已經花很多錢買卻穿不到的衣服,決定好要哪些要丟就去丟了,不要在想著下一次。上面衣服換成其他事物都適用。

東西少,留下的東西都是自己最重要最好用的,把心力放在真正好的事物,而不用花時間去處理那些普通好的事物。

p.68~69
學會分辨那些才是真正投資報酬率高的事物,都想做好但都做不好,不如好好做好最重要得事情。承認自己必不完美,沒辦法做好所有事情。

P.78~80
引述本書"一個爐口代表你的家庭,一個代表你的朋友,第三個是你的健康,第四個是你的工作。為了事業有成,你必須關掉其中一個爐口。而為了真正的功成名就,你必須關掉其中兩個。"

每個人追求的目標不同,但要了解取捨,有得必有失,才不會永遠羨慕別人。你現在得到的你失去的,都是你過去的選擇。不要負面思考為何失去,這本來就是當初的取捨。

p.129~133
面對選擇,列出權值,只要你對他評價低於90%,那就是不夠好,那就要拒絕。

p.151
要清楚自己的人生目標,當我們走到人生盡頭,是否一路走來沒有遺憾,多想想就會知道哪些是自己真正該做的事情。

p.159~163
要有說不的勇氣,當別人與你價值觀不同時,要能堅定自己的信念。

p.223~230
解決問題的根本原因,而非想出一堆應急的解決方案。

p.255~259
活在當下,不去想過去的錯誤,不去擔心還沒發生的事情,活在當下。

引述本書"輸球和被痛宰是兩回事。被痛宰表示他們比你們好。他們更快、更強、更有天賦。...輸球則是另一回事。它代表你失去焦點。它代表你沒有專注在必要的事情上。"

p.262~p265
"當下,何者為重"。弄清楚最重要的項目,按優先順序排列,寫下來,劃掉現在不重要的事情,開始做。

寫在紙上,減少了必須記在腦中的壓力。

三分鐘用 Vagrant 裝好一個 Jenkins

標題殺人法,前提要先把下載過 Box 下載。在上一篇 用 Vagrant 建立 CentOS 6.4,我上網抓了一個 CentOS 6.4(64 位元)的 Box 到本機。

接著我們利用這個 Box 快速做出一個新的 VM 上面跑了 Jenkins。步驟參考下方 gist,然後實體機器瀏覽器打開 http://127.0.0.1:38080/ 就可以看到 Jenkins 老頭了。然後按照之前教的匯出 box,別人或是要搬到機房,就連三分鐘都不用,一分鐘就可以了。

螢幕快照 2014-11-07 上午11.28.19

用 Vagrant 建立 CentOS 6.4

個人有點系統潔癖,所以改用 VM 技術把環境隔離開,弄爛也不用煩惱。下面是從無到有一個 CentOS 6.4 的步驟。

用 Vagrant 的好處之一,是它很方便讓 Host(實體機器)和執行中的 VM 共用同一個資料夾,你就可以在 Host 上用 IDE 編輯專案,然後用 VM 去執行同一個專案。

建好的 VM 把套件工具都裝好後,也可以匯出成 Box,讓其他人直接使用。想得到的好處有,新人快速擁有開發環境,測試環境和生產環境都用同一份 Box 開始建立,在本機上建立好一個新系統就可以匯出在機房裏建立。

更進階的用途,Vagrant 可以在一個 Vagrant 專案下建立設定多台 VM,等於我可以在開發環境(開發環境夠力能跑那麼多 VM 的話)把整個系統架構用 Vagrant 做出來(比如這個系統要有一台 Apache,一台MySQL外加一台獨立的 FTP),測試環境/正式環境也有裝 Vagrant 的話,就直接搬過去用,免去了架設多主機的繁瑣步驟,理論上所有環境都是相同的,不會有在我電腦上可以你不行的問題發生。

Vagrant 再搭配 docker 這種更輕量級的虛擬技術,原本要跑三個 VM 的架構就可以改成跑一個上面跑三個 docker 的 VM,節省了更多資源。

同時 VM 環境建立也可以利用 Vaagrantfile + sh 的方式來做,搭配 git,這樣連建立環境的步驟都能夠版本控管,不用再寫文件記錄安裝手順。

初步來看,若一般需求,你裝個 Virtual Box 就可夠了。

但若你想保留安裝好所有套件的乾淨 VM,那用 Vagrant 的 Config 來做安裝套件(Config 即手順說明書),隨時都可以回復成有完整套件的乾淨 VM,而不是用備份或快照 VM 這種比較笨重的方式,而且備份快照其實已經不是個乾淨的 VM(資料庫已經有資料或是環境上已經有不需要的檔案)。

參考:


[讀書心得] 例外處理設計的逆襲



書中幾乎所有的程式碼都是以 Java 作為例子,所以寫 Java,C# 的人看起來會比較輕鬆。太深入的內容就不寫了,簡單寫幾句看完自己覺得的有印象的(寫程式可以先當作身體反應的準則),有興趣的還是買書去支持一下 Teddy 大大

  • HTC One X 被婊很大。 XD
  • 接到 Exception 的程式碼,若沒有能力去處理,就先往上丟,最後讓 main 發生例外,或是 GUI 顯示比較白話的訊息。
  • Java 7 後新增的功能
    • Multi-catch exceptions:若收到不同的例外都是做同樣的處理(ex:印 log),就可以合併成一個 catch,減少重複的程式碼。
    • try-with-resource:從 C# 的 using 借過來的概念(最近剛好也碰到),直接把產生的資源寫在 try(...這裡頭...){},執行完就會自動釋放資源,可以少寫 finally,也不會忘記釋放資源。
  • Checked Exception v.s. Unchecked Exception
    • Checked Exception:Java 設計概念認為 Checked Exception 代表可以回復的錯誤,Compiler 會強迫開發者去處理 Checked Exception(catch 或是再丟出去)。不過我好像都沒有回復過 Checked Exception,要碼不是印 log,再往上丟,了不起就寫個 re-try 機制來想辦法衝過去。
    • Unchecked Exception:程式碼內不應該出現的錯誤,就使用 Unchecked Exception,若別人收到此錯誤,代表要去檢查為什麼發生,然後去修正程式碼。
    • C# 都是 Unchecked Exception,所以一開始寫發現都沒有 try catch,但最後又被 exception 炸到,很不習慣。
  • 若實在對例外處理沒有想法,那就是一直往上丟就對了,至少炸掉會知道,而不是被 catch 吃掉,提早在設計階段就炸掉趕快處理,比在上線才炸掉來的風險小。

最後壞味道和重構壞味道的部分,實用度很高,去買來翻看看吧。

MacBook Pro 升級 OS X 10.10 Yosemite

優勝美地第一時間發佈時,看到一些開發者推友有遇到升級完,感覺速度變慢,還有開發環境爛掉的問題。雖然小弟也只有拿來做 JAVA 程式開發,沒啥碰 Linux 套件的東西,但因為案子都正在跑,所以也不敢貿然升級。

今天趁著案子告一個段落,爬了一下 Java 開發者升級優勝美地會遇到的問題,連備份都沒做就硬上了。的確下載速度要快,要不然 5G 會抓到哭出來(在公司抓大概三十分鐘就抓完了),安裝的最後一分鐘的確不只一分鐘(記得安裝期間用 cmd + L 可以看到安裝進度的 console),安裝大概又花了三十分鐘。

升級完設定好 apple 帳號相關設定,就可以一般使用了。

嘗試打開 Eclipse,Intellij 果然掛點,會出現以下畫面,就直接點擊更多資訊,就會帶你到網頁上下載 Java SE 6,裝好就可以頭好壯壯繼續寫程式了。

螢幕快照 2014-11-04 下午9.00.22

隔天拿到公司開工,卡頓感很嚴重,尤其我是 mission control(多重桌面)的重度使用者,在切換桌面感覺畫面掉格掉的很嚴重(下面有錄影)。


參考推友 WanCW 給的這篇 升級 OSX 10.10 Yosemite 後 UI lag 的解決方法 ,重置 PRAM,減少透明度,關閉 dashboard,重開機還是一樣頓,後來想想是不是因為我外接 USB 顯示卡(J5 Create JUA 350)的關係,果然拔掉就順了,但為了三螢幕我還是默默把它插回去了。

順便貼一下三螢幕的優勝美地紀念一下...

2014-11-05 14.09.35

Visual Studio 必背熱鍵

因為工作關係要寫 C# 了,沒想到我也會有這一天,還虧我今年買了 MacBook Pro,紀錄一下(隨時更新)我在 Eclipse 常用然後在 Visual Studio (以下簡稱 VS)對應功能的熱鍵。

瀏覽相關

  • 上一頁:Ctrl + -
  • 下一頁:Ctrl + Shift + -
  • 折疊所有代碼:Ctrl + M -> Ctrl + O
  • 展開所有代碼:Ctrl + M -> Ctrl + P
    • ps:因為 VS 預設顯示單一檔案的大綱,是用 Combo Box 來呈現的,要點下去才能看到有哪些方法...
  • 移至定義的行:F12
    • ps:就是 Eclipse 的 F3 啦!
  • 有哪些行參考此定義:Shift + F12

編輯相關

  • 註解:Ctrl + K -> Ctrl + C
  • 取消註解:Ctrl + K -> Ctrl + U
  • 刪除目前行:Ctrl + X
  • 複製目前行':(停留在要複製的行,不用選取) Ctrl + C -> Ctrl + V
  • 程式碼格式整理:Ctrl + K -> Ctrl + F
  • 自動完成:Alt + 向右鍵
  • 插入程式碼片段:Ctrl + K -> Ctrl + X

其它

在工具列提示中顯示快速鍵:工具列上的工具 > 自訂 > 勾選工具列提示中顯示快速鍵

Tomcat7 使用 Scheduler

Java EE Server 上寫一個排程工作,只要加一個 @Schedule 就可以了,Tomcat 除了用 Java SE 的 TimerTask 來排程外的另一個選擇就是 quartz,看了一下有支援 Thread Pool,設定檔不用寫在程式碼上,之後要寫 ant 來置換比較方便,就決定用 quartz。

使用版本

Tomcat7 + quartz 2.1.7

步驟

http://www.quartz-scheduler.org/documentation/quartz-2.1.x/quick-start 是一個官網的簡單使用說明,下面是我自己使用的筆記。

1) 安裝

官網下載,解壓縮後 lib 下的 jar 檔都加入專案的 build path。

2) 啟用 quartz

web.xml 加入 QuartzInitializerListener,QuartzInitializerListener 實作了 javax.servlet.ServletContextListener,QuartzInitializerListener 在 Web App 啟動後就會初始化 quartz 相關的設定。

WebContent/WEB-INF/web.xml


3) 設定 quartz

WebContent/WEB-INF/classes/quartz.properties

4) 設定排程工作

quartz_data.xml 內,
  • 建立一個 Job,取名並指定實作類別。
  • 建立一個 Trigger,取名,指定 Job 和執行時間。
關於 Trigger 的執行時間設定可參考:http://www.quartz-scheduler.org/documentation/quartz-2.x/tutorials/crontrigger

WebContent/WEB-INF/classes/quartz_data.xml

5) 實作排程工作

FooJob.java
public class FooJob implements Job
{
  @Override
  public void execute(final JobExecutionContext ctx) throws JobExecutionException 
  {
    // To something here!
    }
}

問題

1) 執行時發生 java.lang.NoClassDefFoundError: javax/transaction/UserTransaction

嚴重: Exception sending context initialized event to listener instance of class org.quartz.ee.servlet.QuartzInitializerListener

java.lang.NoClassDefFoundError: javax/transaction/UserTransaction

下載 jta-1.1.jar 後,加入專案的 build path。


2) Tomcat7 關閉 Web App 出現 memory leak 警告。

[DefaultQuartzScheduler_Worker-5] but has failed to stop it. This is very likely to create a memory leak

這是因為 Tomcat7 關閉 Web App 時,沒有正確關閉 quartz 的關係,在QuartzInitializerListener 加入下列初始參數。

WebContent/WEB-INF/web.xml

參考

Tomcat7 使用 Logging

專案有需要產生 Log 檔案的需求,以便未來服務發生錯誤有個記錄,所以又要看看 Tomcat7 是如何產生 Log。Tomcat7 預設使用 java.util.logging,目前開發的功能很小,就不打算要另外安裝 log4j,才不會每台機器要裝一次 log4j,PG 兼 SA 就只好挑重點做。

1) 程式碼取得 Logger

Logger logger = Logger.getLogger("com.xyz.foo");

2) 程式碼中使用 Logger

logger.info("Hi!");

3) 替專案設定 Handler

到 ${專案路徑}/WebContent/WEB-INF/classes/ 下,新增或編輯 logging.properties,加入 Handler 並設定相關資訊,是要用 Console 還是要 File,等級多少要印出來。

logging.properties

4) 替專案設定 Logger

通過 Logger Level 的訊息才傳給上一步設定的 Handler。

經過測試,有點討厭的是,Logger 要到負責啟動專案的 JRE 上來設定才有作用。以我使用 macbook 舉例,編輯  Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/logging.properties,拉到最下面可以替 Logger 設定等級。

比如你專案中取得 Logger 是用

Logger.getLogger("com.xyz.foo");

那你可以在此新增

com.xyz.foo.level = FINE

這樣專案中透過 com.xyz.foo Logger,訊息的等級是 FINE 以上才會送給 Handler。而在 logging.properties 可以發現預設的 Logger Level 是 INFO。

.level = INFO

補充

JAVA Logging Level

SEVERE > WARNING > INFO > CONFIG > FINE > FINER > FINEST

Log 輸出

一條 Log 會
  • 第一關,先檢查 Logger Level 後才送到 Handler。
  • 第二關,再檢查 Handler Level 才決定是否要印在螢幕或是檔案上。
我個人習慣是
  • Handler Level 開到 FINEST(第二關永遠放行)。
  • 然後用 Logger Level 來決定是否要印在螢幕或是檔案上(第一關卡控)。
  • 如此,只要檢查 Logger Level 就能判斷會不會被印出來。

Tomcat7 使用 DataSource(MySQL)

之前比較好命有 JBoss 可以用,現在只有 Tomcat ,有些預設沒開的功能就要想辦法整合進來了,這陣子弄了些有的沒的,趕快記錄一下,免得忘記。

1) 在 Tomcat 下設定

到 $tomcat安裝路徑/conf/context.xml 新增 DataSource 的設定。

context.xml

2) 記得下載 mysql-connector.jar 放到 $tomcat安裝路徑/lib 底下。

3) 重新啟動 Tomcat 就應該可以看到有無連上 MySQL 。

4) 程式碼就可以透過 JNDI 用 jdbc/TestDB (上面設定檔替 DataSource 取的名稱)拿到 DataSource。

Eclipse 整合 Tomcat 遇到問題

但是從 Eclipse 下直接啟動 Tomcat 就會發現一直拿不到 DaraSource,是因為 Eclipse 開啓 Tomcat 時,會用預設的設定檔去覆蓋 Tomcat 的設定檔造成的。

其中一個解法是,直接修改 $eclipse使用的workspace/Servers/Tomcat/context.xml,把上一段做的變動改寫過來即可。

但這樣 Tomcat 和 Eclipse 會有兩個 context.xml (Don't Repeat Yourself),而用 Eclipse 啟動又會覆寫 Tomcat 原本的 context.xml (容易讓人搞不清楚到底以哪個為準)。所以就用了下面的做法。

綁定專案設定

直接修改 $project路徑/WebContent/META-INF/context.xml,把上一段做的變動改寫過來即可。Tomcat 再載入專案時就會加上專案裡新增的 DataSource。

這樣做之後接手的人,只需要部署 war 檔,不用特別到 Tomcat 下做設定,比較符合我個人開發專案的習慣。

Nexus 4 倒地不起

我的四兒子在 2014 過年的時候陣亡了,行動上網上到一半死當,然後重開機後就卡死在四個小球的開機畫面(原生的 Android 4.4.2),當初嘗試了:

  • 刷原廠 Android 4.4.2 > 卡在開機畫面
  • 刷原廠 Android 4.3 > 卡在開機畫面
  • 刷原廠 Android 4.2.2 > 開機有點久但可以開機
四兒子是活過來了,但手機訊號一直是零格,點進去看發現 baseband 版本是 unknown,IMEI 也變成 unknown 了,爬了國外跟對岸的文,發現也有人跟我有一樣狀況,但都沒有解答,唯二看到比較有可能回復的,一個是掏寶有把一個 box 可以重新刷板子,另外 XDA 有篇要自己改 ROM / Script 。難度太高我就放棄了。基本上這台就變成 Nexus Touch 了...

最近手機又掛了,爬文依舊沒有解答,但有問題的人變多了,但 Google 屌,完全沒有要處理的態度,又嘗試了以下的排列組合:
  • 刷原廠 Android 4.4.4 > 卡在開機畫面
  • 刷原廠 Android 4.4.3 > 卡在開機畫面
  • 刷原廠 Android 4.4.2 > 卡在開機畫面
  • 刷原廠 Android 4.3 > 卡在開機畫面
  • 刷原廠 Android 4.4.4 +Baseband 2.0.1700.48 > 卡在開機畫面
  • 刷原廠 Android 4.4.3 +Baseband 2.0.1700.48 > 卡在開機畫面
  • 刷原廠 Android 4.4.2 +Baseband 2.0.1700.48 > 卡在開機畫面
  • 刷原廠 Android 4.3 +Baseband 2.0.1700.48 > 卡在開機畫面
  • 刷 cyanogenmod 11 SNAPSHOT M8 > 卡在開機畫面
  • 刷 paranoidandroid 4.42 > 卡在開機畫面
  • 刷 paranoidandroid 4.2 > 卡在開機畫面

最後還是刷原廠 4.2.2 就又活了,但還是沒有訊號...

寫了文件如下,等到之後有新的原廠 ROM 再來試看看...

Java Mail 用 SMTP 透過 Amazon SES (Simple Email Service) 寄信

本文主要是說明 如何用 JavaMail 透過 Amazon SES 寄信

有時候需要一個穩定的 SMTP 主機來幫忙寄訊息,除了自己架主機和透過 Gmail 以外,Amazon 也有一個雲端服務叫做 Amazon SES (Simple Email Service) 可以利用。玩了一下,在考慮不想付費的情況下:

  • 一開啟服務後你就有了一個測試環境(Sandbox),每天可以免費寄200封信給你登記並"通過認證的收件人"。
    • 通過認證的收信人就是,Amazon 會寄封認證信給該收件人,該收件人點信中連結回覆就算通過認證了(就跟一般網站認證很像)。
  • 申請並通過 SES Production Access 後,每天可以免費寄2000封信給"任意收件人"。

程式碼很短但事前步驟有點小多,筆記一下怕以後要用到時又會忘掉。

參考

事前準備

  1. 註冊 Amazon Web Service 帳號。
  2. 取得 Sandbox 環境或是更進一步取得 SES Production Access 環境。
    1. Sandbox 環境
      1. SES 主控台,進入 Verified Senders>Email Addresses>Verify a New Email Address 登記測試環境下要用來測試的收件人。
      2. 收件人通過認證後,就可以直接透過SES 主控台,進入 Verified Senders>Email Addresses>Send a Test Email 來寄信。
    2. SES Production Access 環境
      1. 如果你每天想要寄超過200封信,或是有寄給陌生人的需求,就要填寫表格申請轉換至 SES Production Access,審核結果會在24小時內完成。
  3. 通過前面兩個步驟後,就可以透過 Web Console, AWS SDK 來寄送,但若是用 SMTP 來寄信,必須要到 SES 主控台,進入 SMTP Settings>Create My SMTP Credentials 建立一組帳號密碼。

參考

程式碼

提醒!!

  • 記得專案要 include Java Mail 的 jar 檔。
  • 記得去 SES 主控台建立 SMTP Credentials 取得帳號密碼。

我按官方這篇 Sending an Email Through the Amazon SES SMTP Interface with Java 會發生 java.lang.SecurityException: Access to default session denied ,所以改了一個自己的版本如下:

參考

Intellij 13 中使用 junit 4

在 intellij 13 下要使用 junit 的步驟如下

建立測試資料夾

在專案中建立資料夾,並將其設為 Test Sources Root(參考下圖)。

決定要測試的程式碼

打開要建立 unit test 的程式碼,下圖是打開 HelloGit.java,選取 Navigate>Test。

建立 unit test 範本

intellij 就會開啟建立 unit test 的 wizard,選完按 OK 就會在一開始建立的測試資料夾下建立 unit test(參考下圖)。

編寫和執行

加入要測試的程式碼,執行 unit test 方式就跟執行 java 一樣。

錯誤排解

找不到 junit

錯誤訊息如下,這是因為 android 裡頭有包舊版的 junit,若你有用到新版 junit 的功能,就會發生此問題。
解決方式:加入要用的 junit.jar,並且依賴的順位要比 android API 來的前面(參考下圖)。
!!! JUnit version 3.8 or later expected:

java.lang.RuntimeException: Stub!
    at junit.runner.BaseTestRunner.<init>(BaseTestRunner.java:5)
    at junit.textui.TestRunner.<init>(TestRunner.java:54)
    at junit.textui.TestRunner.<init>(TestRunner.java:48)
    at junit.textui.TestRunner.<init>(TestRunner.java:41)
    at com.intellij.rt.execution.junit.JUnitStarter.junitVersionChecks(JUnitStarter.java:190)
    at com.intellij.rt.execution.junit.JUnitStarter.canWorkWithJUnitVersion(JUnitStarter.java:173)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:56)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

Process finished with exit code 253

找不到 org/hamcrest/SelfDescribing

錯誤訊息如下。
解決方式:加入 /${IntelliJ IDEA 安裝資料夾}/lib/ 下找到 hamcrest-core-1.3.jar 即可(參考下圖)。
java.lang.NoClassDefFoundError: org/hamcrest/SelfDescribing
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    at org.junit.internal.builders.JUnit4Builder.runnerForClass(JUnit4Builder.java:10)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
    at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
    at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:26)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:41)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: java.lang.ClassNotFoundException: org.hamcrest.SelfDescribing
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    ... 25 more


Process finished with exit code 255

AllJoyn Peer Group Manager Module

關於 AllJoyn 請參考這篇

本篇簡單說明 AllJoyn 傳輸檔案的 Peer Group Manager Module,架構在原本 AllJoyn 之上,大大簡化了 AllJoyn 的概念和所需要寫的程式碼。

網路上中文的技術文件比較少,在此分享一下跟工作無關的部分。

Google Blogger 出現灰色的驚嘆號

2014-02-12_225206

不知道從哪天開始,部落格上就被灰色的驚嘆號占領,還好被我 Google 到 why are my blogger images gone and replaced with an exclamation mark?!!! ,中文翻譯就是 CSS 裡頭用到圖片不見了,果然換個圖床擺驚嘆號就消失了,差點就砍了這跟我好幾年的版面(想當初也是自己慢慢調 CSS + JavaScript 弄出來的),修好了就再戰十年!

2014 阪神行

IMAG0684

老婆懷了第二胎,他說再不去日本下次就要等三年了,於是就這樣殺了一趟大阪神戶五天四夜行,去還是坐了樂桃,一個人來回含機場稅不托運行李大概六千五百多,除了機上餐想要吃什麼都沒有以外,也沒什麼好挑剔了。住フローラルイン難波,三人房住三晚平均下一來一碗大概3500台幣,離南海電鐵走5~10分鐘,去心齋橋大概也是5~10分鐘,房間也很大,沒什麼好抱怨了。

旅客名單包含一個孕婦,外加三歲出頭的小屁孩(機票要算全票,到哪裡都要人抱),每天就只安排一個大景點,能走到我就很感謝天了。不得不說不要鐵齒,推車一定要帶,在台灣我從來沒用這台推車(所以三分線已經可以隨便丟),那這五天我每天都靠它才能撐得下去,要不回台應該變成劉備,手長過膝。

第一天下午飛機到關西就不用寫太多了,但才剛出關我的皮夾現金就忘在檢查行李處,馬上醜一被老婆糗了十分鐘…

第二天去神戶,從南波坐阪神電鐵到三宮就差不多花了一個小時,三宮那邊三個車站真是搞死我了,就算行動上網看 Google Map 還是迷路的亂七八糟,附帶一提這次行動上網辦的是 Japan Wireless 42Mbps 3G,一天大概是台幣300元,網頁上用 paypal 付帳,到日本時直接去機場郵局或是請他寄出旅館,返台時裝好丟到郵筒就好,用了兩次覺得連線狀況都還不錯,行動 AP 可以讓同行的人一起上網。

除了不小心迷路逛了一下三宮中心街,主要就是神戶港旁坐摩天輪,旁邊就是麵包超人的主題樂園,モザイク 和 umie 購物中心,摩天輪比想像中的小,有點失望。

IMG_20140113_141338

IMG_7194

IMG_7189

DSC_0069

第三天本來要去大阪兒童樂園,但很賽到了才發現休館,只好硬是從東邊殺到西邊的天保山,原本買的是大阪週遊二日卷,打的如意算盤就是坐免錢的大摩天輪和聖瑪莉亞號,但這兩項設施都公休中,當天馬上集滿醜二到醜四。

不過主要還是想去海遊館,有了小朋友就會想去這種有教育意義的地方,裡頭有一個很大的太平洋水槽(幾個樓層高)很讚,也有我喜歡的企鵝。
IMG_7251

IMG_7252

DSC_0160

DSC_0167

IMG_20140114_153314

第四天去大阪兒童樂園耗了一個上午,中間有個很大的遊園區,反正就是兩個樓層的大型遊樂區,裡頭一堆正太羅莉在跑就是了,另外還有一層是體驗區,很多項目可以讓大一點的小朋友遊玩中學習,但我們家小朋友比較小就只能跟老婆婆一起玩小火車,話說那火車我也陪她玩了一小時,我真有耐心。

IMG_20140115_104102

IMG_20140115_104236

IMAG0736_BURST004

下午還有些體力就又跑了通天閣,周遊卷免費入場,所以就有上去逛了一下,不過上面可以逛的區域還蠻小的,如果要自費的話就不建議上去,路過拍拍照就好。

IMG_20140115_161003

DSC_0227

DSC_0209

晚上有道頓堀坐觀光船,原本周遊卷是免費的,但我撕錯卷撕到大阪水上巴士,為了不掃興當場自掏腰包買了三張卷(當事人也不知道,要看了這篇才會知道),醜五到手。

DSC_0265

IMG_7203

第五天下午就回台灣了沒啥好提,主要推薦一下微笑車隊,新竹去機場950,機場回新竹1050,還蠻方便的,有小朋友體力又不好的可以參考一下。

IMAG0767

以下是我的食記,這次有帶小朋友 + 孕婦自知沒啥搞頭,所以目標就是一直吃。

第一天一下飛機就去機場吃了上次跟老弟吃的神座拉麵,不過太累了就忘記拍我吃的沾麵,消夜跑去松屋吃了牛めし,便宜又大碗。

IMG_20140112_215043

第二天早餐,やよい軒的目玉燒朝食,白飯可以吃到飽。

IMG_20140113_092642

第二天午餐,Steak Land 的神戶牛套餐,一客2980日圓,牛肉入口即化。

IMG_20140113_120808 (conflicted copy 2014-01-13-12-58-43)

第二天晚餐,大起水產的迴轉壽司,價錢還能接受,所以狂吃了一堆,不過同行人對壽司還好。

IMG_20140113_175147

IMG_20140113_183603

第二天宵夜,すき家的コクみそ野菜牛丼,すき家 CP 值頗高,價格便宜然後還吃的到青菜。

IMG_20140113_212220

第三天早餐,UCCカフェプラザ,就一般西式早餐不用多說。

IMG_20140114_092932

第三天午餐,鶴橋風月的大阪燒,有專人服務會在你面前弄到好,前面幾口很好吃,但吃到後面我覺得有吃過就好了,日本東西就這樣,有些你吃過就好了。

IMG_20140114_115033

第三天點心,南海車站附近的老爺爺的起司蛋糕,很好吃很爽口。

IMG_20140114_203756

第三天晚餐,不知名店的三色井,我很愛吃這種生魚片蓋飯,加點醬油就快升天了。

IMG_20140114_205054

第三天宵夜,德島東大拉麵,特點就吃牛肉片超多加上免費生雞蛋,很像在吃牛井的拉麵版,上次是跟我弟在京都車站吃的,那次我喉頭破了兩個洞,每口熱拉麵都讓我痛徹心扉。這次跟老婆看樓下賣水的女生,就忘記拍張拉麵的照片留念了。

第三天第二攤宵夜,ザめしや應該是鮪魚肉井吧,吃完食物都滿到鼻孔了。

IMG_20140114_214722

第四天早餐,すき家的鮭朝食

IMG_20140115_092556

第四天午餐,因為陪小朋友玩就隨便吃了一顆販賣機賣的飯糰,跟台灣的一樣就沒拍了。

第四天晚餐,だるま的串燒,也是吃體驗的,但體驗花了不少錢,有吃過就好。

IMG_7312

第四天第二次晚餐,丸龜製麵的烏龍麵,台北吃的到也不用多說了。

IMG_20140115_181818

第四天宵夜,ザめしや應該是鐵板牛肉吧,老婆狂推而且好像吃了兩次,我不想留下遺憾,那天雖然很飽我還是來吃了。

IMG_20140115_214225

第五天早午餐,すき家的新とりそぼろ丼,點連結可以發現,不是照片有色差就是詐欺。

IMG_20140116_115900

第五天上飛機前最後一餐,麥當勞,不解釋了。

IMG_20140116_131130

你看到這裡也夠屌了,反正這五天真的每天吃到滿出來,一回台當晚就遭到報應,得了腸胃型感冒,上吐下瀉吃了三天白吐司,所以說上天是公平的,你多吃了多少,他就會想辦法叫你吐出來還他。

MacBook Pro 13” 沒有視網膜入手


IMG_20140122_230154
趁著一年一度的蘋果特價日,忍不住就購入了 MacBook Pro 13 ,主要是想拿來行動寫程式寫部落格(假日回娘家多少有些空檔),另外複習一下 linux 基本指令(近來都是開發 Android AP ,碰 linux 的機會又下降了)。
預算的關係就沒上視網膜螢幕了(現在有點小後悔),燦坤取貨當晚就到 NOVA 把 RAM 給升上了 16G (8G * 2),在日本又購入了保護殼,低反發筆電包,鍵盤膜和 DVI 原廠輸出線,蘋果的週邊還真的是個大坑,以上加總大概是四萬五左右吧。
IMG_20140122_230053
加了黑色保護殼之後,外型看起來低調許多。
熱鍵強烈依賴 command 鍵,根本就是 Windows 的 Ctrl 鍵,很容易一直按錯。還好大部份的熱鍵組合都跟  Windows 類似只是 Ctrl 改成 command。顯示桌面找了很久,後來才發現 F11 就解決了。
個人推薦必背熱鍵如下:

  • command + C:複製
  • command + X:剪下
  • command + V:貼上
  • command + A:全選
  • command + Z:復原
  • command + M:將視窗縮到最小關閉
  • command + W:關閉目前視窗
  • command + Q:結束應用程式
  • command + Tab:切換不同的程式,類似 Windows 的 alt + Tab。
  • F11:顯示桌面,類似 Windows 的 windows + D。
  • control + 上:顯示所有桌面的狀況。
  • command + shift + 3:截圖(全螢幕)。
  • command + shift + 4:截圖(自行選取範圍)。
  • command + shift + 4 + 空白鍵:截圖(自行選取某個視窗)。
  • option(alt) + command + ESC:強制閉關程式。
參考:
觸碰手勢的部分真的是驚為天人,雙指捲動畫面,雙指左右撥就上一頁下一頁,四指往外撥就顯示桌面,上手之後一般操作根本可以把滑鼠丟了,可以體會為何有些人用了 Mac 就回不去 Windows 了。
參考:
然後 Mac 的程式安裝也很妙,dmg 檔案解開丟到應用程式資料夾就沒了,移除就直接丟到垃圾桶就好,後來摸比較熟才知道這只是其中一類型的安裝方式,除了跟 windows 一樣逐步的安裝方式,還有類似 linux package tool (HomebrewMacPortsFink),不過一般使用者就只會用到前面兩種。
檔案系統也被蘋果包得很漂亮,就只有應用程式,桌面,文件和下載項目(其實都放在 /Users/$[使用者帳號] 下面,得到終端機才能看到 linux style 的檔案路徑。

基本操作都摸習慣後,就是想辦法弄成自己比較習慣的工作環境。

多重視窗

Mac 裡的 Misson Control 就是我要的功能了,查資料,終端機,程式開發,遠端桌面都放在不同的桌面,才不會擠在一起亂糟糟.

雙螢幕

第二顆螢幕22”是插上去就吃到了,要記得到 系統偏好設定 > 顯示器 > 排列方式 將主螢幕頂端的白色長條移到你想當做主螢幕的那顆螢幕上(比如我就是拉到22”那顆螢幕),這樣就不用每次打開新的程式又要拉到大螢幕上。
IMG_20140122_101848
上圖一開始傻傻的不會設主螢幕,只好把13”當做主螢幕在看。
參考:

多重剪貼

Windows 是用 clcl,找到 ClipMenu 稍微修改一下複製歷史清單的顯示方式(預設不會直接顯示曾經複製過的項目),改一下熱鍵能直接叫出複製歷史清單,就跟 clcl 一模一樣了。

預設的複製項目都會躲到1-10、11-20這類命名的資料夾下,不太好用。
螢幕快照 2014-01-22 下午2.40.43
設定 inline 的項目為30,這樣前30筆就會直接顯示,第31筆才會放進31-40的資料夾。

遠端連線

微軟官方就有 Microsoft for Mac 遠端桌面連線用戶端,才能連回原本的電腦簽單,收信,找舊資料。

Script

直接 vim 或是內建的文字編輯寫指定,存成 .sh(只能在終端機下指令來執行) 或 .command (雙擊檔案圖示就可以執行)就可以了,別忘記先下 chmod 755 修改權限。
參考

使用到目前的心得,除了寫程式的程式碼有點糊,兩公斤的重量還真的有點重之外,其他都很滿意。話說以上兩個缺點,都是本錢夠粗就可以解決的問題,人生就不停的努力賺錢敗家吧。
IMG_20140122_230211