![](/img/trans.png)
[英]java.lang.NoClassDefFoundError: javax/mail/Authenticator
[英]java.lang.NoClassDefFoundError: javax/mail/Authenticator, whats wrong?
发送至 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 执行引发异常
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)
我现在要做什么? 有人可以帮我成功申请 web 吗?
你需要在WEB-INF/lib目录或者你的webapp(或者服务器的lib目录)中添加两个jar包:
虽然这可能是由于您的类路径中缺少 jar 文件,但也可能不是。
在这种情况下,在我们的脑海中保留两个或三个不同的异常是很重要的:
java.lang.ClassNotFoundException
此异常表示在类路径中找不到该类。 这表明我们正在尝试加载类定义,并且类路径上不存在该类。
java.lang.NoClassDefFoundError
此异常表示JVM在其内部类定义数据结构中查找类的定义,但没有找到。 这与说它无法从类路径加载不同。 通常这表明我们之前尝试从类路径加载一个类,但由于某种原因它失败了 - 现在我们再次尝试,但我们甚至不会尝试加载它,因为我们之前加载它失败了。 较早的失败可能是ClassNotFoundException
或ExceptionInInitializerError
(指示静态初始化块中的失败)或任何数量的其他问题。 关键是, NoClassDefFoundError
不一定是类路径问题。
我会查看javax.mail.Authenticator
的源代码,看看它在静态初始化程序中做了什么。 (查看静态变量初始化和静态块,如果有的话。)如果您在NoClassDefFoundError
之前没有收到ClassNotFoundException
,您几乎可以肯定这是一个静态初始化问题。
当主机文件错误地定义本地主机地址时,我经常看到类似的错误,并且静态初始化块依赖于InetAddress.getLocalHost()
。 127.0.0.1 应该指向'localhost'(也可能是localhost.localdomain)。 它不应指向机器的实际主机名(尽管出于某种原因,许多较旧的 RedHat Linux 安装程序喜欢错误地设置它)。
将以下内容添加到您的 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>
我曾经遇到过这种情况,并且我在类路径中有依赖项。 解决方案是在容器(例如 tomcat)的 lib 文件夹中包含 javax.mail 和 javax.activation 库。 使用 maven -将它们设置为提供的范围,它应该可以工作。 您将在所有项目的类路径中共享电子邮件库。
当我遇到这个问题时,我已经在我的 maven pom 文件中包含了mail-api.jar
。 那只是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了解到这一点
甚至我也面临着类似的错误。 尝试以下 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>
jar
文件放在.m2\\repository\\javax\\<folder>\\<version>\\
目录中。在 Servlet 环境下使用com.sun.mail
组,版本1.6.2
运行时,注意工件:
mailapi
包含javax.mail.Authenticator
但不包含“提供者”类javax.mail
包含javax.mail.Authenticator
和所有sun.com.mail
'provider` 类(SMTP、IMAP 和 POP3)smtp
(以及imap
和pop3
)不包含javax.mail.Authenticator
......只是每个com.sun.mail.*
提供者自己现在,如果您不想要 IMAP 和 POP3(因为这些是用于获取电子邮件的客户端协议)而只需要SMTP 进行发送,那么您需要javamail-1.6.2.jar
和smtp-1.6.2.jar
。
现在在 Servlet 环境中,意识到您可以选择“使用容器提供的内容”或“提供我自己的内容”。 因此,您要么将这两个 JAR 文件都放在容器的“公共”运行时中,要么将这两个 JAR 文件都提供在您自己的WEB-INF\\lib
目录中……它会起作用。
您不能做的是将javamail-1.6.2.jar
放入您的WEB-INF\\lib
并将smtp-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
中提供的类总是会“获胜”,以防您需要击败服务器加载为“通用”的旧版本。 但这可能不是一个好主意,总是。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.