Glassfish ed SMTP, come ricevere exception via email

Una delle cose più comode che si possano pensare per ricevere delle exception è riceverle direttamente via email, con tanto di Stack Trace e nome della classe (o bean) che l’ha generata.

A tal fine mi sono scritto un piccolo session bean che viene poi chiamato dall’exception handler in altri componenti delle mie applicazioni.

La prima cosa da fare è configurare una risorsa JavaMail su Glassfish:

Glassfish JavaMail setup
Glassfish JavaMail (click per ingrandire)

Se avete la fortuna, come nel mio caso, di avere a disposizione un server SMTP aperto a dogs&pigs allora basterà impostare un nome JNDI, l’host e dare un utente a proprio piacimento.

Il passo successivo è creare un bean che verrà utilizzato da tutti gli altri componenti per mandare le email:

public class sendMail implements sendMailLocal {

    // Map resource configured in Glassfish server
    @Resource(name = "$JNDI_NAME") // Inserite qui il JNDI che avete impostato su Glassfish
    private Session mailSession;
    static protected final Logger log = Logger.getLogger(sendMail.class.getName());

    /**
     * EJB used to send emails
     * @param recipient
     * @param subject
     * @param body
     */
    @Override
    public void doSendMail(String recipient, String subject, String body) {

        // Prepare mail session
        Message msg = new MimeMessage(mailSession);

        try {
            // Set transport to SMTP
            Transport trans = mailSession.getTransport("smtp");
            msg.setSubject(subject);

            // Parse recepients in properties file
            StringTokenizer recipientToken = new StringTokenizer(recipient,",;");
            while (recipientToken.hasMoreTokens()) {
                String email = recipientToken.nextToken();
                msg.addRecipient(RecipientType.TO, new InternetAddress(email));
            }
            msg.setText(body);
            Transport.send(msg);
        } catch (MessagingException me) {
            StringWriter sw = new StringWriter();
            me.printStackTrace(new PrintWriter(sw));
            String stacktrace = sw.toString();
            log.log(Level.INFO, stacktrace);
        }
    }
}

A questo punto non rimane che invocare il bean, in questo caso mandiamo una mail in caso di exception dentro un message driven bean:

@EJB
private sendMailLocal sendMail;
....

@Override
    public void onMessage(Message message) {

        ....

        } catch (JMSException je) {
            log.log(Level.WARNING, je.toString());
            sendMail.doSendMail("someuser@vostrodomain.it", "Vostro Subject",
                    "Something went very bad");
        }
    }
}

Invece nel caso si voglia chiamare il bean da una classe comune (pojo):

public class vostraClasse {

    sendMailLocal sendMail = lookupsendMailLocal();
    ....
    private sendMailLocal lookupsendMailLocal() {
        try {
            Context c = new InitialContext();
            return (sendMailLocal) c.lookup(""pathToEJB");
        } catch (NamingException ne) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }

Se utilizzate Netbeans, come me, basta un click destro e selezionare “Call Enteprise Bean”, tutto il codice necessario verrà generato automaticamente.
Torniamo ora al caso del MDB che manda un’email in caso di exception:

        } catch (JMSException je) {
            log.log(Level.WARNING, je.toString());
            sendMail.doSendMail("someuser@vostrodomain.it", "Vostro Subject",
                    "Something went very bad");
        }

Non è che sia molto utile un’informazione così striminzita, noi vogliamo invece lo stacktrace dettagliato, il trucco è molto semplice:

} catch (JMSException je) {
      StringWriter sw = new StringWriter();
      je.printStackTrace(new PrintWriter(sw));
      String stacktrace = je.toString();
      sendMail.doSendMail("someuser@vostrodomain.it", "Vostro Subject", 
           "Exception " + getClass().getName() + "\n" + stacktrace);
}

Leave a Reply

Your email address will not be published. Required fields are marked *