I'm deploying a Grails application to Amazon Web Services Elastic Beanstalk and leveraging RDS. I'm using Grails, Spring-Security (RDS tables). The application appears to work fine (login and data in RDS being pulled back). However, from time to time the first time I login I get a database connection error. The second time it (immediately) works fine. The only thing I'm doing slightly different is trying to use Java system properties for the connection string, username and password to externalize the connection properties:
production {
dataSource {
url = System.getProperty("JDBC_CONNECTION_STRING")
driverClassName = "com.mysql.jdbc.Driver"
dbCreate = "validate"
dialect = org.hibernate.dialect.MySQL5InnoDBDialect
username = System.getProperty("PARAM1")
password = System.getProperty("PARAM2")
}
}
Stack trace:
Caused by: org.hibernate.TransactionException: JDBC begin failed:
at org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:96)
at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1353)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:555)
... 80 more
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 41,541,715 milliseconds ago. The last packet sent successfully to the server was 41,541,716 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:532)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:407)
at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1116)
at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3358)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1970)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2150)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2620)
at com.mysql.jdbc.ConnectionImpl.setAutoCommit(ConnectionImpl.java:5022)
at org.apache.commons.dbcp.DelegatingConnection.setAutoCommit(DelegatingConnection.java:371)
at org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.setAutoCommit(PoolingDataSource.java:328)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy$TransactionAwareInvocationHandler.invoke(TransactionAwareDataSourceProxy.java:239)
at $Proxy11.setAutoCommit(Unknown Source)
at org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:91)
... 82 more
Caused by: java.net.SocketException: Connection timed out
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109)
at java.net.SocketOutputStream.write(SocketOutputStream.java:153)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3339)
... 95 more
What I've tried:
I appended ?autoReconnect=true to the JDBC_CONNECTION_STRING
I've added this to conf/spring/resources.groovy:
beans = {
dataSource(BasicDataSource) {
minEvictableIdleTimeMillis=1800000
timeBetweenEvictionRunsMillis=1800000
numTestsPerEvictionRun=3
testOnBorrow=true
testWhileIdle=true
testOnReturn=true
validationQuery="SELECT 1"
}
}
However is that the right place or can/should it be added to the datasource.groovy file per env configuration? Also, the above only seems to be valid if I add the URL/driverClassName, username, and password which now means that is in multiple places. I haven't confirmed if it solves the problem, but is there a way to have all this in one place per env?
This should work:
production {
dataSource {
url = System.getProperty("JDBC_CONNECTION_STRING")
driverClassName = "com.mysql.jdbc.Driver"
dbCreate = "validate"
dialect = org.hibernate.dialect.MySQL5InnoDBDialect
username = System.getProperty("PARAM1")
password = System.getProperty("PARAM2")
//configure DBCP
properties {
minEvictableIdleTimeMillis=1800000
timeBetweenEvictionRunsMillis=1800000
numTestsPerEvictionRun=3
testOnBorrow=true
testWhileIdle=true
testOnReturn=true
validationQuery="SELECT 1"
}
}
}
Related
When use an AWS ELB (Elastic Load Balancer) with HTTPS listener that forward the request to the presto cluster (0.193) behind that runs on HTTP, Java client that uses presto-jdbc (0.213) fails to execute select query due to "plain HTTP request was sent to HTTPS port" error.
Exception in thread "main" java.sql.SQLException: Error executing query
at com.facebook.presto.jdbc.PrestoStatement.internalExecute(PrestoStatement.java:274)
at com.facebook.presto.jdbc.PrestoStatement.execute(PrestoStatement.java:227)
at com.facebook.presto.jdbc.PrestoStatement.executeQuery(PrestoStatement.java:76)
at com.DpTool.executeJdbcQuerySsl(DpTool.java:332)
at com.DpTool.prestoJdbcSsl(DpTool.java:315)
at com.DpTool.main(DpTool.java:520)
Caused by: java.lang.RuntimeException: Error fetching next at http://cluster-elb.mydomain:8443/v1/statement/20181120_215602_00038_57ryf/1 returned an invalid response: JsonResponse{statusCode=400, statusMessage=Bad Request, headers={connection=[close], content-length=[236], content-type=[text/html], date=[Tue, 20 Nov 2018 21:56:02 GMT], server=[awselb/2.0]}, hasValue=false} [Error: <html>
<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<center>The plain HTTP request was sent to HTTPS port</center>
</body>
</html>
]
at com.facebook.presto.jdbc.internal.client.StatementClientV1.requestFailedException(StatementClientV1.java:436)
at com.facebook.presto.jdbc.internal.client.StatementClientV1.advance(StatementClientV1.java:383)
at com.facebook.presto.jdbc.PrestoResultSet.getColumns(PrestoResultSet.java:1742)
at com.facebook.presto.jdbc.PrestoResultSet.<init>(PrestoResultSet.java:119)
at com.facebook.presto.jdbc.PrestoStatement.internalExecute(PrestoStatement.java:249)
... 5 more
It appears that StatementClientV1.advance code try to visit "http://cluster-elb.mydomain:8443/..." which is the ELB address except it should be "https" instead of "http" prefix. The same client code works fine when execute query directly to another HTTPS presto cluster (no ELB). Here is the client Java code. url is "cluster-elb.mydomain:8443"
Properties properties = new Properties();
properties.setProperty("SSL", "true");
Connection conn = DriverManager.getConnection(url, properties);
Statement stmt = conn.createStatement();
String query = "select cluster, query_text from mytable where ds='2018-10-20' limit 10";
ResultSet rs = stmt.executeQuery(query);
Why the presto-jdbc client code is confused and how to make the query work?
This should work in newer versions of Presto. Try it with 0.213.
The problem is due to https://github.com/prestodb/presto/issues/8232 where the nextUri field in QueryStatusInfo is incorrectly set as http instead of https by presto server (when client talk to presto through elb or proxy).
I am trying to implement spring websocket in my project, In which I have a scheduler which keeps on running for every 20 seconds and emit some data to connected sockets. Also, the default SockJS heartbeat is configured to run for every 10 seconds to keep the connection alive
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint(ApplicationConstants.STOMP_MESSAGE_GROUP_PREFIX,
ApplicationConstants.STOMP_MESSAGE_ONETOONE_PREFIX).setHandshakeHandler(getHandler())
.addInterceptors(new OneToOneStompMsgChannelInterceptor()).setAllowedOrigins("*")
.withSockJS().setHeartbeatTime(5000);
}
the problem is ,after running for sometime I am getting an error like below
DEBUG [MessageBrokerSockJS-3] o.s.w.s.s.t.s.WebSocketServerSockJsSession [AbstractSockJsSession.java:363] Terminating connection after failure to send message to client java.lang.IllegalStateException: The remote endpoint was in state [TEXT_PARTIAL_WRITING] which is an invalid state for called method
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase$StateMachine.checkState(WsRemoteEndpointImplBase.java:1177)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase$StateMachine.textPartialStart(WsRemoteEndpointImplBase.java:1135)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendPartialString(WsRemoteEndpointImplBase.java:226)
at org.apache.tomcat.websocket.WsRemoteEndpointBasic.sendText(WsRemoteEndpointBasic.java:49)
at org.springframework.web.socket.adapter.standard.StandardWebSocketSession.sendTextMessage(StandardWebSocketSession.java:197)
at org.springframework.web.socket.adapter.AbstractWebSocketSession.sendMessage(AbstractWebSocketSession.java:105)
at org.springframework.web.socket.sockjs.transport.session.WebSocketServerSockJsSession.writeFrameInternal(WebSocketServerSockJsSession.java:222)
at org.springframework.web.socket.sockjs.transport.session.AbstractSockJsSession.writeFrame(AbstractSockJsSession.java:325)
at org.springframework.web.socket.sockjs.transport.session.WebSocketServerSockJsSession.sendMessageInternal(WebSocketServerSockJsSession.java:212)
at org.springframework.web.socket.sockjs.transport.session.AbstractSockJsSession.sendMessage(AbstractSockJsSession.java:161)
at org.springframework.web.socket.handler.ConcurrentWebSocketSessionDecorator.tryFlushMessageBuffer(ConcurrentWebSocketSessionDecorator.java:126)
at org.springframework.web.socket.handler.ConcurrentWebSocketSessionDecorator.sendMessage(ConcurrentWebSocketSessionDecorator.java:99)
at com.visionit.statchat.stomp.CustomStompSubProtocolHandler.handleMessageFromClient(CustomStompSubProtocolHandler.java:31)
at org.springframework.web.socket.messaging.SubProtocolWebSocketHandler.handleMessage(SubProtocolWebSocketHandler.java:313)
at org.springframework.web.socket.handler.WebSocketHandlerDecorator.handleMessage(WebSocketHandlerDecorator.java:75)
at com.visionit.statchat.stomp.WebSocketSessionCapturingHandlerDecorator.sendToAll(WebSocketSessionCapturingHandlerDecorator.java:201)
at com.visionit.statchat.service.impl.RedisMessageListener.pingClients(RedisMessageListener.java:89)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:65)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
it looks like both are trying to write data at same time.
is there any way to customize the SockJS heartbeat handler and let it use the custom handler which scheduler is using ?
This has been reported as bug in spring websocket framework .Here is the link https://jira.spring.io/browse/SPR-14564
I am trying to configure zoho mail service in grails mail-plugin. Here is my configuration so far,
grails {
mail {
host = "smtp.zoho.com"
port = 465
username = "email#valid.com"
password = "some-valid-password"
props = ["mail.smtp.auth":"true",
"mail.smtp.starttls.enable":"true",
"mail.smtp.socketFactory.port":"465",
"mail.smtp.socketFactory.class":"javax.net.ssl.SSLSocketFactory",
"mail.smtp.socketFactory.fallback":"false"]
}
}
Here is my service method. The above config works great if I put gmail smtp configuration, so I think there is no problem with service method at all. Also email#valid.com is a registered email in Zoho and I can send email using zoho dashboard.
def sendImageProcessedNotification(User user, imageLink){
try{
if(user){
def receiver = user.email
mailService.sendMail {
async true
to receiver
subject "Subject"
html "Html body"
}
}
}catch(e){
log.error(e)
}
}
And here is the stacktrace,
2015-07-19 08:17:37,782 [pool-12-thread-1] ERROR mail.MailMessageBuilder - Failed to send email
org.springframework.mail.MailSendException: Failed to close server connection after message failures; nested exception is javax.mail.MessagingException: Can't send command to SMTP host;
nested exception is:
java.net.SocketException: Connection closed by remote host. Failed messages: com.sun.mail.smtp.SMTPSendFailedException: 553 Relaying disallowed as
; message exception details (1) are:
Failed message 1:
com.sun.mail.smtp.SMTPSendFailedException: 553 Relaying disallowed as
at com.sun.mail.smtp.SMTPTransport.issueSendCommand(SMTPTransport.java:2133)
at com.sun.mail.smtp.SMTPTransport.finishData(SMTPTransport.java:1912)
at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1135)
at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:433)
at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:345)
at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:340)
at org.springframework.mail.javamail.JavaMailSender$send$0.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:110)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:122)
at grails.plugin.mail.MailMessageBuilder$_sendMessage_closure1.doCall(MailMessageBuilder.groovy:112)
at grails.plugin.mail.MailMessageBuilder$_sendMessage_closure1.doCall(MailMessageBuilder.groovy)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:324)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1207)
at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:1121)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1016)
at groovy.lang.Closure.call(Closure.java:423)
at groovy.lang.Closure.call(Closure.java:417)
at groovy.lang.Closure.run(Closure.java:504)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
You just have to mention"setFrom()" properties where ever you have added the email logic.
Example: I've used JavaMailSender and using MimeMessage to send an email so in that case, I will have to mention "helper.setFrom()".
P.S: I've tried so many ways and after that I've solved it with this.
Remove this line "mail.smtp.starttls.enable":"true", add this line "mail.smtp.startssl.enable":true
I am new to gcm and I tried to connect to Cloud Connection Server(XMPP) of GCM using Smack API. It was alright at the start,
My code:
uid = "123456789";
apiKey = "A**************B";
XMPPTCPConnectionConfiguration.Builder config;
config.setSocketFactory(SSLSocketFactory.getDefault());
config = XMPPTCPConnectionConfiguration.builder();
config.setUsernameAndPassword(uid,apiKey);
config.setServiceName("gcm.googleapis.com");
config.setHost("gcm.googleapis.com");
config.setPort(5235);
config.setDebuggerEnabled(true);
mConnection = new XMPPTCPConnection(config.build());
mConnection.setPacketReplyTimeout(10000);
try {
mConnection.connect();
mConnection.login();
}
catch (SmackException | IOException | XMPPException e) {
System.out.println("Exception at SmackCcsClient.init()");
e.printStackTrace();
}
But I couldnt get past the initial handshaking process. I used some dummy random GCMIDs to test downstream messaging at first and it was showing up in the smack debug window but later on, the same code shows nothing after the following xml feed as Raw sent packets:
<stream:stream xmlns='jabber:client' to='gcm.googleapis.com' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' xml:lang='en'>
and i tried
mConnection.login(uid+"#gcm.googleapis.com",apiKey);//even though i assume its next step of the handshake.
Console prints the following errors:
org.jivesoftware.smack.SmackException$NoResponseException: No response received within reply timeout. Timeout was 10000ms (~10s). Used filter: No filter used or filter was 'null'.
at org.jivesoftware.smack.SmackException$NoResponseException.newWith(SmackException.java:106)
at org.jivesoftware.smack.SmackException$NoResponseException.newWith(SmackException.java:85)
at org.jivesoftware.smack.SynchronizationPoint.checkForResponse(SynchronizationPoint.java:253)
at org.jivesoftware.smack.SynchronizationPoint.checkIfSuccessOrWait(SynchronizationPoint.java:146)
at org.jivesoftware.smack.SynchronizationPoint.checkIfSuccessOrWaitOrThrow(SynchronizationPoint.java:125)
at org.jivesoftware.smack.tcp.XMPPTCPConnection.connectInternal(XMPPTCPConnection.java:837)
at org.jivesoftware.smack.AbstractXMPPConnection.connect(AbstractXMPPConnection.java:360)
at psdc.gcm.SmackCcsClient.init(SmackCcsClient.java:64)
at psdc.gcm.GCMServer.activate(GCMServer.java:44)
at psdc.servlets.Mapper.selectIds(Mapper.java:191)
at psdc.servlets.Mapper.doPost(Mapper.java:152)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:644)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:516)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1086)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:659)
at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:223)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1558)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1515)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
Jun 25, 2015 5:36:18 PM org.jivesoftware.smack.AbstractXMPPConnection callConnectionClosedOnErrorListener
WARNING: Connection closed with error
java.io.EOFException: input contained no data
at org.xmlpull.mxp1.MXParser.fillBuf(MXParser.java:2965)
at org.xmlpull.mxp1.MXParser.more(MXParser.java:3003)
at org.xmlpull.mxp1.MXParser.parseProlog(MXParser.java:1409)
at org.xmlpull.mxp1.MXParser.nextImpl(MXParser.java:1394)
at org.xmlpull.mxp1.MXParser.next(MXParser.java:1092)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:1151)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$200(XMPPTCPConnection.java:937)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:952)
at java.lang.Thread.run(Unknown Source)
Please help me to solve this as i am really stuck with this and nowhere to go.Please tell me a way to check if my xml request reaches google or not.
Am using the SMACK library version 4.1.1
Using config.setSecurityMode(ConnectionConfiguration.SecurityMode.ifpossible); solved my problem. It defines the configuration of the connection to be used.It Turns on TLS if the server supports the same.
refer : http://www.igniterealtime.org/builds/smack/docs/latest/javadoc/org/jivesoftware/smack/ConnectionConfiguration.html
config = XMPPTCPConnectionConfiguration.builder();
config.setSecurityMode(ConnectionConfiguration.SecurityMode.ifpossible);
config.setSocketFactory(SSLSocketFactory.getDefault());
config.setUsernameAndPassword(uid,apiKey);
config.setServiceName("gcm.googleapis.com");
config.setHost("gcm.googleapis.com");
config.setPort(5235);
config.setDebuggerEnabled(true);
mConnection = new XMPPTCPConnection(config.build());
mConnection.setPacketReplyTimeout(10000);
try {
mConnection.connect();
Hope it helps someone.
I am trying to send mails from a Grails application, but without any success.
I've used gmail and other smtp server (without ssl!) but the same error occurs:
org.springframework.mail.MailSendException: Mail server connection failed; nested exception is javax.mail.MessagingException: Exception reading response;
nested exception is:
javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?. Failed messages: javax.mail.MessagingException: Exception reading response;
nested exception is:
javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?; message exceptions (1) are:
Failed message 1: javax.mail.MessagingException: Exception reading response;
nested exception is:
javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
I am using in Config.groovy (example for gmail):
grails.mail.host = "smtp.gmail.com"
grails.mail.from = "xxx#gmail.com"
grails.mail.port = "465"
grails.mail.ssl = "on"
grails.mail.username = "xxx#gmail.com"
grails.mail.password = "xxx"
grails.mail.props = ["mail.smtp.auth": "true",
"mail.smtp.socketFactory.port": "465",
"mail.smtp.socketFactory.class": "javax.net.ssl.SSLSocketFactory",
"mail.smtp.socketFactory.fallback": "false",
"mail.smtp.starttls.enable": "true",
"mail.debug": "true"]
EDIT: I made a simple app with just the mail plugin and a controller and the config posted by Javid Jamae works (3rd answer, also I think the other should work).
BUT even if I just copy-paste the same config and the same sending mail code, on my primary project it still gives me the same exception! I think this can be caused by Nimble plugin (Mail plugin was installed by it).
My configuration is:
Grails version: 1.3.4
Groovy version: 1.7.4
JVM version: 1.6.0_21
jquery - 1.4.2.5
mail - 0.9
shiro - 1.0.1
nimble - 0.4-SNAPSHOT
FINAL EDIT :
I resolved the issue: it seems that I have to use the same settings in the Nimble plugin also, in NimbleConfig.groovy -> mail { ... (must have "from = ...") } .
Stupid issue, but waisted a lot of time on it.
I'm not using SSL and I have the following defined at the bottom of my Config.groovy (not under the environments section):
grails {
mail {
host = "smtp.gmail.com"
port = 465
username = "xxx#gmail.com"
password = "xxx"
props = ["mail.smtp.auth":"true",
"mail.smtp.socketFactory.port":"465",
"mail.smtp.socketFactory.class":"javax.net.ssl.SSLSocketFactory",
"mail.smtp.socketFactory.fallback":"false"]
}
}
I'm using:
app.grails.version=1.2.1
plugins.mail=0.9
This works for me.
You have enabled SSL:
grails.mail.ssl = "on"
And got exception
javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?.
So disable SSL (my config):
host = "smtp.gmail.com"
port = 465
username = "username#gmail.com"
password = "password"
javaMailProperties = ['mail.smtp.auth': 'true',
'mail.smtp.socketFactory.port': '465',
'mail.smtp.socketFactory.class': 'javax.net.ssl.SSLSocketFactory',
'mail.smtp.socketFactory.fallback': 'false']
Anyway, if you want to enable SSL - try 587 port.
Also try to set
mail.smtp.starttls.required : 'true'
Because if server not supports secure connection or client doesn't accept server's certificate secure connection will not started and you will got your exception.
But after setting starttls.required = true and secure connection is impossible whole connection will fails so you got proper exception message.
P.S. Take a note that SSL and TLS - is different protocols.
I dont have this line in my configuration
"mail.smtp.starttls.enable": "true"
and my connection is working
also the port should not be in quotes
grails.mail.port = 465
I ran into a similar strain of this issue as well, so I'll share my experience. When using the Nimble plugin (which uses the Mail plugin as a dependency), Nimble defines its own mail settings in grails-app/conf/NimbleConfig.groovy.
The settings in NimbleConfig.groovy appear to overwrite those set in Config.groovy (presumably because NimbleConfig is executed after Config).
The solution here is conditional:
If you're using Nimble, set the mail properties in grails-app/conf/NimbleConfig.groovy; you do not need to set them in grails-app/conf/Config.groovy
If you're not using Nimble, then just follow the Mail plugin instructions for configuration (or use Javid Jamae's answer)
This seems to be what the OP alluded to in his/her edits, but I just thought I'd confirm the edits with my understanding of what's happening.
Update:
For a reference, here are the NimbleConfig.groovy settings that worked for me:
nimble {
...
messaging {
...
mail {
host = 'smtp.gmail.com'
port = 465
username = '...#gmail.com'
password = '...'
props = [
'mail.smtp.auth': 'true',
'mail.smtp.socketFactory.port': '465',
'mail.smtp.socketFactory.class': 'javax.net.ssl.SSLSocketFactory',
'mail.smtp.socketFactory.fallback': 'false'
]
}
}
}
You can verify your config settings at runtime by checking the
mailService.mailSender properties.Something like this:
mailService.mailSender.properties.each{println}
It will yield the host, port, username, password and a few other values.
If you're sure they are all correct, I would suspect a firewall issue.