LoginSignup
2
2

More than 3 years have passed since last update.

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

Last updated at Posted at 2019-11-02

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

再実行結果

[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
スクリーンショット 2019-11-03 2.03.00.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コマンドを使用して実行することがないので、
そこでハマってしまったがなんとか出来た。

以上

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2