Issue in sending mail using java mail API in JBoss 4.2.2 and JBoss 5.1
dasmurali Apr 6, 2011 6:11 AMOne of our application will send email's(around 100K per day) to the clients which is running good in JBoss 4.0.4.
When we migrated to JBoss 4.2.2 or JBoss 5.1, after sending few mail's the threads are hanging. This is happening only in production where our environment is behind firewall. If the JBoss 4.2.2/5.1 server running without firwall, there is no issues with java mail 1.4 API also.
JBoss 4.0.4 will use java mail 1.3 where as JBoss 4.2.2/5.1 will use java mail 1.4 version.
Please find the below thread dump from the JBoss 5.1 server instance.
<code>
Thread: WorkManager(2)-3 : priority:5, demon:true, threadId:77, threadState:RUNNABLE
java.net.SocketInputStream.socketRead0(Native Method)
java.net.SocketInputStream.read(SocketInputStream.java:129)
java.net.ManagedSocketInputStreamHighPerformance.read(ManagedSocketInputStreamHighPerformance.java:258)
com.sun.mail.util.TraceInputStream.read(TraceInputStream.java:97)
java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
java.io.BufferedInputStream.read(BufferedInputStream.java:235)
com.sun.mail.util.LineInputStream.readLine(LineInputStream.java:75)
com.sun.mail.smtp.SMTPTransport.readServerResponse(SMTPTransport.java:1440)
com.sun.mail.smtp.SMTPTransport.close(SMTPTransport.java:645)
javax.mail.Transport.send0(Transport.java:171)
javax.mail.Transport.send(Transport.java:98)
org.myapp.MailHandler.sendEmail(MailHandler.java:274)
org.myapp.MailHandler.handle(MailHandler.java:107)
org.myapp.MailMDB.onMessage(MailMDB.java:71)
sun.reflect.GeneratedMethodAccessor268.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:585)
org.jboss.invocation.Invocation.performCall(Invocation.java:386)
org.jboss.ejb.MessageDrivenContainer$ContainerInterceptor.invoke(MessageDrivenContainer.java:513)
org.jboss.resource.connectionmanager.CachedConnectionInterceptor.invoke(CachedConnectionInterceptor.java:156)
org.jboss.ejb.plugins.MessageDrivenInstanceInterceptor.invoke(MessageDrivenInstanceInterceptor.java:115)
org.jboss.ejb.plugins.CallValidationInterceptor.invoke(CallValidationInterceptor.java:63)
org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:121)
org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:350)
org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:181)
org.jboss.ejb.plugins.RunAsSecurityInterceptor.process(RunAsSecurityInterceptor.java:133)
org.jboss.ejb.plugins.RunAsSecurityInterceptor.invoke(RunAsSecurityInterceptor.java:103)
org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:205)
org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invoke(ProxyFactoryFinderInterceptor.java:138)
org.jboss.ejb.MessageDrivenContainer.internalInvoke(MessageDrivenContainer.java:415)
org.jboss.ejb.Container.invoke(Container.java:1029)
sun.reflect.GeneratedMethodAccessor267.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:585)
org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:157)
org.jboss.mx.server.Invocation.dispatch(Invocation.java:96)
org.jboss.mx.server.Invocation.invoke(Invocation.java:88)
org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:668)
org.jboss.invocation.local.LocalInvoker$MBeanServerAction.invoke(LocalInvoker.java:169)
org.jboss.invocation.local.LocalInvoker.invoke(LocalInvoker.java:118)
org.jboss.invocation.InvokerInterceptor.invokeLocal(InvokerInterceptor.java:209)
org.jboss.invocation.InvokerInterceptor.invoke(InvokerInterceptor.java:195)
org.jboss.proxy.TransactionInterceptor.invoke(TransactionInterceptor.java:61)
org.jboss.ejb.plugins.inflow.MessageEndpointInterceptor.delivery(MessageEndpointInterceptor.java:249)
org.jboss.ejb.plugins.inflow.MessageEndpointInterceptor.invoke(MessageEndpointInterceptor.java:128)
org.jboss.proxy.ClientMethodInterceptor.invoke(ClientMethodInterceptor.java:74)
org.jboss.proxy.ClientContainer.invoke(ClientContainer.java:101)
$Proxy138.onMessage(Unknown Source)
org.jboss.resource.adapter.jms.inflow.JmsServerSession.onMessage(JmsServerSession.java:178)
org.jboss.jms.client.container.ClientConsumer.callOnMessageStatic(ClientConsumer.java:160)
org.jboss.jms.client.container.SessionAspect.handleRun(SessionAspect.java:831)
org.jboss.aop.advice.org.jboss.jms.client.container.SessionAspect_z_handleRun_5716666.invoke(SessionAspect_z_handleRun_5716666.java)
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
org.jboss.jms.client.container.ClosedInterceptor.invoke(ClosedInterceptor.java:170)
org.jboss.aop.advice.PerInstanceInterceptor.invoke(PerInstanceInterceptor.java:86)
org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
org.jboss.jms.client.delegate.ClientSessionDelegate.run(ClientSessionDelegate.java)
org.jboss.jms.client.JBossSession.run(JBossSession.java:199)
org.jboss.resource.adapter.jms.inflow.JmsServerSession.run(JmsServerSession.java:234)
org.jboss.resource.work.WorkWrapper.execute(WorkWrapper.java:205)
org.jboss.util.threadpool.BasicTaskWrapper.run(BasicTaskWrapper.java:260)
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)
java.lang.Thread.run(Thread.java:595)
<code>
I browsed the "com.sun.mail.smtp.SMTPTransport" code and found the below code snippet is giving problem.
After sending email to each indiavidaul "email address"(i.e recipient), the "Transport" class calls the "close()" method which indirectly send "QUIT" server command (in SMTPTransport.java)
<code> sendCommand("QUIT"); <code>
And will wait for the server response for the same "QUIT" command. Here the threads are hanging/waiting for the server respnse.
Below is the compelted method code from
SMTPTransport.java
<code>
/**
* Close the Transport and terminate the connection to the server.
*/
public synchronized void close() throws MessagingException {
if (!super.isConnected()) // Already closed.
return;
try {
if (serverSocket != null) {
sendCommand("QUIT");
if (quitWait) {
int resp = readServerResponse();
if (resp != 221 && resp != -1 && debug)
out.println("DEBUG SMTP: QUIT failed with " + resp);
}
}
} finally {
closeConnection();
}
}
<code>
Thanks and Regards
Murali Reddy