2016-08-12 95 views
-2

使用this链接尝试升级到TLSv1.2。唯一的区别是支持所有TLS到现在这样用的:TLS升级,使用CustomHttpsSocketFactory时发生Stackoverflow错误

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

奇特的事情是让这个错误:

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

凡Myfile.java有我的内容是这样,通知行下面提到 101:

//...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} 

我的问题

  1. 看起来很明显,base.createSocket正在递归调用它自己的方法。不明白怎么样?

  2. 无法在我的本地机器上复制,这些日志仅在生产中发生。因此,我怎么能复制这种(使用相同的Java版本,Tomcat的版本,库版本存在于生产)

编辑

按照意见的堆栈跟踪:

的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) 在 com.myorg.cs.aggregator.ciscoivr.services.IvrServiceImpl.getCustomerInfo_aroundBody30(IvrServiceImpl.java:380) 在 com.myorg.cs.aggregator.ciscoivr.services.IvrServiceImpl $ AjcClosure31.run(IvrServiceImpl.java:1) 在 org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc $约$ 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) 约为$ org_springframework_transaction_aspectj_AbstractTransactionAspect $ 1个$ 2a73e96c(AbstractTransactionAspect.aj:70) org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc $在 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) 在 org.springframework.transaction.interceptor.TransactionInterceptor $ 1.proceedWithInvocation(TransactionInterceptor.java:99) 在 org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport的.java:281) 在 org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 在 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() 在 org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) 在 org.springframework.aop.framework.CglibAopProxy $ CglibMethodInvocation.invokeJoinpoint( CglibAopProxy.java:718) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) 在 com.myorg.cs.aggregator.interceptor.ResponseTimeInterceptor.invokeUnderTrace(RESPONSETIME Interceptor.java:38) 在 org.springframework.aop.interceptor.AbstractTraceInterceptor.invoke(AbstractTraceInterceptor.java:112) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 在 org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85) 在 com.myorg.base.aspect.RequestContextProcessingAspect.forwardRequestContext(RequestContextProcessingAspect.java:113) 在sun.reflect.GeneratedMethodAccessor419.invoke(未知源)在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.l ang.reflect.Method.invoke(Method.java:497)在 org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:621) 在 org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice的.java:610) 在 org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:68) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:168) 在 org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) at org.springframework.aop.framework.ReflectiveMethodInvoca tion.proceed(ReflectiveMethodInvocation.java:179) 在 org.springframework.aop.framework.CglibAopProxy $ DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:654) 在 com.myorg.cs.aggregator.controller.IVRController $$ EnhancerBySpringCGLIB $$ a764c904.getCustomerInfo() 在sun.reflect.GeneratedMethodAccessor659.invoke(未知来源)在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在java.lang.reflect.Method.invoke(方法。 org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:222) at org.springframework.web.method.support.InvocableHandlerMethod。invokeForRequest(InvocableHandlerMethod.java:137) 在 org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) 在 org.springframework.web.servlet.mvc.method。 annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:814) 在 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:737) 在 org.springframework.web.servlet。 mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherSer vlet.java:959) 在 org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) 在 org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) 在 org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) 在javax.servlet.http.HttpServlet.service(HttpServlet.java:622)在 org.springframework.web.servlet.FrameworkServlet.service (FrameworkServlet.java:846) 在javax.servlet.http.HttpServlet.service(HttpServlet.java:729)在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) 在 有机apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 在 org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 在 org.apache.catalina.core。 ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 在 org.tuckey.web.filters.urlrewrite.RuleChain.handleRewrite(RuleChain。的java:176) 在 org.tuckey.web.filters.urlrewrite.RuleChain.doRules(RuleChain.java:145) 在 org.tuckey.web.filters.urlrewrite.UrlRewriter.processRequest(UrlRewriter.java:92) 在 org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:381) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) 在 org.apache .catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 在 com.myorg.cs.aggregator.filter.RequestIdentifierFilter.doFilterInternal(RequestIdentifierFilter.java:54) 在 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) 在 org.apache.catalina.filters.CorsFilter.handleNonCORS(CorsFilter.java:438) 在 org.apache.catalina.filters .CorsFilter.doFilter(CorsFilter.java:179) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) 在 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) 在 org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90) 在 org.springframework.security.web。的FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:330) 在 org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114) 在 org.springframework.security.web.FilterChainProxy $ VirtualFilterChain。 doFilter(FilterChainProxy.java:330) at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:122) 在 org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:330) 在 org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) 在 组织.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:330) 在 org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:168) 在 org.springframework.security .web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.springframework.security.w eb.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:48) 在 org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:330) 在 org.springframework.security.web.authentication。 logout.LogoutFilter.doFilter(LogoutFilter.java:120) 在 org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:330) 在 org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter。 doFilter(AbstractAuthenticationProcessingFilter.java:205) at org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:330) 在 org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:205) 在 org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:330) 在 组织.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64) 在 org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 在 org.springframework.security.web .FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:330) at org.springframework.security.web.context.SecurityContextPer sistenceFilter.doFilter(SecurityContextPersistenceFilter.java:91) 在 org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:330) 在 org.springframework.security.web.context.request.async。 WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:53) 在 org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 在 org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(的FilterChainProxy。 java:330) at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy。的java:213) 在 org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176) 在 org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) 在 有机.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) 在 org.apache.catalina.core.ApplicationFilterChain .doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219) 在 org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) 在 org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) 在 org.apache.catalina .core.StandardHostValve.invoke(StandardHostValve.java:142) 在 org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) 在 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(StandardEngine Valve.java:88) 在 org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518) 在 org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091) 在 org.apache.coyote.AbstractProtocol $ AbstractConnectionHandler.process(AbstractProtocol.java:668) 在 org.apache.tomcat.util.net.NioEndpoint $ SocketProcessor.doRun(NioEndpoint.java:1521) 在 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)

