当前位置: 首页 > 知识库问答 >
问题:

TLS升级,使用CustomHttpsSocketFactory时发生Stackoverflow错误

商昆琦
2023-03-14

使用此链接试图升级到TLSv1。2.唯一的区别是到目前为止支持所有TLS,因此使用了以下方法:

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

奇怪的是出现了这样的错误:

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

我的文件在哪里。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 IllegalArgumentExcepthtml" target="_blank">ion();
          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}

我的问题

>

  • 很明显,base.createSocket递归调用它自己的方法。不明白怎么做?

    无法在我的本地机器上复制,这些日志只发生在生产中。因此,我如何复制这个(使用与生产中存在的相同的Java版本,tomcat版本,lib版本)

    编辑

    根据stacktrace的评论:

    原因:java。lang.stackoverflowerr在com上。迈尔格。我的乌提尔斯。Myfile$CustomHttpsSocketFactory。createSocket(Myfile.ja)

  • 共有3个答案

    阚通
    2023-03-14

    我也有同样的问题。您将多次注册HTTPS协议。我认为注册操作就像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.register协议方法必须在JVM中调用一次。每个寄存器协议在时间堆栈溢出流后导致一个方法调用。

    解决方案:添加一个像init这样的同步方法并调用它。

    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();
    ...
    ...
    
    国盛
    2023-03-14

    我有同样的问题与java.util.concurrent.执行异常:java.lang.StackOverflow Error

    类加载器使私有的最终SecurePROcolSocketFactory基多次base=CustomHttpsSocketFactory和递归调用该方法导致StackOverflow Error。

    在我的例子中,我的CustomHttpsSocketFactory扩展了SSLProtocolSocketFactory,问题消失了

    吕扬
    2023-03-14

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

     类似资料:
    • 从数据库获取数据时出错: 那我该怎么解决呢?

    • 问题内容: 昨天,“软件更新”中对Jave(1.6.0_31)进行了更新,但是现在当我尝试发送更新的应用程序时,出现此错误“上载到iTunes Store时出错”。 控制台写入此错误…需要Java 1.5、1.6或1.7。当前,java是默认的Java版本。请升级。 任何想法如何解决这个问题? 谢谢! 问题答案: 我遇到了同样的“上载到iTunes Store时发生错误”问题,这使我度过了一个美好

    • 我在使用HTTPUrlConnection时遇到了一些问题。代码基本上是在循环中运行的,每次都连接到不同的URL,检查响应,如果响应满足某些条件,则退出。我被StackOverflowerr搞砸了,但我不确定自己搞砸了什么。我没有使用

    • 我正在尝试使用Jackson将对象序列化到JSON,以便字段名基于一种类型的字段。 我有和这个线程中的OP一样的问题: 然而,这并不奏效。 我正在使用Wildfly 10.1 Final null CustomSerializer类: > 将注释添加到object字段,因此我的Response类现在如下所示: 当我测试它时,我得到了以下json对象: 现在,我尝试了本博客中的建议,并在我的Resp

    • 对python不够熟练,不知道这里发生了什么,所以如果有人知道如何纠正这个问题,将不胜感激。 我的$path如下所示: /users/wg/.rvm/gems/ruby-1.9.3-P125@rails3_2/bin://users/wg/.rvm/gems/ruby-1.9.3-P125@global/bin:///users/wg/.rvm/rubies/ruby-1.9.3-P125/bin

    • 我们正在尝试在 WSO2 BPS 中将 TLS 1.0 升级到 TLS 1.2 版本。以下过程使用此链接升级 TLS 最新版本 来自 WSO2 和我们的 JAVA 应用程序的参考链接在 JDK 1.8 中运行。 > 打开<code> 删除了sslProtocol=“TLS”属性,并将其替换为sslEnabledProtocols=“TLSv1.2”,如下所示。 Wso2BPMN, 那么,TLSv1