Рабочие примеры:
1) Приложение имеет интерфейс InputStreamSource
public void send() throws IOException, MessagingException {
final ByteArrayOutputStream stream = createInMemoryDocument("body");
final InputStreamSource attachment = new ByteArrayResource(stream.toByteArray());
final MimeMessage message = javaMailSender.createMimeMessage();
final MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setSubject("subject");
helper.setFrom("from@from.com");
helper.setTo("to@to.com");
helper.setReplyTo("replyTo@replyTo.com");
helper.setText("stub", false);
helper.addAttachment("document.txt", attachment);
javaMailSender.send(message);
}
2) Приложение имеет интерфейс DataSource
public void send() throws IOException, MessagingException {
final ByteArrayOutputStream document = createInMemoryDocument("body");
final InputStream inputStream = new ByteArrayInputStream(document.toByteArray());
final DataSource attachment = new ByteArrayDataSource(inputStream, "application/octet-stream");
final MimeMessage message = javaMailSender.createMimeMessage();
final MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setSubject("subject");
helper.setFrom("from@from.com");
helper.setTo("to@to.com");
helper.setReplyTo("replyTo@replyTo.com");
helper.setText("stub", false);
helper.addAttachment("document.txt", attachment);
javaMailSender.send(message);
}
Объяснение:
Переданный ресурс содержит открытый поток: недопустимый аргумент.
JavaMail требует InputStreamSource, который создает свежий поток для
каждый звонок.
Это сообщение может появиться, если разработчик использует реализацию InputStreamSource
, которая возвращает true
в методе isOpen()
.
В методе есть специальная проверка MimeMessageHelper#addAttacment()
:
public void addAttachment(String attachmentFilename, InputStreamSource inputStreamSource, String contentType) {
//...
if (inputStreamSource instanceof Resource && ((Resource) inputStreamSource).isOpen()) {
throw new IllegalArgumentException(
"Passed-in Resource contains an open stream: invalid argument. " +
"JavaMail requires an InputStreamSource that creates a fresh stream for every call.");
}
//...
}
InputStreamResource#isOpen()
всегда возвращает true
, что делает невозможным использование этой реализации в качестве вложения:
public class InputStreamResource extends AbstractResource {
//...
@Override
public boolean isOpen() {
return true;
}
//...
}