-2

Using this link tried to upgrade to TLSv1.2. The only difference was to support all TLS till now so used this :

sslSocket.setEnabledProtocols(new String[]{"TLSv1","TLSv1.1","TLSv1.2"});

The peculiar thing was to get this error :

java.lang.StackOverflowError
        at com.myorg.my.utils.Myfile$CustomHttpsSocketFactory.createSocket(Myfile.java:101)

Where Myfile.java having my contents like this, notice line 101 mentioned below :

//...non useful code above
public Myfile(){
        String scheme = "https";
        Protocol baseHttps = Protocol.getProtocol(scheme);
        int defaultPort = baseHttps.getDefaultPort();

        ProtocolSocketFactory baseFactory = baseHttps.getSocketFactory();
        ProtocolSocketFactory customFactory = new CustomHttpsSocketFactory(baseFactory);

        Protocol customHttps = new Protocol(scheme, customFactory, defaultPort);
        Protocol.registerProtocol(scheme, customHttps); 
    }

    class CustomHttpsSocketFactory implements SecureProtocolSocketFactory
    {

       private final SecureProtocolSocketFactory base;

       public CustomHttpsSocketFactory(ProtocolSocketFactory base)
       {
          if(base == null || !(base instanceof SecureProtocolSocketFactory)) throw new IllegalArgumentException();
          this.base = (SecureProtocolSocketFactory) base;
       }

       private Socket acceptAllTLS(Socket socket)
       {
          if(!(socket instanceof SSLSocket)) return socket;
          SSLSocket sslSocket = (SSLSocket) socket;
          sslSocket.setEnabledProtocols(new String[]{"TLSv1","TLSv1.1","TLSv1.2"});
          return sslSocket;
       } 
   @Override
   public Socket createSocket(String host, int port) throws IOException
   {
      return acceptAllTLS(base.createSocket(host, port));
   }
   @Override
   public Socket createSocket(String host, int port, InetAddress localAddress, int localPort) throws IOException
   {
      return acceptAllTLS(base.createSocket(host, port, localAddress, localPort));
   }
   @Override
   public Socket createSocket(String host, int port, InetAddress localAddress, int localPort, HttpConnectionParams params) throws IOException
   {
      // The following line is 101 where the error occurs     
      return acceptAllTLS(base.createSocket(host, port, localAddress, localPort, params));
   }
   @Override
   public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException
   {
      return acceptAllTLS(base.createSocket(socket, host, port, autoClose));
   }  // ...non  useful code below}

MY QUESTIONS

  1. Seeming obvious, base.createSocket is calling its own method recursively. Cannot understand how?

  2. Could not replicate on my local machine, these logs occur only in production. Hence how could i replicate this (Used the same Java version, tomcat version, lib version as present in production)

EDIT

As per comments the stacktrace :

java.util.concurrent.ExecutionException: java.lang.StackOverflowError at java.util.concurrent.FutureTask.report(FutureTask.java:122) at java.util.concurrent.FutureTask.get(FutureTask.java:206) at com.myorg.cs.aggregator.ciscoivr.services.IvrServiceImpl$1.getStatusList(IvrServiceImpl.java:519) at com.myorg.cs.aggregator.ciscoivr.services.IvrServiceImpl.getCustomerInfo_aroundBody30(IvrServiceImpl.java:380) at com.myorg.cs.aggregator.ciscoivr.services.IvrServiceImpl$AjcClosure31.run(IvrServiceImpl.java:1) at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96cproceed(AbstractTransactionAspect.aj:66) at org.springframework.transaction.aspectj.AbstractTransactionAspect$AbstractTransactionAspect$1.proceedWithInvocation(AbstractTransactionAspect.aj:72) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281) at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96c(AbstractTransactionAspect.aj:70) at com.myorg.cs.aggregator.ciscoivr.services.IvrServiceImpl.getCustomerInfo(IvrServiceImpl.java:335) at sun.reflect.GeneratedMethodAccessor660.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302) at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208) at com.sun.proxy.$Proxy156.getCustomerInfo(Unknown Source) at com.myorg.cs.aggregator.controller.IVRController.getCustomerInfo(IVRController.java:106) at com.myorg.cs.aggregator.controller.IVRController$$FastClassBySpringCGLIB$$e1f912c1.invoke() at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:718) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) at com.myorg.cs.aggregator.interceptor.ResponseTimeInterceptor.invokeUnderTrace(ResponseTimeInterceptor.java:38) at org.springframework.aop.interceptor.AbstractTraceInterceptor.invoke(AbstractTraceInterceptor.java:112) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85) at com.myorg.base.aspect.RequestContextProcessingAspect.forwardRequestContext(RequestContextProcessingAspect.java:113) at sun.reflect.GeneratedMethodAccessor419.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:621) at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:610) at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:68) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:168) at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:654) at com.myorg.cs.aggregator.controller.IVRController$$EnhancerBySpringCGLIB$$a764c904.getCustomerInfo() at sun.reflect.GeneratedMethodAccessor659.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:222) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:814) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:737) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) 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.tuckey.web.filters.urlrewrite.RuleChain.handleRewrite(RuleChain.java:176) at org.tuckey.web.filters.urlrewrite.RuleChain.doRules(RuleChain.java:145) at org.tuckey.web.filters.urlrewrite.UrlRewriter.processRequest(UrlRewriter.java:92) at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:381) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at com.myorg.cs.aggregator.filter.RequestIdentifierFilter.doFilterInternal(RequestIdentifierFilter.java:54) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.filters.CorsFilter.handleNonCORS(CorsFilter.java:438) at org.apache.catalina.filters.CorsFilter.doFilter(CorsFilter.java:179) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:316) at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126) at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:122) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:168) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:48) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:120) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:205) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:205) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:91) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:53) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213) at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176) at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262) 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:502) 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:617) at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:673) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1521) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1478) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:745)

