AWSでJavaMailを使用してメール送信する

#AWSでJavaメールを使用してみる

今回は、前回の記事で立ち上げたAWSのEC2を使用してJavaメールをgoogleのSMTP経由で送信してみる

＊前回までの記事は下記を参照ください。
https://qiita.com/ktkt11122334/items/36f950670e5952d7d17e


##EC2でJavaを動かす
EC2にJavaが入ってるか確認する
前回立ち上げたEC2にssh
ssh -i [pemファイル] ec2-user@ec2-54-65-248-190.ap-northeast-1.compute.amazonaws.com


Javaが入っていないことを確認
java -version
-bash: java: コマンドが見つかりません
javac -version
-bash: javac: コマンドが見つかりません
yum list installed | grep java
**なにも表示されない

openJDKをyumで落としてくる
sudo yum update
sudo yum -y install java-1.8.0-openjdk-devel

再確認
Javaがインストールされていることがわかる
java -version
openjdk version "1.8.0_222"
OpenJDK Runtime Environment (build 1.8.0_222-b10)
OpenJDK 64-Bit Server VM (build 25.222-b10, mixed mode)

javac -version
javac 1.8.0_222


試しにHelloWorld表示するプログラムを書いてみる

```
public class HelloWorld {

  public static void main(String[] args) {
    System.out.println("HelloWorld");
  }

}
```

javac HelloWorld.java
ls
HelloWorld.class  HelloWorld.java

表示確認
java HelloWorld
—————————
HelloWorld
—————————


##ローカル環境でメール送信用プログラムを作成
Javaでメール送信用コードを書いていく
開発環境はEclipseを使用して、標準のOpenJDK1.8~を使用
JavaMailは専用のライブラリが必要なので落としてくる
下記のあたりから落としてきて使用する
https://www.oracle.com/technetwork/java/index-138643.html

