Отправка электронной почты с почтой от heroku вызывает странное исключение

Я пытаюсь отправить электронное письмо из приложения Pedestal, размещенного на Heroku, с помощью Postal. Электронная почта должна быть отправлена ​​в обработчике POST /send_email.

Но это не удается с:

clojure.lang.ExceptionInfo:
Interceptor Exception: No implementation of method: :make-input-stream of   
protocol: #'clojure.java.io/IOFactory found for class: nil

Он работает локально или через repl, работающий на героку.

Источник:

(ns team-happiness.routes
  (:require [io.pedestal.http :as bootstrap]
            [io.pedestal.http.route.definition :refer [defroutes]]
            [io.pedestal.http.body-params :as body-params]
            [postal.core :as postal]))

(defn smtp []
  {:host (System/getenv "SENDGRID_HOST")
   :ssl true
   :user (System/getenv "SENDGRID_USERNAME")
   :pass (System/getenv "SENDGRID_PASSWORD")})

(defn mail []
  {:from "[email protected]"
   :to "[email protected]"
   :subject "Hi!"
   :body "Hello from Heroku!"})

(defn send-email [request]
  (postal/send-message (smtp) (mail))
  {:status 200 :headers {} :body ""})

(defroutes routes
  [[
    [ "/send_email" {:post send-email}]
  ]])

Трассировки стека:

