I have a spring boot application with javamail, i configure spring.properties but it seems to not take properties to send email.
#mail properties
spring.mail.host = smtp.gmail.com
spring.mail.port = 587
spring.mail.username = eeee#gmail.com
spring.mail.password = eeee
spring.mail.protocol = smtp
spring.mail.defaultEncoding=UTF-8
spring.mail.smtp.starttls.enable=false
spring.mail.smtp.starttls.required=false
spring.mail.smtp.auth=true
spring.mail.smtp.connectiontimeout=5000
spring.mail.smtp.timeout=5000
spring.mail.smtp.writetimeout=5000
here the java code to send email
#Service
public class MailSenderServiceImpl implements IMailSenderService{
#Autowired
JavaMailSender mailSender;
#Override
public void sendEmailStatusNotification(Shipment shipment) throws IOException, MessagingException{
final MimeMessage mimeMessage = this.mailSender.createMimeMessage();
final MimeMessageHelper message = new MimeMessageHelper(mimeMessage, "UTF-8");
message.setFrom(shipment.getSender().getSenderEmail());
message.setTo(new String[] {shipment.getRecipient().getRecipientEmail()});
message.setSubject("Shipment "+shipment.getTrackingNumber()+"status update");
message.setText("the shipment status is now :"+shipment.getStatus().getLabel());
this.mailSender.send(mimeMessage);
}
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
here we see this error
org.springframework.mail.MailSendException: Mail server connection failed; nested exception is com.sun.mail.util.MailConnectException: Couldn't connect to host, port: localhost, 25; timeout -1;
nested exception is:
java.net.ConnectException: Connection refused: connect. Failed messages: com.sun.mail.util.MailConnectException: Couldn't connect to host, port: localhost, 25; timeout -1;
nested exception is:
java.net.ConnectException: Connection refused: connect; message exceptions (1) are:
Failed message 1: com.sun.mail.util.MailConnectException: Couldn't connect to host, port: localhost, 25; timeout -1;
nested exception is:
java.net.ConnectException: Connection refused: connect
Any idea ?
By default spring.properties is not a properties source, try putting them in application.properties.
Related
I am using the below code:
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.userDnPatterns("uid={0},OU=b")
.groupSearchBase("OU=Service Account")
.contextSource()
.url("ldaps://AD.b.com:636/DC=b,DC=com")
.and()
.passwordCompare()
.passwordEncoder(new BCryptPasswordEncoder())
.passwordAttribute("userPassword");
}
I am getting errors after inserting username and password which are provided by Admin.
Error log:
2022-04-11 10:05:09.086 ERROR 1969 --- [nio-8083-exec-9] w.a.UsernamePasswordAuthenticationFilter : An internal error occurred while trying to authenticate the user.
org.springframework.security.authentication.InternalAuthenticationServiceException: Connection or outbound has closed; nested exception is javax.naming.CommunicationException: Connection or outbound has closed [Root exception is java.net.SocketException: Connection or outbound has closed]; remaining name 'uid=test,OU=b'
I use brand new spring boot project with next Maven dependency
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
Implementation of method
#Autowired
JavaMailSender emailSender;
#GetMapping("/send")
public String send() {
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom("some-name#domain.com");
message.setTo("toReceiver#gmail.com");
message.setSubject(null);
message.setText("Hello World");
emailSender.send(message);
return "success send email " + now();
}
application.yml
host: smtp.yandex.ru
username: some-name#domain.io
password: password
port: 465
And receive the next exception
2020-08-03 23:02:35.102 ERROR 21615 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.mail.MailSendException: Mail server connection failed; nested exception is javax.mail.MessagingException: Got bad greeting from SMTP host: smtp.yandex.com, port: 465, response: [EOF].
Failed messages: javax.mail.MessagingException: Got bad greeting from SMTP host: smtp.yandex.com, port: 465, response: [EOF]; message exceptions (1) are: Failed message 1: javax.mail.MessagingException: Got bad greeting from SMTP host: smtp.yandex.com, port: 465, response: [EOF]] with root cause
But the same code works perfectly with Mailtrap service
According to this link I used not secure 25 port
After which I received the next exception
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.mail.MailSendException: Mail server connection failed; nested exception is com.sun.mail.util.MailConnectException: Couldn't connect to host, port: smtp.yandex.ru, 25; timeout -1;
587 port =
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.mail.MailAuthenticationException: Authentication failed; nested exception is javax.mail.AuthenticationFailedException: [EOF];
I guess a problem with SSL
Similar issue
With port: 465 (SMTP Protocol), you can try enable ssl via properties:
"mail.smtp.ssl.enable": true
mail.smtp.ssl.enable: If set to true, use SSL to connect and use the SSL port by default. Defaults to false for the "smtp" protocol and true for the "smtps" protocol.
Using spring boot, add properties to application.yml:
mail:
...
properties:
"mail.smtp.ssl.enable": true
References:
Outgoing mail
mail server address — smtp.yandex.com
connection security — SSL
port — 465
The SMTP protocol provider supports the following properties:
https://javaee.github.io/javamail/docs/api/com/sun/mail/smtp/package-summary.html
This properties help me
spring:
boot:
admin:
mail:
to: ${spring.mail.username}, test#yandex.ru
from: ${spring.mail.username}
mail:
host: smtp.yandex.ru
username: test#yandex.ru
password: password
port: 587
protocol: smtp
properties:
"mail.transport.protocol": smtp
"mail.smtp.auth": true
"mail.smtp.starttls.enable": true
I tried to test my Gmail smtp in my Spring-Application and followed this Tutorial. I have implemented it as specified in the tutorial, but my EmailService throws a MailSendException:
org.springframework.mail.MailSendException: Mail server connection failed; nested exception is com.sun.mail.util.MailConnectException: Couldn't connect to host, port: localhost, 2525; timeout 5000;
nested exception is:
java.net.ConnectException: Connection refused: connect. Failed messages: com.sun.mail.util.MailConnectException: Couldn't connect to host, port: localhost, 2525; timeout 5000;
nested exception is:
java.net.ConnectException: Connection refused: connect
; message exception details (1) are:
Failed message 1:
com.sun.mail.util.MailConnectException: Couldn't connect to host, port: localhost, 2525; timeout 5000;
nested exception is:
java.net.ConnectException: Connection refused: connect
at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2210)
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:722)
at javax.mail.Service.connect(Service.java:342)
Has anyone a tip how to solve this? (Never tested something like SMTP/Email and therefore just followed the tutorial above.
EDIT: I can send emails without any problem manually, but I need to test it.
my application.yml:
spring.mail.host: smtp.gmail.com
spring.mail.port: 587
spring.mail.properties.mail.smtp.starttls.enable: true
spring.mail.username: ************#gmail.com
spring.mail.password: ***************
spring.mail.properties.mail.smtp.starttls.required: true
spring.mail.properties.mail.smtp.auth: true
spring.mail.properties.mail.smtp.connectiontimeout: 5000
spring.mail.properties.mail.smtp.timeout: 5000
spring.mail.properties.mail.smtp.writetimeout: 5000
From the log you can see, that Spring is trying to connect to port 2525 but can't make connection. That means that there's no running mail server on this port, during test execution - which should be provided by JUnit Rule implementation (If you're using JUnit5 use Extensions)
Make sure that your test configuration is properly setup. That means, check whether your test code, e.g.
#Rule
public SmtpServerRule smtpServerRule = new SmtpServerRule(2525);
matches
src/test/resources/application.yml
spring:
mail:
default-encoding: UTF-8
host: localhost
jndi-name:
username: username
password: secret
port: 2525
properties:
mail:
debug: false
smtp:
debug: false
auth: true
starttls: true
protocol: smtp
test-connection: false
I would also recommend to update the code from the Tutorial and add test user - as it could be used with secured protocols.
public class SmtpServerRule extends ExternalResource {
// omitted for brevity
#Override
protected void before() throws Throwable {
super.before();
smtpServer = new GreenMail(new ServerSetup(port, null, "smtp"));
smtpServer.addUser("username", "secret");
smtpServer.start();
}
// omitted for brevity
}
Also, refer to the official GreenMail documentation for more specific setup.
I'm trying to send an email from my Spring boot application. Here are my configuration properties.
spring:
application:
name: spring-base-template
profiles:
active: ${env:local}
mail:
default-encoding: UTF-8
host: company.host.name
username: myusername#domain.com
password: mypassword
port: 587
properties:
mail:
smtp:
auth: true
starttls:
enable: true
socketFactory:
port: 465
class: javax.net.ssl.SSLSocketFactory
fallback: false
protocol: smtp
test-connection: false
My sample code look like this
try {
SimpleMailMessage mail = new SimpleMailMessage();
mail.setTo("myusername#domain.com");
mail.setFrom("myusername#domain.com");
mail.setSubject("Registration Confirmation");
mail.setText("You are registered Successfully! Thank you for being with us!");
javaMailSender.send(mail);
} catch(Exception e) {
e.printStackTrace();
}
When I try to send the email, following is the exception
org.springframework.mail.MailSendException: Mail server connection failed; nested exception is javax.mail.MessagingException: Could not connect to SMTP host: company.host.name, port: 587;
nested exception is:
java.net.SocketException: Connection reset. Failed messages: javax.mail.MessagingException: Could not connect to SMTP host: company.host.name, port: 587;
nested exception is:
java.net.SocketException: Connection reset; message exception details (1)
are:
Failed message 1:
javax.mail.MessagingException: Could not connect to SMTP host:
company.host.name, port: 587;
Any ideas would be greatly appreciated.
I am using Spring AMQP RabbitHandler and have written the following code:
#RabbitListener(queues = "#{testQueue.name}")
public class Tut4Receiver {
#RabbitHandler
public void receiveMessage(String message){
System.out.println("Message received "+message);
}
}
The Queue is defined like:-
#Bean
public Queue testQueue() {
return new AnonymousQueue();
}
I am using separate code to initialize the Connection Factory.
My question is if RabbitMQ is down for some time, it keeps on retrying to create a consumer but only if it receives a ConnectionRefused error. But suppose the user does not exist in RabbitMQ and there is a gap in which a new user will be created, then it receives a fatal error from RabbitMQ and it never retries due to which the result is auto delete queue would be created on RabbitMQ without any consumers.
Stack Trace:
SimpleMessageListenerContainer] [SimpleAsyncTaskExecutor-11] [|] [|||] Consumer received fatal exception on startup
org.springframework.amqp.rabbit.listener.exception.FatalListenerStartupException: Authentication failure
at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.start(BlockingQueueConsumer.java:476)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1280)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.springframework.amqp.AmqpAuthenticationException: com.rabbitmq.client.AuthenticationFailureException: ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN. For details see the broker logfile.
at org.springframework.amqp.rabbit.support.RabbitExceptionTranslator.convertRabbitAccessException(RabbitExceptionTranslator.java:65)
at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:309)
at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.createConnection(CachingConnectionFactory.java:547)
at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils$1.createConnection(ConnectionFactoryUtils.java:90)
at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils.doGetTransactionalResourceHolder(ConnectionFactoryUtils.java:140)
at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils.getTransactionalResourceHolder(ConnectionFactoryUtils.java:76)
at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.start(BlockingQueueConsumer.java:472)
... 2 common frames omitted
Caused by: com.rabbitmq.client.AuthenticationFailureException: ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN. For details see the broker logfile.
at com.rabbitmq.client.impl.AMQConnection.start(AMQConnection.java:339)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:813)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:767)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:887)
at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:300)
SimpleMessageListenerContainer] [SimpleAsyncTaskExecutor-11] [|] [|||] Stopping container from aborted consumer
[|] [|||] Waiting for workers to finish.
[|] [|||] Successfully waited for workers to finish.
Any way to retry even on fatal exceptions like when the user does not exist?
Authentication failures are considered fatal by default and not retried.
You can override this behavior by setting a property on the listener container (possibleAuthenticationFailureFatal). The property is not available as a boot property so you have to override boot's container factory...
#Bean(name = "rabbitListenerContainerFactory")
public SimpleRabbitListenerContainerFactory simpleRabbitListenerContainerFactory(
SimpleRabbitListenerContainerFactoryConfigurer configurer, ConnectionFactory connectionFactory) {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
configurer.configure(factory, connectionFactory);
factory.setContainerConfigurer(smlc -> smlc.setPossibleAuthenticationFailureFatal(false));
return factory;
}