I'm developing a class that uses javax.mail which simply receives some parameters from my AS400 RPGLE program and sends an email that contains a Subject, Body and an Attachment.
In the parameters I'm passing the path of a server (ex: '\\192.0.0.100\docs\new') and the name (ex: File.pdf) of the file that will be attached, which in this case it's a .pdf file. To read the file inside the server I'm authenticating using SmbFile passing the domain, user and password.
I've tested the code several times running it locally in my eclipse calling the method from my main class passing the parameters hardcoded and it sends the email successfully, the problem starts when I deploy my class in production, I get a "javax.mail.MessagingException: IOException while sending message; nested exception is: java.io.FileNotFoundException: \\192.0.0.100\docs\new\File.pdf (A file or a directory in the name does not exist.)".
The interesting part is that the error comes when the program calls Transport.send(message);
, before sending the email I've put a if(sFileReader.exists())
and it gives no error.
I've also put some logs to monitor the values passed through the variables and they are all correct, exactly as the ones that I was using for my local tests. Tried also in production to send an email without an attachment and it works.
Do you guys have any idea? Thanks a lot.
Below an example of my code and how I was calling my method locally:
public static void main(String[] args) throws Exception {
sendEmail("192.0.0.100", "100", "user", "pwd", "[email protected]",
"[email protected]", "Subject", "Body", "smb://192.0.0.100/doc/new/", "File.PDF",
"domain", "user", "pwd");
}
public static void sendEmail(String server_ip, String server_port, final String username_mail, final String password_mail, String EMAIL_FROM, String list_emails, String subject, String body, String attachment_path, String attachment_name, String domain_attach, String user_attach, String password_attach) throws AddressException, MessagingException {
Session session = null;
Properties properties = null;
MimeMessage message = null;
MimeBodyPart attachmentBodyPart = null, textBodyPart = null;
Multipart multipart = null;
NtlmPasswordAuthentication auth_attach = null;
SmbFile sPathReader = null, sFileReader = null;
DataSource source = null;
properties = System.getProperties();
properties.setProperty("mail.smtp.host", server_ip);
properties.put("mail.smtp.port", server_port);
if(username_mail != "" && password_mail != "") {
Authenticator auth = new Authenticator() {
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username_mail, password_mail);
}
};
session = Session.getInstance(properties, auth);
}else {
session = Session.getDefaultInstance(properties);
}
try {
// Authenticate to the server
auth_attach = new NtlmPasswordAuthentication(domain_attach, user_attach, password_attach);
sPathReader = new SmbFile(attachment_path, auth_attach);
sFileReader = new SmbFile(sPathReader, attachment_name);
if(sFileReader.exists()) {
message = new MimeMessage(session);
message.setFrom(new InternetAddress(EMAIL_FROM));
message.addRecipient(Message.RecipientType.TO,
new InternetAddress(list_emails));
message.setSubject(subject);
textBodyPart = new MimeBodyPart();
textBodyPart.setText(body);
attachmentBodyPart = new MimeBodyPart();
multipart = new MimeMultipart();
source = new FileDataSource(sFileReader.getUncPath());
attachmentBodyPart.setDataHandler(new DataHandler(source));
attachmentBodyPart.setFileName(attachment_name);
multipart.addBodyPart(textBodyPart);
multipart.addBodyPart(attachmentBodyPart);
message.setContent(multipart);
// Send message
Transport.send(message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
I've found out the problem, my program works correctly for the ones that need to get a file from a server in windows, but in my case I was calling my class from AS400 using a RPGLE program and it has a different way of accessing external urls, it needs a "/QNTC/" in the path, for example "/QNTC/192.0.0.100/docs/test.pdf", it's not needed to authenticate in Java, IBM will do it, so in this case a simple String containing the URL was needed.
IBM has a good documentation about it, on how to configure under IFS the QNTC paths.
I hope it helps somebody.