34

发送到 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/mail/Authenticator controller.RegisterTenantController.doPost(RegisterTenantController.java:108) javax.servlet.http.HttpServlet.service(HttpServlet.java:709) javax.servlet.http.HttpServlet.service (HttpServlet.java:802)

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

4

7 回答 7

51

你需要添加两个jar到WEB-INF/lib目录或者你的webapp(或者服务器的lib目录):

于 2009-10-27T11:09:29.530 回答
27

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

在这种情况下,重要的是要牢记两三个不同的例外情况:

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

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

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

当 hosts 文件错误地定义了 localhost 地址并且静态初始化块依赖于InetAddress.getLocalHost(). 127.0.0.1 应该指向“localhost”(也可能是 localhost.localdomain)。它不应该指向机器的实际主机名(尽管出于某种原因,许多旧的 RedHat Linux 安装程序喜欢错误地设置它)。

于 2009-10-27T16:08:43.110 回答
22

将以下内容添加到您的 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>
于 2012-08-13T23:29:53.433 回答
8

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

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

于 2011-09-13T23:29:31.143 回答
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了解到这一点

于 2016-01-08T21:49:08.990 回答
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>\目录中。
于 2019-08-22T00:57:09.227 回答
0

com.sun.mail在 Servlet 环境下使用group 和 version运行时1.6.2,请注意工件:

  • mailapi包含javax.mail.Authenticator包含“提供者”类
  • javax.mail包含javax.mail.Authenticator 所有sun.com.mail提供者”类(SMTP、IMAP 和 POP3)
  • smtp(and imapand pop3) 不包含javax.mail.Authenticator...只是每个com.sun.mail.*提供者自己

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

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

不能做的是放入javamail-1.6.2.jar你的WEB-INF\libsmtp-1.6.2.jar你的$TOMCAT_HOME/lib. 为什么不?因为,类加载器层次结构。SMTP 提供程序需要这些javax.mail类。但是(与重要的不同java.sql),这些javax.mail类不是由系统类加载器“进一步”甚至“在同一级别”加载的......它们是由一个特定于您的 web 应用程序的类加载器在“其中一个分支”上加载的下'!因此,当 SMTP 提供者想要一个javax.mail类时,它找不到一个,因为“每个人都通用”的类加载器没有业务查看单个 web 应用程序来加载所需的类!

所以要么:

  • 使用javax.mail-1.6.2.jar但不使用其他 JavaMail JAR;或者
  • 同时javamail-1.6.2.jar使用smtp-1.6.2.jar

但总是把这些放在服务器的公共库中,或者 全部放在你的网络应用程序的公共库中。

你采取哪种立场取决于你。每种方式都有优点和缺点。您提供的类WEB-INF\libs总是会“获胜”,以防您需要击败服务器加载为“普通”的旧版本。但这可能不是一个好主意,总是。

于 2021-06-07T06:26:18.557 回答