-
1. Re: Seam email resend on exception or error
gaborj Apr 15, 2010 5:14 PM (in response to tathagat)- One option is that you define a mail-queue as JMS queue, put your messages into the queue. The sender then checks SMTP server status before sending messages from the queue. If your SMTP is down your queue is getting filled with messages when it recovers after outage your messages are delivered in the order they were sent, this queue is persistent so you never loose msg...
- Of course similar processing can be implemented using database where you save the state of your messages and you run a scheduler e.g. Quartz with some short interval as sender (I think there is an asynchronous processor in mail example)...
- Or you can combine these two above
-
2. Re: Seam email resend on exception or error
tathagat Apr 18, 2010 11:15 PM (in response to tathagat)Thank you for your reply!
I think databbase AND quartz approach would be best to guarantee success against SMTP failure and between restarts.Now the question is - How do I save the state of my email message in database?
I send email using the following code (from seam docs):
Contexts.getEventContext().set("emailInfo", infoNeededForTemplate); renderer.render(template);
Thanks again in advance.
Cheers
T -
3. Re: Seam email resend on exception or error
kapitanpetko Apr 19, 2010 3:18 AM (in response to tathagat)
Tathagat Tathagat wrote on Apr 18, 2010 23:15:
I think databbase AND quartz approach would be best to guarantee success against SMTP failure and between restarts.
Now the question is - How do I save the state of my email message in database?This has been asked before, search the forum. In general:
- if you want more control, use JavaMail directly
- if you do insist on using Seam mail, install your own Transport that saves the mail to DB before sending.
HTH
-
4. Re: Seam email resend on exception or error
tathagat Apr 19, 2010 1:34 PM (in response to tathagat)Great. Thanks so much :).
In the end I wrote my own transport which saves the email in the DB.
Cheers
-
5. Re: Seam email resend on exception or error
tathagat Apr 19, 2010 2:59 PM (in response to tathagat)May be I spoke too soon :).
In my custom Transport I do the following (overiding sendMessage)
public void sendMessage(Message message, Address[] addresses) { try { // saving in DB // get the bytes from message and save in DB or do whatever super.sendMessage(message, addresses); logger.debug("sendMessage: " + this.getLastReturnCode()); } catch (SendFailedException e) { logger.error("sendMessage", e); } catch (MessagingException e) { logger.error("sendMessage", e); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
This works fine.
Now to test, I passed in the wrong password from components.xml
<mail:mail-session host="smtp.gmail.com" port="465" ssl="true" username="USERNAME" password="WRONG PASSWORD"/>
At this point, my code throws exception even before it goes inside sendMessage.
Exception when renderer.render(template) is called
javax.faces.FacesException: failed to connect Caused by: javax.mail.AuthenticationFailedException: failed to connect
So again, I do not have access to the message object to persist. Is there a way around this problem?
Thanks again
Cheers
T -
6. Re: Seam email resend on exception or error
kapitanpetko Apr 19, 2010 3:31 PM (in response to tathagat)I don't have the code here, but maybe Seam's MailSession tries to authenticate first? Hit it with the debugger to see where it fails. Are you sure your Transport is installed properly?
-
7. Re: Seam email resend on exception or error
tathagat Apr 19, 2010 3:33 PM (in response to tathagat)Thanks for the hint!
Doing debugging now - will keep you posted.
Yes, when there are no errors - my debug statements in custom Transport get printed.
Thanks a ton :).
Cheers
T -
8. Re: Seam email resend on exception or error
tathagat Apr 19, 2010 5:07 PM (in response to tathagat)Alright!
After some debugging I found out that the method connect() was being called in javax.mail.Service somewhere down the line before sendMessage was called.So I did the following:
In my custom Transport override connect() methodpublic void connect() { logger.debug("connect: DO NOTHING!"); }
and in public void sendMessage(Message message, Address[] addresses) (also in my custom Transport) I called super.connect() before super.sendMessage(message, addresses).
Doing this I have a handle to message no matter what goes wrong.
I hope this helps someone and I hope I don't find another problem :).
Thanks for all the help!
Cheers
T -
9. Re: Seam email resend on exception or error
tathagat Apr 20, 2010 11:29 AM (in response to tathagat)Hoping didn't help :D. Got another problem.
I user hibernate session with tomcat for persistence.
So I use in my classes:@In Session managedHibernateSession;
which is defined in my components.xml.
It works fine everywhere, except when I try to use it in my Custom Transport.
@Scope(ScopeType.APPLICATION) public class CustomTransport extends SMTPSSLTransport { @In(create=true,value="managedHibernateSession") org.hibernate.Session managedHibernateSession;
managedHibernateSession is always null!
Any guesses why? I tried different scopes on the class (although I have another class with Application scope and it works fine there).
Thanks in advance.
Cheers
T -
10. Re: Seam email resend on exception or error
tathagat Apr 20, 2010 11:35 AM (in response to tathagat)Also, what's strange is:
@Create public void create() { logger.debug("Creating Custom Transport"); }
This code is never being called in my CustomTransport class.
Cheers
T -
11. Re: Seam email resend on exception or error
kapitanpetko Apr 20, 2010 12:58 PM (in response to tathagat)I don't think the transport can be a Seam component, hence not @Create-ing and @In-jecting. Instantiate your Session without using Seam.
-
12. Re: Seam email resend on exception or error
tathagat Apr 20, 2010 2:32 PM (in response to tathagat)Thanks for the hint.
I could not figure out how to instantiate my own Session (right now Seam does it reading from components.xml)
So I created following properties in my CustomTransport
private Message message; private Address[] addresses; private int returnCode;
and changed the sendMessage method to fill them.
public void sendMessage(Message _message, Address[] _addresses) { setMessage(_message); setAddresses(_addresses); try { super.connect(); super.sendMessage(_message, _addresses); } catch (SendFailedException e) { logger.error("sendMessage", e); } catch (MessagingException e) { logger.error("sendMessage", e); } finally { returnCode = this.getLastReturnCode(); } }
This also required the constructor to be changed
private static CustomTransport customTransport ; public CustomTransport(Session session, URLName urlname) { super(session, urlname); customTransport = this; }
and a getInstance method to be created
public static CustomTransport getInstance() { return customTransport ; }
Now after sending an email, I can fetch the values from my CustomTransport and save them in the DB.
Thanks again for all the help :).
P.S. May be someone can tell me how to instantiate Hibernate Session object manually?
Cheers
T -
13. Re: Seam email resend on exception or error
kapitanpetko Apr 21, 2010 3:12 AM (in response to tathagat)Good that it worked out, but consider what happens if two messages are sent more or less simultaneously. You instantiate a Session the usual way: create a SesssionFactory, then call openSession.
-
14. Re: Seam email resend on exception or error
tathagat Apr 21, 2010 1:22 PM (in response to tathagat)abso-freakin-lutely right!
I was worrying about that but did not have another solution at hand.
I still could not get a Session using SessionFactory (tried HibernateUtil). Always one exception or the other.
But in the end this worked
org.hibernate.Session hibernateSession = (org.hibernate.Session) Component.getInstance("managedHibernateSession");
Now all is good :).
Thanks again so much for all the help.
Cheers
T