java.lang.NoClassDefFoundError: javax/mail/Authenticator, whats wrong?
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.s开发者_运维问答etText(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?
You need to add two jars into the WEB-INF/lib directory or your webapp (or lib directory of the server):
- mail.jar - contains the actual smtp implmentation
- activation.jar - needed by mail.jar
While it's possible that this is due to a jar file missing from your classpath, it may not be.
It is important to keep two or three different exceptions strait in our head in this case:
java.lang.ClassNotFoundException
This exception indicates that the class was not found on the classpath. This indicates that we were trying to load the class definition, and the class did not exist on the classpath.java.lang.NoClassDefFoundError
This exception indicates that the JVM looked in its internal class definition data structure for the definition of a class and did not find it. This is different than saying that it could not be loaded from the classpath. Usually this indicates that we previously attempted to load a class from the classpath, but it failed for some reason - now we're trying again, but we're not even going to try to load it, because we failed loading it earlier. The earlier failure could be aClassNotFoundException
or anExceptionInInitializerError
(indicating a failure in the static initialization block) or any number of other problems. The point is, aNoClassDefFoundError
is not necessarily a classpath problem.
I would look at the source for javax.mail.Authenticator
, and see what it is doing in it's static initializer. (Look at static variable initialization and the static block, if there is one.) If you aren't getting a ClassNotFoundException
prior to the NoClassDefFoundError
, you're almost guaranteed that it's a static initialization problem.
I have seen similar errors quite frequently when the hosts file incorrectly defines the localhost address, and the static initialization block relies on InetAddress.getLocalHost()
. 127.0.0.1 should point to 'localhost' (and probably also localhost.localdomain). It should NOT point to the actual host name of the machine (although for some reason, many older RedHat Linux installers liked to set it incorrectly).
Add following to your maven dependency
<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>
I once ran into this situation and I had the dependencies in classpath. The solution was to include javax.mail and javax.activation libraries in the container's (eg. tomcat) lib folder. Using maven -set them to provided scope and it should work. You will have shared email libs in classpath for all projects.
Useful source: http://haveacafe.wordpress.com/2008/09/26/113/
When I had this problem, I had included the mail-api.jar
in my maven pom file. That's the API specification only. The fix is to replace this:
<!-- DO NOT USE - it's just the API, not an implementation -->
<groupId>javax.mail</groupId>
<artifactId>javax.mail-api</artifactId>
with the reference implementation of that api:
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
I know it has sun in the package name, but that's the latest version. I learned this from https://stackoverflow.com/a/28935760/1128668
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>
- 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
containsjavax.mail.Authenticator
but not the 'provider' classesjavax.mail
contains bothjavax.mail.Authenticator
and all thesun.com.mail
'provider` classes (SMTP, IMAP and POP3)smtp
(andimap
andpop3
) don't containjavax.mail.Authenticator
... just eachcom.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
withsmtp-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.
精彩评论