2015-08-26T21:22:25.474347+00:00 app[web.1]: clojure.lang.ExceptionInfo: Interceptor Exception: No implementation of method: :make-input-stream of protocol: #'clojure.java.io/IOFactory found for class: nil
2015-08-26T21:22:25.474349+00:00 app[web.1]:    at clojure.core$ex_info.invoke(core.clj:4593) ~[na:na]
2015-08-26T21:22:25.474350+00:00 app[web.1]:    at io.pedestal.impl.interceptor$throwable__GT_ex_info.invoke(interceptor.clj:31) ~[na:na]
2015-08-26T21:22:25.474352+00:00 app[web.1]:    at io.pedestal.impl.interceptor$try_f.invoke(interceptor.clj:53) ~[na:na]
2015-08-26T21:22:25.474354+00:00 app[web.1]:    at io.pedestal.impl.interceptor$enter_all_with_binding.invoke(interceptor.clj:141) ~[na:na]
2015-08-26T21:22:25.474355+00:00 app[web.1]:    at io.pedestal.impl.interceptor$enter_all$fn__12957.invoke(interceptor.clj:156) ~[na:na]
2015-08-26T21:22:25.474357+00:00 app[web.1]:    at clojure.lang.AFn.applyToHelper(AFn.java:152) ~[team-happiness-0.0.1.jar:na]
2015-08-26T21:22:25.474358+00:00 app[web.1]:    at clojure.lang.AFn.applyTo(AFn.java:144) ~[team-happiness-0.0.1.jar:na]
2015-08-26T21:22:25.474359+00:00 app[web.1]:    at clojure.core$apply.invoke(core.clj:630) ~[na:na]
2015-08-26T21:22:25.474361+00:00 app[web.1]:    at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1868) ~[na:na]
2015-08-26T21:22:25.474362+00:00 app[web.1]:    at clojure.lang.RestFn.invoke(RestFn.java:425) ~[team-happiness-0.0.1.jar:na]
2015-08-26T21:22:25.474364+00:00 app[web.1]:    at io.pedestal.impl.interceptor$enter_all.invoke(interceptor.clj:154) ~[na:na]
2015-08-26T21:22:25.474365+00:00 app[web.1]:    at io.pedestal.impl.interceptor$execute.invoke(interceptor.clj:272) [na:na]
2015-08-26T21:22:25.474367+00:00 app[web.1]:    at io.pedestal.http.impl.servlet_interceptor$interceptor_service_fn$fn__15523.invoke(servlet_interceptor.clj:398) [na:na]
2015-08-26T21:22:25.474368+00:00 app[web.1]:    at io.pedestal.http.servlet.FnServlet.service(servlet.clj:28) [na:na]
2015-08-26T21:22:25.474369+00:00 app[web.1]:    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:751) [team-happiness-0.0.1.jar:na]
2015-08-26T21:22:25.474371+00:00 app[web.1]:    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:566) [team-happiness-0.0.1.jar:na]
2015-08-26T21:22:25.474372+00:00 app[web.1]:    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1111) [team-happiness-0.0.1.jar:na]
2015-08-26T21:22:25.474373+00:00 app[web.1]:    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:498) [team-happiness-0.0.1.jar:na]
2015-08-26T21:22:25.474375+00:00 app[web.1]:    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1045) [team-happiness-0.0.1.jar:na]
2015-08-26T21:22:25.474376+00:00 app[web.1]:    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) [team-happiness-0.0.1.jar:na]
2015-08-26T21:22:25.474377+00:00 app[web.1]:    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:98) [team-happiness-0.0.1.jar:na]
2015-08-26T21:22:25.474379+00:00 app[web.1]:    at org.eclipse.jetty.server.Server.handle(Server.java:461) [team-happiness-0.0.1.jar:na]
2015-08-26T21:22:25.474380+00:00 app[web.1]:    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:284) [team-happiness-0.0.1.jar:na]
2015-08-26T21:22:25.474381+00:00 app[web.1]:    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:244) [team-happiness-0.0.1.jar:na]
2015-08-26T21:22:25.474394+00:00 app[web.1]:    at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:534) [team-happiness-0.0.1.jar:na]
2015-08-26T21:22:25.474395+00:00 app[web.1]:    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:607) [team-happiness-0.0.1.jar:na]
2015-08-26T21:22:25.474397+00:00 app[web.1]:    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:536) [team-happiness-0.0.1.jar:na]
2015-08-26T21:22:25.474398+00:00 app[web.1]:    at java.lang.Thread.run(Thread.java:745) [na:1.7.0_79]
2015-08-26T21:22:25.474400+00:00 app[web.1]: Caused by: java.lang.IllegalArgumentException: No implementation of method: :make-input-stream of protocol: #'clojure.java.io/IOFactory found for class: nil
2015-08-26T21:22:25.474401+00:00 app[web.1]:    at clojure.core$_cache_protocol_fn.invoke(core_deftype.clj:554) ~[na:na]
2015-08-26T21:22:25.474402+00:00 app[web.1]:    at clojure.java.io$eval3371$fn__3372$G__3360__3379.invoke(io.clj:69) ~[na:na]
2015-08-26T21:22:25.474403+00:00 app[web.1]:    at clojure.java.io$input_stream.doInvoke(io.clj:136) ~[na:na]
2015-08-26T21:22:25.474404+00:00 app[web.1]:    at clojure.lang.RestFn.invoke(RestFn.java:410) ~[team-happiness-0.0.1.jar:na]
2015-08-26T21:22:25.474406+00:00 app[web.1]:    at postal.support$pom_version.invoke(support.clj:61) ~[na:na]
2015-08-26T21:22:25.474407+00:00 app[web.1]:    at postal.support$user_agent.invoke(support.clj:67) ~[na:na]
2015-08-26T21:22:25.474408+00:00 app[web.1]:    at postal.message$make_jmessage.invoke(message.clj:177) ~[na:na]
2015-08-26T21:22:25.474410+00:00 app[web.1]:    at postal.smtp$smtp_send_STAR_$fn__17638.invoke(smtp.clj:34) ~[na:na]
2015-08-26T21:22:25.474411+00:00 app[web.1]:    at clojure.core$map$fn__560.invoke(core.clj:2624) ~[na:na]
2015-08-26T21:22:25.474412+00:00 app[web.1]:    at clojure.lang.LazySeq.sval(LazySeq.java:40) ~[team-happiness-0.0.1.jar:na]
2015-08-26T21:22:25.474414+00:00 app[web.1]:    at clojure.lang.LazySeq.seq(LazySeq.java:49) ~[team-happiness-0.0.1.jar:na]
2015-08-26T21:22:25.474419+00:00 app[web.1]:    at clojure.lang.RT.seq(RT.java:507) ~[team-happiness-0.0.1.jar:na]
2015-08-26T21:22:25.474420+00:00 app[web.1]:    at clojure.core$seq__27.invoke(core.clj:137) ~[na:na]
2015-08-26T21:22:25.474421+00:00 app[web.1]:    at postal.smtp$smtp_send_STAR_.invoke(smtp.clj:35) ~[na:na]
2015-08-26T21:22:25.474423+00:00 app[web.1]:    at postal.smtp$smtp_send.doInvoke(smtp.clj:58) ~[na:na]
2015-08-26T21:22:25.474424+00:00 app[web.1]:    at clojure.lang.RestFn.invoke(RestFn.java:423) ~[team-happiness-0.0.1.jar:na]
2015-08-26T21:22:25.474425+00:00 app[web.1]:    at postal.core$send_message.invoke(core.clj:35) ~[na:na]
2015-08-26T21:22:25.474427+00:00 app[web.1]:    at team_happiness.routes$send_email.invoke(routes.clj:31) ~[team-happiness-0.0.1.jar:na]
2015-08-26T21:22:25.474428+00:00 app[web.1]:    at io.pedestal.interceptor$eval13068$fn__13069$fn__13070.invoke(interceptor.clj:38) ~[na:na]
2015-08-26T21:22:25.474429+00:00 app[web.1]:    at io.pedestal.impl.interceptor$try_f.invoke(interceptor.clj:50) ~[na:na]
2015-08-26T21:22:25.474431+00:00 app[web.1]:    ... 25 common frames omitted
2015-08-26T21:22:25.474631+00:00 app[web.1]: INFO  i.p.http.impl.servlet-interceptor - {:line 266, :msg "sending error", :message "Internal server error: exception"}