Caused by: java.lang.StackOverflowError at com.myorg.my.utils.Myfile$CustomHttpsSocketFactory.createSocket(Myfile.ja> va:101)

Community
  • 1
  • 1
Danyal
  • 448
  • 4
  • 18
  • Please provide the stacktrace. – 11thdimension Aug 12 '16 at 14:21
  • 11thdimension : The stacktrace 'caused by', repeats this line : at com.myorg.my.utils.Myfile$CustomHttpsSocketFactory.createSocket(Myfile.java:101), some 100 plus times and exits – Danyal Aug 12 '16 at 14:26
  • We need to see what happens before that. – 11thdimension Aug 12 '16 at 14:34
  • Here : java.util.concurrent.ExecutionException: java.lang.StackOverflowError at java.util.concurrent.FutureTask.report(FutureTask.java:122) at java.util.concurrent.FutureTask.get(FutureTask.java:206) at com.myorg.services.SomefileCallingMyMethod$1.getStatusList(SomefileCallingMyMethod.java:519) at com.myorg.services.SomefileCallingMyMethod.getCustomerInfo_aroundBody30(SomefileCallingMyMethod.java:380) at com.myorg.services.SomefileCallingMyMethod.$AjcClosure31.run(IvrServiceImpl.java:1) – Danyal Aug 12 '16 at 14:42
  • 1
    @Danyal rather than adding the stack trace as a comment please add it to the question itself :) – Lahiru Jayaratne Aug 12 '16 at 16:30
  • The stack trace you posted does not agree with the exception you posted. There is no evidence in the stack trace that `createSocket()` has anything to do with it. I suggest you have a prior verion of the code running in production, that has `CustomHttpsSocketFactory extends SecureProtocolSocketFactory` instead of `CustomHttpsSocketFactory implements SecureProtocolSocketFactory`. – user207421 Aug 13 '16 at 03:56
  • EJP as mentioned in the question, there is a 'caused by', which points to my code. Did not write that again earlier for brevity. Wrote that now. :) – Danyal Aug 13 '16 at 04:33
  • My bad EJP. As mentioned I did write the exception earlier in the question. Possibly it was unclear. My bad again, apologies – Danyal Aug 13 '16 at 05:28