引起:在 com.myorg.my.utils.Myfile $ CustomHttpsSocketFactory.createSocket java.lang.StackOverflowError的 (Myfile.ja> VA:101)

+0

请提供堆栈跟踪。 – 11thdimension

+0

11thdimension:由''引起的堆栈跟踪,重复以下行:at com.myorg.my.utils.Myfile $ CustomHttpsSocketFactory.createSocket(Myfile.java:101),大约100加上次数并退出 – Danyal

+0

我们需要看看之前发生了什么那。 – 11thdimension

回答

1

如果您使用的是JRE8(除非您已经替换了JRE8附带的默认SunJSSE),那么系统属性为“jdk.tls.client.protocols”。默认情况下,这里提到的任何内容都将用于所有客户端通信。我刚刚在你提到的other post下加了我的评论。

+0

我试着用这个java -XshowSettings:properties -version,并且对你的属性的引用不在那里。谢谢Rajesh反正。另外它如何解释Stackoverflow错误? – Danyal

+1

代码看起来很好......我没有看到任何递归调用。如果有任何递归调用,每次都会导致堆栈溢出。可能只是偶然发生堆栈溢出而已......在这种情况下,可能会有一些流程存在过多的函数调用,并且偶然在此时达到堆栈限制。除非我们能够看到整个堆栈跟踪,否则我们不能排除这一点。你可能也想检查你的堆栈帧大小,如果它太小,就更改它。在生产和设置之间,堆栈框架也可能有所不同。 – Rajesh

+0

如果没有看到“jdk.tls.client.protocols”,那么您可能没有使用JRE8。这里记录 - https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html – Rajesh

0

我有同样的问题java.util.concurrent.ExecutionException:java.lang.StackOverflowError的

的类加载器使得私人最终SecureProtocolSocketFactory基地多次基地= CustomHttpsSocketFactory和递归调用该方法导致StackOverflowError。

在我的情况我CustomHttpsSocketFactory 延伸SSLProtocolSocketFactory和问题消失

0

我有同样的问题。您将多次注册HTTPS协议。我认为注册操作像堆栈一样工作。

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方法必须在JVM中调用一次。每个registerProtocol在时间堆栈溢出之后引起一个方法调用。

解决方法:添加一个像init一样的syncronized方法并调用它。

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(); 
... 
...