将我的Rails 2.3应用程序从MRI Ruby 1.8.7切换到JRuby 1.6.5后,该应用程序无法再发送邮件。我正在使用ActionMailer:
class MessageMailer < ActionMailer::Base
def message(msg, recipient, reply_to_email=nil)
template = (msg.message_type.nil?) ? "default" : msg.message_type.name.downcase.gsub(' ', '_')
recipients recipient
subject msg.subject
from (msg.sender.nil? or msg.sender.email.blank?) ? "\"no-reply\" <#{SYSTEM_EMAIL_ADDRESS}>" : msg.sender.email
content_type "text/html"
body render_message(template, :message => msg)
reply_to reply_to_email || ((msg.sender.nil? or msg.sender.email.blank?) ? "\"no-reply\" <#{SYSTEM_EMAIL_ADDRESS}>" : msg.sender.email)
end
...
end
MessageMailer.deliver_message(...)
这可能是无关紧要的,因为这一切都在MRI Ruby 1.8.7下工作。
Rails应用程序配置为在config / environments / production.rb中使用sendmail:
config.action_mailer.delivery_method = :sendmail
sendmail日志(/var/log/mail.log)更有趣:
# Sending mail under MRI Ruby 1.8.7
Jan 5 09:38:49 my sendmail[24755]: q05EcnCr024755: from=edwarda, size=310, class=0, nrcpts=1, msgid=<201201051438.q05EcnCr024755@my.example.org>, relay=edwarda@localhost
Jan 5 09:38:49 my sm-mta[24757]: q05Ecn02024757: from=<edwarda@my.example.org>, size=516, class=0, nrcpts=1, msgid=<201201051438.q05EcnCr024755@my.example.org>, proto=ESMTP, daemon=MTA-v4, relay=localhost [127.0.0.1]
Jan 5 09:38:49 my sendmail[24755]: q05EcnCr024755: to=me@example.com, ctladdr=edwarda (1011/1012), delay=00:00:00, xdelay=00:00:00, mailer=relay, pri=30310, relay=[127.0.0.1] [127.0.0.1], dsn=2.0.0, stat=Sent (q05Ecn02024757 Message accepted for delivery)
Jan 5 09:38:49 my sm-mta[24759]: STARTTLS=client, relay=aspmx.l.google.com., version=TLSv1/SSLv3, verify=FAIL, cipher=RC4-SHA, bits=128/128
Jan 5 09:38:49 my sm-mta[24759]: q05Ecn02024757: to=<me@example.com>, ctladdr=<edwarda@my.example.org> (1011/1012), delay=00:00:00, xdelay=00:00:00, mailer=esmtp, pri=120516, relay=aspmx.l.google.com. [74.125.45.27], dsn=2.0.0, stat=Sent (OK 1325774329 o43si18661797yhk.140)
# Sending mail under JRuby 1.6.5
Jan 5 11:10:26 my sendmail[7623]: q05GAQkH007623: from=edwarda, size=199, class=0, nrcpts=0, relay=edwarda@localhost
请注意,当我运行JRuby时nrcpts(收件人数)为0,运行1.8.7时为1。
我使用完全相同的代码和宝石,除了我为JRuby使用这些宝石:
gem 'activerecord-jdbc-adapter', '<= 1.2.0', :require => false
gem 'activerecord-jdbcpostgresql-adapter', '<= 1.2.0', :require => 'jdbc_adapter'
gem 'ffi-ncurses'
gem 'jruby-openssl'
gem 'torquebox', '2.0.0.beta1', :platforms => 'jruby'
gem 'torquebox-rake-support', :platforms => 'jruby'
gem 'torquebox-capistrano-support', '2.0.0.beta1'
如果它有用,这是我的Gemfile.lock。
我的Rails日志中没有有趣或不寻常的输出;只有通常的成功信息。
编辑:我无法在我的开发(OSX)计算机上重现此问题。
有关为什么收件人可能会迷路或者我可能会如何解决此问题的想法?
答案 0 :(得分:3)
这与JRuby错误有关:http://jira.codehaus.org/browse/JRUBY-6162
显然IO.popen
在尝试执行sendmail命令时过早关闭。在上游修复之前,这个猴子补丁可以包含在初始化程序中以解决问题:
Rails 2:
module ActionMailer
class Base
def perform_delivery_sendmail(mail)
sendmail_args = sendmail_settings[:arguments]
sendmail_args += " -f \"#{mail['return-path']}\"" if mail['return-path']
IO.popen("#{sendmail_settings[:location]} #{sendmail_args}", "r+") do |f| #r+ geht, w+ geht nicht richtig, bzw. nur manchmal
f.puts mail.encoded.gsub(/\r/, '')
f.close_write
sleep 1 # <---- added this line in order to give sendmail some time to process
end
end
end
end
Rails 3:
module Mail
class Sendmail
def initialize(values)
self.settings = { :location => '/usr/sbin/sendmail',
:arguments => '-i -t' }.merge(values)
end
attr_accessor :settings
def deliver!(mail)
envelope_from = mail.return_path || mail.sender || mail.from_addrs.first
return_path = "-f \"#{envelope_from.to_s.shellescape}\"" if envelope_from
arguments = [settings[:arguments], return_path].compact.join(" ")
Sendmail.call(settings[:location], arguments, mail.destinations.collect(&:shellescape).join(" "), mail)
end
def Sendmail.call(path, arguments, destinations, mail)
IO.popen("#{path} #{arguments} #{destinations}", "r+") do |io|
io.puts mail.encoded.to_lf
io.close_write # <------ changed this from flush to close_write
sleep 1 # <-------- added this line
end
end
end
end
答案 1 :(得分:0)
旧版本很可能将邮件传递给“sendmail -t”,该邮件不包含任何收件人标头。 -t告诉sendmail使用这些标题来确定邮件的去向,所以没有它们,你会在from =行的日志中获得nrcpts = 0,并且没有为消息记录=行。