3 Answers3

1

If you are using JRE8 (unless you have replaced the default SunJSSE that comes with JRE8), there is a system property "jdk.tls.client.protocols". By default, whatever you mention here will be used for all client communication. I just added my comments under other post u mentioned.

Community
  • 1
  • 1
Rajesh Jose
  • 314
  • 2
  • 12
  • I tried with this java -XshowSettings:properties -version, and the reference to your property was not there. Thanks Rajesh anyways. Also how does it explain the Stackoverflow error? – Danyal Aug 12 '16 at 15:16
  • 1
    Code looks fine...I don't see any recursive call in that. If there was any recursive call, it would have caused stack overflow each and every time. It could be just by chance that the stack over flow happened just at that point...There could be some flow where there are too many functions calls and by chance it hit the stack limit at this point. Unless we can see the entire stack trace, we can not rule out that. You may also want to check your stack frame size and change it if it is too small. Between production and your setup, there could be a difference in stack frame also. – Rajesh Jose Aug 12 '16 at 15:26
  • If the "jdk.tls.client.protocols" is not seen, you may not be using JRE8. It is documented here - https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html – Rajesh Jose Aug 12 '16 at 15:28
  • Fair point Rajesh, about everytime. I tried with too many calls on my local, 24 REQ/persec for 20k requests (Much more that expected in mine 1 req/sec in prod), Still could not replicate – Danyal Aug 12 '16 at 15:31
  • We are using JRE8 Rajesh :) – Danyal Aug 12 '16 at 15:31
  • Number of parallel request will not make any difference...The difference could be environment - Eg: Data coming in the request or the data in model. Also the stack frame size (-Xss) configured also could make a difference – Rajesh Jose Aug 12 '16 at 15:37
  • Did not configue Xss. Does not come in java options too. :( – Danyal Aug 12 '16 at 15:37
0

I have had the same problem with java.util.concurrent.ExecutionException: java.lang.StackOverflowError

The classloader makes private final SecureProtocolSocketFactory base many times base = CustomHttpsSocketFactory and the recursive call to the method causes a StackOverflowError.

In my case my CustomHttpsSocketFactory extends SSLProtocolSocketFactory and the problem disappears

0

I have same problem. You will be register HTTPS protocol many many times. I think registration operation works like stack.

String scheme = "https";
Protocol baseHttps = Protocol.getProtocol(scheme);
int defaultPort = baseHttps.getDefaultPort();

ProtocolSocketFactory baseFactory = baseHttps.getSocketFactory();
ProtocolSocketFactory customFactory = new CustomHttpsSocketFactory(baseFactory);

Protocol customHttps = new Protocol(scheme, customFactory, defaultPort);
Protocol.registerProtocol(scheme, customHttps); 

Protocol.registerProptocol method must call once in JVM. Each registerProtocol cause one method call after a time stack over flow.

Solution: Add a syncronized method like init and call it.

public static boolean INITIALIZED = false; 

private static synchronized void init() {
    if (!INITIALIZED) {
        INITIALIZED = true;
        String scheme = "https";
        Protocol baseHttps = Protocol.getProtocol(scheme);
        int defaultPort = baseHttps.getDefaultPort();

        ProtocolSocketFactory baseFactory = baseHttps.getSocketFactory();
        ProtocolSocketFactory customFactory = new CustomHttpsSocketFactory(baseFactory);

        Protocol customHttps = new Protocol(scheme, customFactory, defaultPort);
        Protocol.registerProtocol(scheme, customHttps); 
    }
}
...
...
init();
...
...