You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Yong Yuan <yy...@gmail.com> on 2010/10/23 07:43:03 UTC

Threads blocked by HttpServletRequest#getAttribute("javax.servlet.request.X509Certificate") on Tomcat 6.0.10 with OpenJDK 1.6.0

Hello,
I have an application that calls
request.getAttribute("javax.servlet.request.X509Certificate") to get a
HTTP request's peer certificates. It turned out, unfortunately, this
call would cause large number of threads to block. Looking at thread
dumps, I noticed that most of the threads were blocking on a static
method as shown below. The threads blocked because the method
com.sun.security.cert.internal.x509.X509V1CertImpl.getFactory() is a
synchronized static method.

http-7102-1 [BLOCKED] CPU time: 0:01
com.sun.security.cert.internal.x509.X509V1CertImpl.getFactory()
com.sun.security.cert.internal.x509.X509V1CertImpl.<init>(byte[])
sun.reflect.GeneratedConstructorAccessor89.newInstance(Object[])
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Object[])
java.lang.reflect.Constructor.newInstance(Object[])
javax.security.cert.X509Certificate.getInst(Object)
javax.security.cert.X509Certificate.getInstance(byte[])
sun.security.ssl.SSLSessionImpl.getPeerCertificateChain()
org.apache.tomcat.util.net.jsse.JSSESupport.getPeerCertificateChain(boolean)
org.apache.coyote.http11.Http11Processor.action(ActionCode, Object)
org.apache.coyote.Request.action(ActionCode, Object)
org.apache.catalina.connector.Request.getAttribute(String)
org.apache.catalina.connector.RequestFacade.getAttribute(String)
sun.reflect.GeneratedMethodAccessor61.invoke(Object, Object[])
sun.reflect.DelegatingMethodAccessorImpl.invoke(Object, Object[])
java.lang.reflect.Method.invoke(Object, Object[])
com.sun.jersey.server.impl.container.servlet.ThreadLocalInvoker.invoke(Object,
Method, Object[])
$Proxy49.getAttribute(String)
....


I looked into the source code of
org.apache.tomcat.util.net.jsse.JSSESupport.getPeerCertificateChain(boolean),
and found that this method called session.getPeerCertificateChain() at
line 124 to later check if it needs to force a handshake. It is this
method that led to the invocation of X509V1CertImpl.getFactory(),
which blocked most of the threads.

My questions are:

-- Is there any way I can bypass this call,
session.getPeerCertificateChain(), and still get my peer certificates
back?

-- If not, then for the short term, I can replace
session.getCertificateChain() with session.getCertificates() in the
method org.apache.tomcat.util.net.jsse.JSSESupport.getPeerCertificateChain(boolean).
Accordingly to the JavaDoc of javax.net.SSLSession, the method
"getPeerCertificateChain() exists for compatibility with previous
releases. New applications should use getPeerCertificates() instead."
Following the source code of
sun.security.ssl.SSLSessionImpl.getCertificates(), I didn't find any
blocking call. My test also confirmed such observation. That said,
will doing so introduce any bug?

Thanks a lot,

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org