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 的概念和所需要寫的程式碼。

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