3
Hi! I have a routine on a JSF+Spring 3.0.5 system that sends an email containing 4 attachments in pdfs on every 11th day at 07:01 AM to 11 addresses. My problem is that when the application is in production on a 32-bit Windows Server 2003, 3 messages are sent to each email address. On the other hand, when the application is in a development environment, only one message is sent to each contact. What should happen in production.
This routine was implemented with Spring as follows:
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class EnviarEmailService {
@SuppressWarnings("unused")
// second, minute, hour, day of month, month, day(s) of week
@Scheduled(cron = "30 01 07 11 * *")
private void job() {
try{
enviarEmail();
}catch(Exception e){
e.printStackTrace();
}
}
}
Email method:
public void enviarEmail() {
try {
ResourceBundle resource = ResourceBundle.getBundle("configuracao",Locale.getDefault());
String corpoEmail = "<META HTTP-EQUIV='Content-Type' CONTENT='text/html; charset=ISO-8859-1'>"
+ resource.getString("mensagem").toString();
corpoEmail = corpoEmail + getCorpoEmailAux().toString();
List<String> destinatarios = new ArrayList<String>();
String[] destinos = resource.getString("destinatarios").toString().split(";");
for (String email : destinos) {
destinatarios.add(email);
}
List<String> anexos = new ArrayList<String>();
anexos.add(medido.getDiretorioReal("/pdf/medido.pdf"));
anexos.add(vencido.getDiretorioReal("/pdf/vencido.pdf"));
anexos.add(inconsiste.getDiretorioReal("/pdf/inconsiste.pdf"));
anexos.add(recorrente.getDiretorioReal("/pdf/recorrente.pdf"));
Email email = new Email("smtp",
"mail.cogerh.com.br",
"587",
"true",
resource.getString("remetente").toString(),
resource.getString("senha").toString(),
"ISO-8859-1",
Email.TIPO_TEXTO_HTML,
resource.getString("remetente_nome").toString(),
"true", "*");
email.conectar();
email.prepararEmail(resource.getString("assunto").toString(), corpoEmail, destinatarios, anexos);
email.enviar();
} catch (Exception e) {
// TODO: handle exception
}
Auxiliary methods:
public void prepararEmail(String assunto, String corpoEmail,
List<String> destinatarios, List<String> anexos) {
this.assunto = assunto;
this.corpoEmail = corpoEmail;
this.destinatarios = destinatarios;
this.anexos = anexos;
try {
mensagem = new MimeMessage(session);
mensagem.setFrom(new InternetAddress(getUsuario(), getNomeUsuario()));
mensagem.setSubject(getAssunto());
mensagem.setSentDate(new Date());
if (destinatarios != null && !destinatarios.isEmpty()) {
for (String destinatario : destinatarios) {
mensagem.addRecipient(Message.RecipientType.TO, new InternetAddress(destinatario, destinatario));
}
}
textoMensagemCompleta = new MimeBodyPart();
textoMensagemCompleta.setContent(getCorpoEmail(), getTipoTextoEmail() + "\"ISO-8859-1\"");
parteMensagemCompleta = new MimeMultipart();
parteMensagemCompleta.addBodyPart(textoMensagemCompleta);
if (anexos != null & !anexos.isEmpty()) {
for (int index = 0; index < anexos.size(); index++) {
MimeBodyPart tempMimeBodyPart = new MimeBodyPart();
FileDataSource fds = new FileDataSource(anexos.get(index).toString());
tempMimeBodyPart.setDataHandler(new DataHandler(fds));
tempMimeBodyPart.setFileName(fds.getName());
parteMensagemCompleta.addBodyPart(tempMimeBodyPart);
}
}
mensagem.setContent(parteMensagemCompleta);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void enviar() {
try {
Transport.send(mensagem);
} catch (MessagingException e) {
e.printStackTrace();
}
}
The strategy I thought to fix this problem was:
- Add a table in the "monthly message already sent" database linked to month and year that would bar a second or third shipment.
(It didn’t work because they were inserted at the same time, as if there were 3 threads inserting this control at the same time in the bank).
If you have been through this can you give me a help? Thank you!
There is only one JVM running this in the production environment?
– Victor Stafusa
Hi! Thank you for answering! I have two Jvms: Java SE Development Kit 7 Update 45, Java SE Development Kit 6 Update 23
– Alessandra
Yes, this is the Jvms that are installed, but not necessarily the ones that are running, remembering that it is quite possible that the same JVM is running more than once simultaneously. What and how many are running your program?
– Victor Stafusa
As for your solution of a flag in the database, you may be able to save the sending time up to hundredths (hh:mm:ss.mmm). This would eliminate the thread problem. However, this is a gambit.
– StatelessDev
@Victorstafusa there is only one. In case the same JVM is running more than once simultaneously there is something that can be done?
– Alessandra
@Statelessdev and does not work for the fault in question. Thank you, anyway.
– Alessandra