person Kirill Salykin    schedule 26.08.2015    source источник
comment
Используете ли вы сборочный пакет github.com/upworthy/heroku-buildpack-boot? (все должно быть хорошо, просто хочу разобраться)   -  person codefinger    schedule 26.08.2015
comment
Да, в самом деле. единственный рабочий.   -  person Kirill Salykin    schedule 26.08.2015
comment
Какое значение вы используете для SENDGRID_HOST?   -  person codefinger    schedule 26.08.2015
comment
Можно отправить электронную почту, но только с помощью heroku run boot repl.   -  person Kirill Salykin    schedule 26.08.2015
comment
Пожалуйста, опубликуйте трассировку стека, а также минимальный код, необходимый для воспроизведения проблемы (или, по крайней мере, код из вашего проекта, который отвечает за отправку электронной почты).   -  person Nathan Davis    schedule 27.08.2015
comment
Пожалуйста, найдите ссылку на общедоступный репозиторий Github. Добавлена ​​трассировка стека.   -  person Kirill Salykin    schedule 27.08.2015
comment
Я заметил, что порт по умолчанию для ssl с почтой — 465, но SendGrid говорит, что они используют 587. Когда я установил этот порт в функции smtp, я получил исключение javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?.   -  person codefinger    schedule 27.08.2015
comment
Согласно sendgrid.com/docs/Classroom/Basics/smtp_ports.html 465 порт тоже есть.   -  person Kirill Salykin    schedule 27.08.2015
comment
Я думаю, что это может быть ошибка postal, при которой он не может прочитать этот файл из uberjar github.com/drewr/postal/blob/master/src/postal/support.clj#L61 Возможно, это объясняет, почему это работает из repl?   -  person codefinger    schedule 27.08.2015
comment
конечно! я просто смотрел на эту строку github.com/drewr /postal/blob/master/src/postal/support.clj#L64   -  person Kirill Salykin    schedule 27.08.2015
comment
@codefinger, можете ли вы порекомендовать другой проект для отправки писем? Не этот github.com/clojurewerkz/mailer   -  person Kirill Salykin    schedule 27.08.2015
comment
@codefinger это проблема чтения версии pom. Я обхожу это с помощью (System/setProperty postal.version 1). Можете ли вы дать ответ из своего комментария? Я отмечу его как принятый. Благодарю вас!   -  person Kirill Salykin    schedule 27.08.2015
comment
@sync, я вижу ссылки, но лучше разместить эту информацию прямо в посте. Репозитории исходного кода меняются и/или исчезают. Если бы источник имел отношение к решению, у будущих посетителей не было бы надежного способа сказать, что это за код, если только он не указан в сообщении.   -  person Nathan Davis    schedule 27.08.2015
comment
@NathanDavis - вы правы, я добавлю источник и трассировку стека. Спасибо.   -  person Kirill Salykin    schedule 27.08.2015


Ответы (1)


Я смог заставить это работать, установив следующую переменную конфигурации:

$ heroku config:set JVM_OPTS="-Dpostal.version=1.11.3"

Проблема, похоже, в том, что postal пытается определить свою версию, проверяя файл pom.properties внутри его jar. Но поскольку это uberjar, это банка внутри банки, и попытка прочитать входной поток не удалась.

Установив указанное выше системное свойство, он никогда не заглядывает в банку.

person codefinger    schedule 26.08.2015
comment
Не заброшен! Уведомления просто прячутся в моей электронной почте. Это очень старый код, который необходимо переработать. Поднимется по этому вопросу. - person drewr; 06.11.2015
comment
Исправлена ​​​​проблема с уведомлением с некоторыми более агрессивными фильтрами Gmail. - person drewr; 06.11.2015