java.lang.NoClassDefFoundError: javax/mail/Authenticator, whats wrong?

Viewed 121238

Send to Email.java

package helper;

//Mail.java - smtp sending starttls (ssl) authentication enabled
//1.Open a new Java class in netbeans (default package of the project) and name it as "Mail.java"
//2.Copy paste the entire code below and save it.
//3.Right click on the file name in the left side panel and click "compile" then click "Run"

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

public class sendToEmail
{
    String  d_email = "sample@gmail.com",
     d_password = "mysamplepassword",
     d_host = "smtp.gmail.com",
     d_port  = "465",
     //m_to = "sample@yahoo.com",
     m_subject = "trial",
     m_text = "Hey, this is the testing email.";

    public sendToEmail(String strEmailAddress)
    {


        Properties props = new Properties();
        props.put("mail.smtp.user", d_email);
        props.put("mail.smtp.host", d_host);
        props.put("mail.smtp.port", d_port);
        props.put("mail.smtp.starttls.enable","true");
        props.put("mail.smtp.auth", "true");
        //props.put("mail.smtp.debug", "true");
        props.put("mail.smtp.socketFactory.port", d_port);
        props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        props.put("mail.smtp.socketFactory.fallback", "false");

        SecurityManager security = System.getSecurityManager();

        try
        {
            Authenticator auth = new SMTPAuthenticator();
            Session session = Session.getInstance(props, auth);
            //session.setDebug(true);

            MimeMessage msg = new MimeMessage(session);
            msg.setText(m_text);
            msg.setSubject(m_subject);
            msg.setFrom(new InternetAddress(d_email));
            msg.addRecipient(Message.RecipientType.TO, new InternetAddress(strEmailAddress));
            Transport.send(msg);
        }
        catch (Exception mex)
        {
            mex.printStackTrace();
        } 
    }

    public class SMTPAuthenticator extends javax.mail.Authenticator
    {
        public PasswordAuthentication getPasswordAuthentication()
        {
            return new PasswordAuthentication(d_email, d_password);
        }
    }
}

portion of my controller.java

/* Send to Email will run properly soon */
            sendToEmail email = new sendToEmail(strEmailAddress);

When I run my web application I got this error message saying:

Type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception javax.servlet.ServletException: Servlet execution threw an exception

root cause java.lang.NoClassDefFoundError: javax/mail/Authenticator controller.RegisterTenantController.doPost(RegisterTenantController.java:108) javax.servlet.http.HttpServlet.service(HttpServlet.java:709) javax.servlet.http.HttpServlet.service(HttpServlet.java:802)

What will I do now? Can somebody help me to get this web application successful?

7 Answers

Even I was facing a similar error. Try below 2 steps (the first of which has been recommended here already) - 1. Add the dependencies to your pom.xml

         <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>1.4.5</version>
        </dependency>

        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1.1</version>
        </dependency>
  1. If that doesn't work, manually place the jar files in your .m2\repository\javax\<folder>\<version>\ directory.

When running with com.sun.mail group, version 1.6.2 under a Servlet environment, notice that artifact:

  • mailapi contains javax.mail.Authenticator but not the 'provider' classes
  • javax.mail contains both javax.mail.Authenticator and all the sun.com.mail 'provider` classes (SMTP, IMAP and POP3)
  • smtp (and imap and pop3) don't contain javax.mail.Authenticator ... just each com.sun.mail.* provider on its own

Now, if one didn't want IMAP and POP3 (since these are client protocols for fetching email) but just SMTP for sending, you want javamail-1.6.2.jar and smtp-1.6.2.jar.

Now in a Servlet environment, realise that you can either choose 'use what the container provides' or 'supply my own'. So you either place both those JAR files in the Container's 'common' runtime, or you supply both those JAR files in your own WEB-INF\lib directory ... and it will work.

What you can't do is put javamail-1.6.2.jar into your WEB-INF\lib and smtp-1.6.2.jar into your $TOMCAT_HOME/lib. Why not? Because, class-loader hierarchy. The SMTP provider needs the javax.mail classes. But (unlike , significantly, java.sql), the javax.mail classes are not loaded by the system classloader 'further up' or even 'at the same level' ... they're loaded by a classloader that's specific to YOUR webapp on 'one of the branches down'! So when the SMTP provider wants a javax.mail class, it doesn't find one, because the 'common to everyone' classloader has no business looking into individual webapps to load the required classes!

So either:

  • use javax.mail-1.6.2.jar and no other JavaMail JARs; OR
  • use both javamail-1.6.2.jar with smtp-1.6.2.jar

but always put these all in the Server's common libraries OR all in your web-app's common libraries.

Which stance you adopt depends on you. There are pros and cons each way. Classes you supply in WEB-INF\libs are always going to 'win', in case you need to defeat an older version loaded as 'common' by the Server. But that may not be a great idea, always.

Related