java.lang.NoClassDefFoundError:javax / mail / Authenticator,怎么回事?

时间:2009-10-27 10:45:56

标签: java javamail

发送至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);
        }
    }
}

我的controller.java

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

当我运行我的Web应用程序时,我收到此错误消息:

  

输入例外报告

     

消息

     

描述服务器遇到了   内部错误()阻止了它   完成此请求。

     

例外   javax.servlet.ServletException:   Servlet执行引发异常

     

根本原因   java.lang.NoClassDefFoundError:   使用javax /邮件/认证者     controller.RegisterTenantController.doPost(RegisterTenantController.java:108)     javax.servlet.http.HttpServlet.service(HttpServlet.java:709)     javax.servlet.http.HttpServlet.service(HttpServlet.java:802)

我现在要做什么?有人可以帮助我使这个Web应用程序成功吗?

7 个答案:

答案 0 :(得分:46)

您需要在WEB-INF / lib目录或webapp(或服务器的lib目录)中添加两个jar:

答案 1 :(得分:26)

虽然这可能是由于类路径中缺少jar文件,但可能不是。

在这种情况下,保持两到三个不同的例外是很重要的:

  1. java.lang.ClassNotFoundException 此异常表示在类路径中找不到该类。这表明我们正在尝试加载类定义,并且该类在类路径中不存在。

  2. java.lang.NoClassDefFoundError 此异常表示JVM在其内部类定义数据结构中查找了类的定义但未找到它。这与说它无法从类路径加载不同。通常这表明我们之前尝试从类路径加载一个类,但由于某种原因它失败了 - 现在我们再次尝试,但我们甚至都不会尝试加载它,因为我们之前没有加载它。较早的故障可能是ClassNotFoundExceptionExceptionInInitializerError(表示静态初始化块中的故障)或任何其他问题。关键是,NoClassDefFoundError不一定是类路径问题。

  3. 我会查看javax.mail.Authenticator的源代码,看看它在静态初始化程序中的作用。 (查看静态变量初始化和静态块,如果有的话。)如果在ClassNotFoundException之前没有得到NoClassDefFoundError,则几乎可以保证它是静态初始化问题。

    当hosts文件错误地定义localhost地址时,我经常看到类似的错误,静态初始化块依赖于InetAddress.getLocalHost()。 127.0.0.1应指向'localhost'(可能还有localhost.localdomain)。它不应该指向机器的实际主机名(尽管由于某种原因,许多较旧的RedHat Linux安装程序喜欢将其设置错误)。

答案 2 :(得分:20)

在maven依赖项中添加以下内容

    <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>

答案 3 :(得分:8)

我曾经在这种情况下运行,并且我在classpath中有依赖项。解决方案是在容器(例如,tomcat)lib文件夹中包含javax.mail和javax.activation库。使用maven,您可以将它们设置为提供范围,它应该可以正常工作。您将在类路径中为所有项目共享电子邮件库。

有用的来源:http://haveacafe.wordpress.com/2008/09/26/113/

答案 4 :(得分:4)

当我遇到此问题时,我已将mail-api.jar包含在我的maven pom文件中。这是API规范。解决方法是替换它:

<!-- DO NOT USE - it's just the API, not an implementation -->
<groupId>javax.mail</groupId>
<artifactId>javax.mail-api</artifactId>

使用该api的参考实现:

<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>

我知道包名中有sun,但这是最新版本。我是从https://stackoverflow.com/a/28935760/1128668

那里学到的

答案 5 :(得分:1)

即使我遇到了类似的错误。请尝试以下2个步骤(此处已经建议了第一个步骤)-  1.将依赖项添加到您的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. 如果这样不起作用,请手动将jar文件放在您的.m2\repository\javax\<folder>\<version>\目录中。

答案 6 :(得分:0)

在 Servlet 环境下与 com.sun.mail 组、版本 1.6.2 一起运行时,请注意工件:

  • mailapi 包含 javax.mail.Authenticator 'provider' 类
  • javax.mail 包含 javax.mail.Authenticator 和所有 sun.com.mail 'provider` 类(SMTP、IMAP 和 POP3)
  • smtp(以及 imappop3)不包含 javax.mail.Authenticator ... 只是每个 com.sun.mail.* 提供程序自己的

现在,如果不想要 IMAP 和 POP3(因为这些是用于获取电子邮件的客户端协议)而只是用于发送的 SMTP,那么您需要 {{1} } 和 javamail-1.6.2.jar

现在在 Servlet 环境中,意识到您可以选择“使用容器提供的内容”或“提供我自己的内容”。因此,您要么将这两个 JAR 文件都放在容器的“公共”运行时中,要么将这两个 JAR 文件都提供在您自己的 smtp-1.6.2.jar 目录中……它会起作用。

不能做的是将 WEB-INF\lib 放入您的 javamail-1.6.2.jar 并将 WEB-INF\lib 放入您的 smtp-1.6.2.jar。为什么不?因为,class-loader hierarchy。 SMTP 提供程序需要 $TOMCAT_HOME/lib 类。但是(与,重要的是 javax.mail 不同),java.sql 类不是由系统类加载器“进一步”加载的,甚至不是“在同一级别”加载的……它们是由一个类加载器加载的特定于“其中一个分支”上的网络应用程序!因此,当 SMTP 提供程序想要一个 javax.mail 类时,它找不到一个,因为“每个人都通用”的类加载器没有业务查看单个 Web 应用程序以加载所需的类!

所以要么:

  • 使用 javax.mail 而没有其他 JavaMail JAR;或
  • 同时使用 javax.mail-1.6.2.jarjavamail-1.6.2.jar

但始终将这些all放在服务器的公共库中或all在您的网络应用的公共库中。

你采取哪种立场取决于你。各有利弊。您在 smtp-1.6.2.jar 中提供的类总是会“获胜”,以防您需要击败服务器加载为“通用”的旧版本。但这可能不是一个好主意,总是。