クラス設計は、メールクライアントからメールビルダーを呼び出して設定値を付与
sendMailメソッドで送信処理
メールビルダークラスは、インナーアウター構成として
インナークラスにビルダー、アウタークラスにMailSendクラスを構築
*今後はgithubにあげる予定(githubを使ったことがないので、今後対応予定


メールクライアント

```
import mail_builder.SendMail;

public class JavaMailClients {

  public static void main(String[] args) {

    SendMail.MailBuilder mailBuilder = new SendMail.MailBuilder();

    mailBuilder.setTo("メール送信先アドレス");
    mailBuilder.setFrom("メール送信元アドレス");
    mailBuilder.setPassword("googleメールのパスワード");
    mailBuilder.setUserName("googleメールのユーザー名");
    mailBuilder.setSmtpHost("smtp.gmail.com"); // googleのsmtpサーバ使用
    mailBuilder.setSmtpPort("587");


    String subject = "テストメール";
    String contents = "テスト送信";
    mailBuilder.build().sendMail(subject, contents);

  }

}

```

メール送信側

```
package mail_builder;

import java.io.UnsupportedEncodingException;
import java.util.Properties;

import javax.mail.Address;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class SendMail {

  // mail contents
  private String to = "";               // send target
  private String from = "";             // mail from

  // mail user settings
  private String userName = "";         // mail account(example google account)
  private String password = "";         // mail account password
  private String smtpHost = "";
  private String smtpPort = "";
  private final String smtpAuth = "true";
  private final String starttls = "true";
  private final String connectionTimeoutValue = "10000";
  private final String timeoutValue = "10000";

  // others
  private final String charSet = "ISO-2022-JP";
  private final String encoding = "base64";


  // smtp settings
  private Properties mailProperties = new Properties();
  private final String SMTP_HOST = "mail.smtp.host";
  private final String SMTP_PORT = "mail.smtp.port";
  private final String SMTP_AUTH = "mail.smtp.auth";
  private final String SMTP_START_TLS = "mail.smtp.starttls.enable";
  private final String SMTP_CONNECTION_TIMEOUT = "mail.smtp.connectiontimeout";
  private final String SMTP_TIMEOUT = "mail.smtp.timeout";


  public static class MailBuilder {

    private String to = "";
    private String from = "";
    private String userName = "";
    private String password = "";
    private String smtpHost = "";
    private String smtpPort = "";

    public MailBuilder setTo(String to) {
      this.to = to;
      return this;
    }

    public MailBuilder setFrom(String from) {
      this.from = from;
      return this;
    }

    public MailBuilder setUserName(String userName) {
      this.userName = userName;
      return this;
    }

    public MailBuilder setPassword(String password) {
      this.password = password;
      return this;
    }

    public MailBuilder setSmtpHost(String smtpHost) {
      this.smtpHost = smtpHost;
      return this;
    }

    public MailBuilder setSmtpPort(String smtpPort) {
      this.smtpPort = smtpPort;
      return this;
    }

    public SendMail build() {
      return new SendMail(this);
    }

  }



  private SendMail(MailBuilder mailBuilder) {
    this.to = mailBuilder.to;
    this.from = mailBuilder.from;
    this.userName = mailBuilder.userName;
    this.password = mailBuilder.password;
    this.smtpHost = mailBuilder.smtpHost;
    this.smtpPort = mailBuilder.smtpPort;
  }



  public void sendMail(String subject, String contents) {

    mailProperties.setProperty(SMTP_HOST, smtpHost);
    mailProperties.setProperty(SMTP_PORT, smtpPort);
    mailProperties.setProperty(SMTP_AUTH, smtpAuth);
    mailProperties.setProperty(SMTP_START_TLS, starttls);
    mailProperties.setProperty(SMTP_CONNECTION_TIMEOUT, connectionTimeoutValue);
    mailProperties.setProperty(SMTP_TIMEOUT, timeoutValue);

    Session session = Session.getInstance(mailProperties,
      new javax.mail.Authenticator() {
         protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(userName, password);
         }
      }
    );

    try {
      MimeMessage message = new MimeMessage(session);

      message.setFrom(new InternetAddress(from, "test_user"));
      message.setReplyTo(new Address[]{ new InternetAddress(from) });
      message.setRecipient( Message.RecipientType.TO, new InternetAddress(to) );
      message.setSubject(subject, charSet);
      message.setText(contents, charSet);
      message.setHeader("Content-Transfer-Encoding", encoding);

      Transport.send(message);

    } catch (MessagingException e) {
      throw new RuntimeException(e);
    } catch (UnsupportedEncodingException e) {
      throw new RuntimeException(e);
    }

  }


}

```

自分の携帯に送信したがExceptionが発生
googleアカウントで他者からのメールサーバーアクセスを許可する必要があるみたい
下記の画面でオン設定にする
![スクリーンショット 2019-11-03 1.54.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526203/dff94a5b-d96f-28f9-8550-81f72033303f.png)


再実行結果

```
[From :]
 test_user
[Subject :]
*なぜか表示されない
[Content:]
$B%F%9%HAw?.(B

```

文字化けが発生している
$B%F%9%HAw?.(B

ハードコーディングしてある文字コードの設定を変更してみる。
x-windows-iso2022jp(こちらを使用していたが記載のコードでは既に変更済み
↓
ISO-2022-JP


結果

```
[From :]
 test_user
[Subject :]
テストメール
[Content:]
テスト送信
```

結果確認完了
Eclipseでデータを掃き出し
アーカイブ形式でサーバーに送信する
![スクリーンショット 2019-11-03 2.02.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526203/1cd4b4c6-af08-b96c-d771-a839ecaa4962.png)
![スクリーンショット 2019-11-03 2.03.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526203/8f0035e0-eeb4-a50b-c939-bf436b0f2221.png)


##EC2上で実行する
EC2サーバへ
[local]

```
scp -i [pemファイル] SendMail.zip ec2-user@ec2-54-65-248-190.ap-northeast-1.compute.amazonaws.com:~;
ssh -i [pemファイル] ec2-user@ec2-54-65-248-190.ap-northeast-1.compute.amazonaws.com
```

[ec2]

```
unzip SendMail.zip 
ls
bin  src
cd bin
ls
JavaMailClients.class  javax.mail-1.6.2.jar  mail_builder

java JavaMailClients
Exception in thread "main" java.lang.NoClassDefFoundError: javax/mail/MessagingException
	at mail_builder.SendMail$MailBuilder.build(SendMail.java:86)
```

ローカルでは成功していたのになぜかエラー

ローカル環境では、Eclipseで実行したがMacOSで実行してみることにした
HomeBrewを入れてJava8をインストール
[local ターミナル]

```
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
brew cask install adoptopenjdk8
Error: Cask 'adoptopenjdk8' is unavailable: No Cask with this name exists.
```

Brewでもエラーが出てしまう
どうやらリポジトリにjava8がないっぽい

公式で落とそうにもoracleに変わってから登録が必要でめんどくさくなってくる
MacOS用のopenjdkを探すも見つからず・・

2時間ほど粘ったが、ハマってしまった


Exceptionの内容を見るに、javaxのメールクラスが読み込めていないので
classpathの設定についてググって見る
jarファイルを含む場合は、classpathにjarを設定する必要があることがわかる

再実行
java -cp .:./javax.mail-1.6.2.jar JavaMailClients

Exception in thread "main" java.lang.RuntimeException: javax.mail.AuthenticationFailedException: 534-〜〜〜〜


またエラー・・・
メールサーバへのアクセス認証に失敗しているみたいなので
それについてもググって見ると、下記のサイトで設定方法が書いてあった
https://stackoverflow.com/questions/34433459/gmail-returns-534-5-7-14-please-log-in-via-your-web-browser/34433953


再度設定して実行
java -cp .:./javax.mail-1.6.2.jar JavaMailClients


無事、動きました。
javaコマンドを使用して実行することがないので、
そこでハマってしまったがなんとか出来た。

以上