JRuby (please use github issues at http://bugs.jruby.org)
  1. JRuby (please use github issues at http://bugs.jruby.org)
  2. JRUBY-6804

Jruby cannot work with sendmail in a rails environment (or IO.popen does not function in jruby)

    Details

    • Type: Bug Bug
    • Status: Resolved Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: JRuby 1.6.7
    • Fix Version/s: JRuby 1.7.0.RC2
    • Component/s: Standard Library
    • Labels:
      None
    • Environment:
    • Testcase included:
      yes
    • Number of attachments :
      2

      Description

      Deploying a Rails application with JRuby to production is impossible due to the fact that JRuby has a bug when using IO.popen and sendmail.rb (%GEM_HOME%/gems/mail-2.4.4/lib/mail/network/delivery_methods/sendmail.rb)
      depends on this functionality.

      I have isolated the issue and have a tiny script that when run under MRI ruby will email. The same script, when run via jruby, has no errors and no email is ever sent. Monitoring of /var/log/maillog confirms this.

      Consider the following script (email_test.rb):

       
      def file_as_string(file)
      	rVal = ''
      	File.open(file, 'r') do |file_handle|
      		file_handle.read.each_line do |line|
      			rVal << line
      		end
      	end
      	rVal
      end
      IO.popen("/usr/sbin/sendmail -i -t -f \"cristopher.shupp@va.gov\" cristopher.shupp@va.gov", "w+") do |io|
        email = file_as_string("/tmp/the_email.txt")
        io.puts email
        io.flush
      end
      
      #from sendmail.rb
      #  def self.call(path, arguments, destinations, mail)
      #    IO.popen("#{path} #{arguments} #{destinations}", "w+") do |io|
      #      io.puts mail.encoded.to_lf
      #      io.flush
      #    end
      #  end
      

      when run via MRI ruby as follows:

       /u01/dev/ruby_1.8.7/bin/ruby /tmp/email_test.rb
      

      Then sendmail's log (/var/log/maillog) is filled with activity, and an email arrives:

      Jul 31 09:11:25 vahdrtvapp05 sendmail[11520]: q6VEBO2a011520: Authentication-Warning: vahdrtvapp05.aac.va.gov: t192zcs set sender to cristopher.shupp@va.gov using -f
      Jul 31 09:11:25 vahdrtvapp05 sendmail[11520]: q6VEBO2a011520: from=cristopher.shupp@va.gov, size=359, class=0, nrcpts=1, msgid=<5017ded29f6c8_5487e267025@vahdrtvapp05.aac.va.gov.mail>, relay=t192zcs@localhost
      Jul 31 09:11:25 vahdrtvapp05 sendmail[11524]: q6VEBPPt011524: from=<cristopher.shupp@va.gov>, size=631, class=0, nrcpts=1, msgid=<5017ded29f6c8_5487e267025@vahdrtvapp05.aac.va.gov.mail>, proto=ESMTP, daemon=NoMTA4, relay=localhost.localdomain [127.0.0.1]
      Jul 31 09:11:25 vahdrtvapp05 sendmail[11520]: q6VEBO2a011520: to=cristopher.shupp@va.gov, ctladdr=cristopher.shupp@va.gov (1174/7400), delay=00:00:01, xdelay=00:00:00, mailer=relay, pri=30359, relay=[127.0.0.1] [127.0.0.1], dsn=2.0.0, stat=Sent (q6VEBPPt011524 Message accepted for delivery)
      Jul 31 09:11:26 vahdrtvapp05 sendmail[11526]: q6VEBPPt011524: to=<cristopher.shupp@va.gov>, delay=00:00:01, xdelay=00:00:01, mailer=relay, pri=120631, relay=mailproxy.aac.va.gov [10.238.10.254], dsn=2.0.0, stat=Sent (ok:  Message 49228463 accepted)
      

      When run via jruby as follows:

       java -jar ./lib/jars/jruby-complete-1.6.7.2.jar /tmp/email_test.rb 
      

      There is no output and sendmail's log remains silent.

      1. email_test.rb
        0.5 kB
        Cris Shupp
      2. the_email.txt
        0.4 kB
        Cris Shupp

        Activity

        Hide
        Cris Shupp added a comment -

        modifying email_test.rb as follows

        require 'java'
        
        java_import 'java.lang.Runtime' do |pkg, cls|
          'JRuntime'
        end
        
        java_import 'java.io.OutputStreamWriter' do |pkg, cls|
          'JWrite'
        end
        
        java_import 'java.io.BufferedWriter' do |pkg, cls|
          'JBWrite'
        end
        
        def file_as_string(file)
        	rVal = ''
        	File.open(file, 'r') do |file_handle|
        		file_handle.read.each_line do |line|
        			rVal << line
        		end
        	end
        	rVal
        end
        email = file_as_string("/tmp/the_email.txt")
        process = JRuntime.getRuntime().exec("/usr/sbin/sendmail -i -t -f \"cristopher.shupp@va.gov\" cristopher.shupp@va.gov")
        outputStream = process.getOutputStream
        writer = JBWrite.new(JWrite.new(outputStream))
        writer.write(email,0,email.length)
        writer.close
        
        
        #IO.popen("/usr/sbin/sendmail -i -t -f \"cristopher.shupp@va.gov\" cristopher.shupp@va.gov", "w+") do |io|
        #  email = file_as_string("/tmp/the_email.txt")
        #  io.puts email
        #  io.flush
        #end
        
        #from sendmail.rb
        #  def self.call(path, arguments, destinations, mail)
        #    IO.popen("#{path} #{arguments} #{destinations}", "w+") do |io|
        #      io.puts mail.encoded.to_lf
        #      io.flush
        #    end
        #  end
        

        does work. Now to find a workaround in rails...

        Show
        Cris Shupp added a comment - modifying email_test.rb as follows require 'java' java_import 'java.lang.Runtime' do |pkg, cls| 'JRuntime' end java_import 'java.io.OutputStreamWriter' do |pkg, cls| 'JWrite' end java_import 'java.io.BufferedWriter' do |pkg, cls| 'JBWrite' end def file_as_string(file) rVal = '' File.open(file, 'r') do |file_handle| file_handle.read.each_line do |line| rVal << line end end rVal end email = file_as_string("/tmp/the_email.txt") process = JRuntime.getRuntime().exec("/usr/sbin/sendmail -i -t -f \"cristopher.shupp@va.gov\" cristopher.shupp@va.gov") outputStream = process.getOutputStream writer = JBWrite.new(JWrite.new(outputStream)) writer.write(email,0,email.length) writer.close #IO.popen("/usr/sbin/sendmail -i -t -f \"cristopher.shupp@va.gov\" cristopher.shupp@va.gov", "w+") do |io| # email = file_as_string("/tmp/the_email.txt") # io.puts email # io.flush #end #from sendmail.rb # def self.call(path, arguments, destinations, mail) # IO.popen("#{path} #{arguments} #{destinations}", "w+") do |io| # io.puts mail.encoded.to_lf # io.flush # end # end does work. Now to find a workaround in rails...
        Hide
        Charles Oliver Nutter added a comment -

        Surprising that the popen version doesn't work; of all the process-launching mechanisms, it's the simplest. We basically just use Runtime.exec, get the streams into an IO, and that's that.

        Will investigate for 1.7.0pre2.

        Show
        Charles Oliver Nutter added a comment - Surprising that the popen version doesn't work; of all the process-launching mechanisms, it's the simplest. We basically just use Runtime.exec, get the streams into an IO, and that's that. Will investigate for 1.7.0pre2.
        Hide
        Thomas E Enebo added a comment -

        Cris, Can you try JRuby 1.7.0.RC1? popen has been changed since 1.6.x.

        Show
        Thomas E Enebo added a comment - Cris, Can you try JRuby 1.7.0.RC1? popen has been changed since 1.6.x.
        Hide
        Cris Shupp added a comment -

        Thomas,

        I will test next week. Sorry for the delay.

        Cris

        Show
        Cris Shupp added a comment - Thomas, I will test next week. Sorry for the delay. Cris
        Hide
        Cris Shupp added a comment -

        I retested with my unit test cases and RC2 did send the e-mail as desired!

        Show
        Cris Shupp added a comment - I retested with my unit test cases and RC2 did send the e-mail as desired!

          People

          • Assignee:
            Thomas E Enebo
            Reporter:
            Cris Shupp
          • Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: