java.lang.NoClassDefFoundError: javax/mail/Authenticator, что не так?
Отправить на 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);
Когда я запускаю свое веб-приложение, я получаю это сообщение об ошибке:
Тип отчета об исключении
сообщение
description Сервер обнаружил внутреннюю ошибку (), которая не позволила ему выполнить этот запрос.
исключение javax.servlet.ServletException: выполнение сервлета вызвало исключение
первопричина (HttpServlet.java:802)
Что мне теперь делать? Может ли кто-нибудь помочь мне добиться успеха этого веб-приложения?
7 ответов
Вам нужно добавить два jar-файла в каталог WEB-INF/lib или ваше веб-приложение (или каталог lib сервера):
- mail.jar - содержит фактическую реализацию smtp
- Activation.jar - требуется mail.jar
Хотя возможно, что это связано с отсутствием файла JAR в вашем пути к классам, это не так.
В этом случае важно сохранить два или три разных исключения в нашей голове:
java.lang.ClassNotFoundException
Это исключение указывает, что класс не был найден в пути к классам. Это указывает на то, что мы пытались загрузить определение класса, а класс не существовал в пути к классам.java.lang.NoClassDefFoundError
Это исключение указывает на то, что JVM искала в своей внутренней структуре данных определения класса определение класса и не нашла его. Это отличается от того, что он не может быть загружен из пути к классам. Обычно это означает, что мы ранее пытались загрузить класс из пути к классам, но по какой-то причине это не удалось - теперь мы пытаемся снова, но даже не собираемся пытаться загрузить его, потому что мы не смогли загрузить его ранее. Предыдущий сбой может бытьClassNotFoundException
илиExceptionInInitializerError
(указывает на сбой в блоке статической инициализации) или на любое количество других проблем. Дело в том,NoClassDefFoundError
это не обязательно проблема classpath.
Я бы посмотрел на источник javax.mail.Authenticator
и посмотрите, что он делает в своем статическом инициализаторе. (Посмотрите на инициализацию статической переменной и статический блок, если таковой имеется.) Если вы не получаете ClassNotFoundException
до NoClassDefFoundError
Вы почти гарантированы, что это статическая проблема инициализации.
Я часто сталкивался с подобными ошибками, когда файл hosts неправильно определяет адрес локального хоста, а блок статической инициализации полагается на 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>
Я однажды бегал в этой ситуации, и у меня были зависимости в classpath. Решением было включить библиотеки javax.mail и javax.activation в папку lib контейнера (например, tomcat). С Maven вы установите их в предусмотренном объеме, и это должно работать. У вас будут общие почтовые библиотеки в classpath для всех проектов.
Полезный источник: http://haveacafe.wordpress.com/2008/09/26/113/
Когда у меня возникла эта проблема, я включил 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>
Я знаю, что в названии пакета есть солнце, но это последняя версия. Я узнал об этом из /questions/12947027/javalangnoclassdeffounderror-comsunmailutilmaillogger-dlya-testa-junit-dlya-pochtyi-java/12947039#12947039
Даже я столкнулся с подобной ошибкой. Попробуйте выполнить следующие 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>\
каталог.
При беге с
com.sun.mail
группа, версия
1.6.2
в среде сервлета обратите внимание на этот артефакт:
-
mailapi
содержит, но не классы "провайдера" - содержит как и все
sun.com.mail
классы провайдера (SMTP, IMAP и POP3) -
smtp
(а такжеimap
а такжеpop3
) не содержатjavax.mail.Authenticator
... только каждыйcom.sun.mail.*
провайдер самостоятельно
Теперь, если кому-то нужны не IMAP и POP3 (поскольку это клиентские протоколы для получения электронной почты), а только SMTP для отправки, вы хотите и.
Теперь, в среде сервлетов, поймите, что вы можете выбрать «использовать то, что предоставляет контейнер», либо «предоставить мое собственное». Таким образом, вы либо помещаете оба этих файла JAR в «общую» среду выполнения контейнера, либо помещаете оба этих файла JAR в свой собственный каталог ... и он будет работать.
То, что вы не можете сделать, положите в свой
WEB-INF\lib
и в ваш
$TOMCAT_HOME/lib
. Почему нет? Потому что иерархия загрузчиков классов . Провайдеру SMTP нужны классы. Но (в отличие, что существенно,
java.sql
), классы не загружаются системным загрузчиком классов «выше» или даже «на том же уровне» ... они загружаются загрузчиком классов, специфичным для ВАШЕГО веб-приложения, на «одной из ветвей вниз»! Поэтому, когда провайдер SMTP хочет
javax.mail
class, он не находит его, потому что «общий для всех» загрузчик классов не имеет никакого отношения к изучению отдельных веб-приложений для загрузки требуемых классов!
Так что либо:
- использовать
javax.mail-1.6.2.jar
и никаких других JAR JavaMail; ИЛИ ЖЕ - использовать оба
javamail-1.6.2.jar
с участиемsmtp-1.6.2.jar
но всегда помещайте все это в общие библиотеки сервера ИЛИ все в общие библиотеки вашего веб-приложения.
Какую позицию вы займете, зависит от вас. У каждого есть свои плюсы и минусы. Занятия, которые вы проводите в
WEB-INF\libs
всегда будут «побеждать», если вам нужно победить более старую версию, загруженную Сервером как «обычную». Но это может быть не всегда хорошей идеей.