めもる

調べたことをメモる。

SDK for Java SES v1での `no object DCH for MIME type multipart/mixed;`エラーの解決方法

Lambdaで、AWS SDK for JavaのSES v1のsendRawEmailメソッドを使ったときにエラーが発生したのでメモ。

添付ファイル付きでメール送信するためにsendRawEmailを使用。

使用環境

コードとエラーメッセージ

コードの内容は、AWS公式ドキュメントのサンプルをScalaに書き換えたものを使用。

Amazon SES API を使用して raw E メールを送信する - Amazon Simple Email Service

エラーメッセージはこれ。

Caused by: javax.activation.UnsupportedDataTypeException: no object DCH for MIME type multipart/mixed;
boundary="----=_Part_0_1692073709.1687521607753"
at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:905)
at javax.activation.DataHandler.writeTo(DataHandler.java:330)
at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1485)
at javax.mail.internet.MimeMessage.writeTo(MimeMessage.java:1773)
at javax.mail.internet.MimeMessage.writeTo(MimeMessage.java:1749)

解決方法

このコードを追加する。

val mc: MailcapCommandMap = MailcapCommandMap()
mc.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed")
CommandMap.setDefaultCommandMap(mc)

multipart/*以外のMIMEタイプの設定方法はこれみたい。 text/htmltext/plainは試して動いたけど、他は動作確認してません。

mc.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html"); 
mc.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml"); 
mc.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain"); 
mc.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed"); 
mc.addMailcap("message/rfc822;; x-java-content- handler=com.sun.mail.handlers.message_rfc822"); 

参考:stackoverflow.com

なんで動くようになったのか

DataHandlerがオブジェクトを使って作成された場合、writeToはそのオブジェクト・タイプのDataContentHandlerを検索します。DataContentHandlerが見つかると、DataContentHandlerのwriteToメソッドを呼び出します。

引用元: DataHandler (Java Platform SE 8)

DataHandlerは、現在のDataContentHandlerFactoryを使ってそのMIMEタイプに対応する適切なDataContentHandlerを捜し出そうとします。そして、DataHandlerはDataContentHandlerのメソッドを呼び出します。

引用元: DataContentHandler (Java Platform SE 8)

「そのMIMEタイプに対応する適切なDataContentHandlerを捜す」とことで、multipart/mixed用のDataContentHandler(DCH)が見つからなくてエラーになったみたい。 https://github.com/javaee/activation/blob/master/activation/src/main/java/javax/activation/DataHandler.java#L909-L910

諸々をimportして使うだけだと、MIMEタイプとDataContentHandlerのマッピングがされていないよう。 で、MailcapCommandMap.addMailcap()で連携したので、動くようになった。