Search code examples
groovyjakarta-mailmimegroovy-console

Sending an email: no object DCH for MIME type multipart/mixed


I'm trying to send an email using Java code but running from GroovyConsole. It works fine for when I just send an email without attachments but it fails as soon as I add in the multipart logic for attachments.

EDIT: I'm using Javamail version 1.4.7

This is the error I'm getting.

javax.activation.UnsupportedDataTypeException: no object DCH for MIME type multipart/mixed; 

boundary="----=_Part_16_24710054.1375885523061"

at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:891)

and it's happening on the line Transport.send(mimeMsg) below.

import java.util.Properties;
import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;


Properties properties = new Properties()
Session session
MimeMessage mimeMsg 

properties.put("mail.smtp.host", "[my host ip]")

session = Session.getDefaultInstance(properties)
mimeMsg = new MimeMessage(session)

String recipient = "[to email address]"

mimeMsg.addRecipient(Message.RecipientType.TO, new InternetAddress(recipient))

mimeMsg.setSubject("This is the subject")
mimeMsg.setText("This is the message #1")

mimeMsg.setFrom(new InternetAddress("[from email address]"))

BodyPart messageBodyPart = new MimeBodyPart()
messageBodyPart.setText(mimeMsg.getContent())    
Multipart multipart = new MimeMultipart()

String filePath = "[full & correct path to test.txt]"
DataSource source = new FileDataSource(filePath)
messageBodyPart.setDataHandler(new DataHandler(source))

String fileName = "test.txt"
messageBodyPart.setFileName("test.txt")

multipart.addBodyPart(messageBodyPart)

mimeMsg.setContent(multipart)

Transport.send(mimeMsg)

println "Message Sent!"

Solution

  • I think it's a classloader issue to do with the way GroovyConsole runs...

    If I add the following @Grab and @GrabcConfig to the script, it works...

    @Grab( 'javax.mail:mail:1.4.7' )
    @GrabConfig(systemClassLoader=true, initContextClassLoader=true)
    import javax.mail.*
    import javax.mail.internet.*
    import javax.activation.*
    
    def props = new Properties().with { p ->
        p.'mail.smtp.host' = 'my mail server'
        p
    }
    
    def session = Session.getDefaultInstance( props )
    
    def message = new MimeMessage( session )
    
    message.addRecipient( Message.RecipientType.TO, new InternetAddress( 'to address' ) )
    message.subject = 'This is the subject'
    message.text = 'This is the message #1'
    message.from =  new InternetAddress( 'from address' )
    
    def textpart = new MimeBodyPart()
    textpart.text = 'This is the message #2'
    
    def attachment = new MimeBodyPart()
    attachment.dataHandler = new DataHandler( new FileDataSource( '/path/to/file.txt' ) )
    attachment.fileName = 'file.txt'
    
    def multi = new MimeMultipart()
    multi.addBodyPart( textpart )
    multi.addBodyPart( attachment )
    
    message.content = multi
    
    Transport.send( message )
    

    Or, remove the two @Grab and @GrabConfig lines, and run it from the command line with:

    groovy -cp /path/to/mail-1.4.7.jar:/path/to/activation-1.1.jar mail.groovy