2016-08-12 91 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(); 
... 
...