简体   繁体   中英

ClassCastException when sending Email using JavaMail

I got this error when trying to send email.

The error from Session debug:

 DEBUG: getProvider() returning jakarta.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]
 DEBUG: Exception loading provider, THROW:
       java.lang.ClassCastException: jakarta.mail.Transport com.sun.mail.smtp.SMTPTransport
        at jakarta.mail.Session.getService(Session.java:838)
        at jakarta.mail.Session.getTransport(Session.java:772)
        at jakarta.mail.Session.getTransport(Session.java:713)
        at jakarta.mail.Session.getTransport(Session.java:693)
        at jakarta.mail.Session.getTransport(Session.java:677)
        ...

The error throws in the app:

 jakarta.mail.NoSuchProviderException: smtp
        at jakarta.mail.Session.getService(Session.java:842) ~[jakarta.jakartaee-api-9.0.0.jar:?]
        at jakarta.mail.Session.getTransport(Session.java:772) ~[jakarta.jakartaee-api-9.0.0.jar:?]
        at jakarta.mail.Session.getTransport(Session.java:713) ~[jakarta.jakartaee-api-9.0.0.jar:?]
        at jakarta.mail.Session.getTransport(Session.java:693) ~[jakarta.jakartaee-api-9.0.0.jar:?]
        at jakarta.mail.Session.getTransport(Session.java:677) ~[jakarta.jakartaee-api-9.0.0.jar:?]
        ...

Looking at the source code of the jakarta.mail.Session.getService():

if (serviceClass == null || !type.isAssignableFrom(serviceClass))
            serviceClass =
                Class.forName(provider.getClassName(), false, cl);  // [line:838] The line where the Session debug shows where it happened. 
                
            if (!type.isAssignableFrom(serviceClass))
            throw new ClassCastException(
                    type.getName() + " " + serviceClass.getName());  // [line:842] The line where the error throws in the app shows where it happened.

I could not tell what is the problem from the source code above.

Here is my code:

    /**
     * Setting up e-mail settings.
     * 
     * @return Session instance.
     */
    private Session setSession(PrintStream ps) {
        logger.debug("Setting up email setting ...");
        Properties props = new Properties();
        props.put("mail.smtp.host", EMAIL_SERVER);
        props.put("mail.smtp.connectiontimeout", TIMEOUT);
        props.put("mail.smtp.timeout", TIMEOUT);
        
        Session session = Session.getInstance(props, null);
        session.setDebug(true);
        session.setDebugOut(ps);
        logger.debug("Done.");
        return session;
    }
    
    
    public void send(String toEmail, String body, String subject) {
    
        Transport transport = null;
        PrintStream logps = IoBuilder.forLogger(LogManager.getLogger())
                                     .setLevel(Level.DEBUG)
                                     .buildPrintStream();
    
        try {
            Session session = setSession(logps);
            transport = session.getTransport("smtp");
            transport.connect();
            MimeMessage msg = new MimeMessage(session);
            
            // Set message headers
            logger.debug("Setting up MimeMessage Header ...");
            msg.addHeader("Content-type", "text/HTML; charset=UTF-8");
            logger.debug("Done.");
            
            msg.setSubject(subject, "UTF-8");
            
            // For body content
            MimeBodyPart mimeBody = new MimeBodyPart();
            mimeBody.setContent(body,"text/html; charset=utf-8");
            
            // For footer
            MimeBodyPart mimeFooter = new MimeBodyPart();
            mimeFooter.setContent(footer(),"text/html; charset=utf-8");
            
            // put all MimeBodyPart into multipart
            Multipart multipart = new MimeMultipart();
            multipart.addBodyPart(mimeBody);
            multipart.addBodyPart(mimeFooter);
            
            // Set content into msg
            msg.setContent(multipart);
            
            msg.setSentDate(new Date());
            logger.debug("Done");
            
            logger.debug("Message is ready. Sending email ...");
            logger.debug("JavaMail debug info before sending email:");
            logger.debug(logps);
            transport.sendMessage(msg,InternetAddress.parse(toEmail.trim(), false));
            logger.debug("JavaMail debug info after sending email:");
            logger.debug(logps);
            logger.debug("E-Mail Sent Successfully.");
            
            
        } catch (MessagingException e) {
            logger.fatal("Error while composing email.",e);
        } catch (Exception ex) {
            logger.fatal("Error sending email.",ex);
        } finally {
            try {
                transport.close();
            } catch (MessagingException e) {
                logger.fatal("Error while closing Transport connection.",e);
            }
        }
    }
    
    public String footer() {
        return "<hr><br/><br/><i>This is system generated, please do not reply to this email</i>";
    }

About the NoSuchProviderException error, I found somewhere that I need to add smtp.jar in my path to resolve it, but still the same error occur after adding the jar. That is the only solution that I found after googling.

And for the java.lang.ClassCastException thrown from Session debug, I found nothing about it.

The problem was solved by updating the jars from 1.6.2 to 2.0.1. I'm not sure if it was a bug in the jar or something wrong with my code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM