drewr / postal

Clojure email support
MIT License
586 stars 85 forks source link

Is the attached file left open? #76

Open fdabrao opened 8 years ago

fdabrao commented 8 years ago

I used this code and after finish I can´t delete the attached file, any idea? (send-message {:host "smtp.gmail.com" :user usuario :pass senha :tls :yes :port 587} {:from usuario :to destino :subject "Reports" :body [{:type "text/html" :content (clojure.string/replace (slurp template) #"\$mes" mes)} {:type :inline :content (java.io.File. anexo) :content-type "application/pdf"}]})

drewr commented 8 years ago

Is this on Windows?

fdabrao commented 8 years ago

Yes, on Windows

charles-dyfis-net commented 8 years ago

I don't believe the JVM guarantees a timeline for GC. If you use a try/finally block to force the file to close, does that resolve the issue?

(BTW, Windows is the only modern operating system I know of where open files can't be unlinked; typically it's just a reference count decrement).

fdabrao commented 8 years ago

I tried this too: ( let [anexo (java.io.File. "file.pdf")] (send-message {:host "smtp.gmail.com" :user usuario :pass senha :tls :yes :port 587} {:from usuario :to destino :subject "Reports" :body [{:type "text/html" :content (clojure.string/replace (slurp template) #"\$mes" mes)} {:type :inline :content anexo :content-type "application/pdf"}]} (.close anexo)) , same result

drewr commented 8 years ago

Yeah this is why I asked if it's Windows. As Charles mentioned it has to do with GC and dangling references. There are various workarounds you can try. I've found that GCing isn't enough and retrying with a few hundred ms delay is more effective.

fdabrao commented 8 years ago

So, I tried to rewrite it like:

(defn make-auth [user pass]
    (proxy (javax.mail.Authenticator) []
        (getPasswordAuthentication [] (PasswordAuthentication. user pass))))
(defn enviar-email-anexo [host porta usuario senha anexo destinatario]
    (let [prop (Properties.)
                _ (.put prop "mail.smtp.host" host) 
                _ (.put prop "mail.smtp.port" porta)
                _ (.put prop"mail.smtp.auth" true)
                _ (.put prop "mail.smtp.starttls.enable" true)
                _ (.put prop "mail.user" usuario)
                _ (.put prop "mail.password" senha)
                auth (make-auth usuario senha)
                sessao (Session/getInstance prop auth)
                mensagem (MimeMessage. sessao)
                messageBodyPart (MimeBodyPart.)
                multipart (MimeMultipart.)
                attachPart (MimeBodyPart.)
                ]
        (.setFrom mensagem (InternetAddress. usuario))
        (.setRecipient mensagem Message$RecipientType/TO (InternetAddress. destinatario))
        (.setSubject mensagem "Relatório de Service Desk")

        (.setContent messageBodyPart "<html><body>Hello</body></html>" "text/html")
        (.addBodyPart multipart messageBodyPart)

        (.attachFile attachPart anexo)
        (.addBodyPart multipart attachPart)

        (.setContent mensagem multipart)
        (Transport/send mensagem)
        ))

and it´s not blocking the file. So I think in some situation your code keep the file open.