Протокол SSLException на Java 11 - PullRequest
1 голос
/ 17 января 2020

Я недавно перенес свое приложение Springboot из Springboot 1, Java 8 в Spring boot 2, Java 11. До сих пор это работало нормально на 8. Это Springboot-приложение - это cron-задание, которое выполняется ежедневно и обрабатывает тысячи записей. Для каждой записи это приложение вызывает другое приложение для получения ответа (оба приложения работают на Java 11).

Странно то, что я получаю это исключение только при обработке нескольких записей (скажем, около 100 с) rest отлично работает.

Ниже приведена трассировка стека исключений:

javax.net.ssl.SSLProtocolException: Connection reset
         at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:126)
         at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:321)
         at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:264)
         at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:259)
         at java.base/sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1314)
         at java.base/sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:839)
         at org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:137)
         at org.apache.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:153)
         at org.apache.http.impl.io.SessionInputBufferImpl.readLine(SessionInputBufferImpl.java:280)
         at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:140)
         at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:57)
         at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:259)
         at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:163)
         at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:153)
         at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:273)
         at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125)
         at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:254)
         at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:195)
         at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:86)
         at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108)
         at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
         at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
         at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:106)
         at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:57)
         at com.win.billpayalerts.service.EcmService.getEcmInfoWithRetryCount(EcmService.java:171)
         at com.win.billpayalerts.service.EcmService.getEcmAccountInfoByEcmContactId(EcmService.java:91)
         at com.win.billpayalerts.service.EcmService.getEcmAccountInfoByEcmContactId(EcmService.java:362)
         at com.win.billpayalerts.service.AlertService.getEcmInfoForCustomer(AlertService.java:233)
         at com.win.billpayalerts.service.InvoiceAlertProcessor.processInvoice(InvoiceAlertProcessor.java:48)
         at com.win.billpayalerts.service.AlertProcessor.invokeNotificationAlert(AlertProcessor.java:70)
         at com.win.billpayalerts.service.AlertProcessor.run(AlertProcessor.java:44)
         at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:779)
         at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:763)
         at org.springframework.boot.SpringApplication.run(SpringApplication.java:318)
         at org.springframework.boot.SpringApplication.run(SpringApplication.java:1213)
         at org.springframework.boot.SpringApplication.run(SpringApplication.java:1202)
         at com.win.billpayalerts.BillpayAlertsApplication.main(BillpayAlertsApplication.java:10)
         at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
         at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
         at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
         at java.base/java.lang.reflect.Method.invoke(Method.java:566)
         at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:47)
         at org.springframework.boot.loader.Launcher.launch(Launcher.java:86)
         at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
         at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)
Caused by: java.net.SocketException: Connection reset
         at java.base/java.net.SocketInputStream.read(SocketInputStream.java:186)
         at java.base/java.net.SocketInputStream.read(SocketInputStream.java:140)
         at java.base/sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:448)
         at java.base/sun.security.ssl.SSLSocketInputRecord.bytesInCompletePacket(SSLSocketInputRecord.java:68)
         at java.base/sun.security.ssl.SSLSocketImpl.readApplicationRecord(SSLSocketImpl.java:1104)
         at java.base/sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:823)
         ... 39 common frames omitted

Это файл Gradle исходного приложения:

plugins {
  id 'org.springframework.boot' version '2.1.6.RELEASE'
  id 'java'
}

apply plugin: 'io.spring.dependency-management'
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'jacoco'
apply plugin: 'checkstyle'
apply plugin: 'jdepend'

sourceCompatibility = 1.11
targetCompatibility = 1.11


bootJar {
  archiveBaseName = 'alerts'
}


repositories {
  mavenCentral()
}

dependencies {
  compile('org.springframework.boot:spring-boot-starter-data-jpa')
  compile('org.springframework.boot:spring-boot-starter-jdbc') {
    exclude group: 'org.apache.tomcat', module: 'tomcat-jdbc'
  }
  compile('org.springframework.boot:spring-boot-starter-web')
  compile('org.springframework.boot:spring-boot-starter-mail')

  compile("org.apache.axis:axis:1.4")
  compile('org.apache.commons:commons-lang3:3.5')
  compile('org.apache.httpcomponents:httpclient:4.3.4')
  compile('org.apache.pdfbox:pdfbox:2.0.1')

  compile("net.sf.ehcache:ehcache:2.10.3")

  compile("commons-discovery:commons-discovery:0.5")
  compile("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.8.4")

  compile('ch.qos.logback:logback-core:1.1.8')
  compile('ch.qos.logback:logback-classic:1.1.8')
  compile("wsdl4j:wsdl4j:1.6.2")


  runtime('com.microsoft:sqljdbc4:4.0')

  testRuntime('com.h2database:h2')
  testCompile('org.springframework.boot:spring-boot-starter-test')
  testCompile group: 'junit', name: 'junit', version: '4.4'
}

Это файл Gradle другое приложение:

 plugins {
   id 'org.springframework.boot' version '2.1.6.RELEASE'
   id 'java'
 }

 apply plugin: 'io.spring.dependency-management'
 apply plugin: 'java'
 apply plugin: 'eclipse'
 apply plugin: 'org.springframework.boot'
 apply plugin: 'jacoco'
 apply plugin: 'checkstyle'
 apply plugin: 'jdepend'

 sourceCompatibility = 1.11

 bootJar {
   baseName = 'accounts'
 } 


 repositories {
   mavenCentral()
 }

 dependencies {
   implementation('org.springframework.boot:spring-boot-starter')
   compile('org.springframework.boot:spring-boot-starter-actuator')
   compile('org.springframework.boot:spring-boot-starter-cache')
   compile('org.springframework.boot:spring-boot-starter-web')
   compile('org.springframework.boot:spring-boot-starter-mail')
   compile("io.springfox:springfox-swagger2:2.7.0")
   compile("io.springfox:springfox-swagger-ui:2.7.0")

   compile('org.springframework.boot:spring-boot-starter-jdbc') {
      exclude group: 'org.apache.tomcat', module: 'tomcat-jdbc'
   }

   compile('org.apache.commons:commons-lang3:3.5')
   compile('org.springframework.boot:spring-boot-starter-data-jpa')
   compile('org.apache.commons:commons-collections4:4.0')
   compile group: 'net.sf.jt400', name: 'jt400-jdk8', version: '9.5'
   compile('org.apache.httpcomponents:httpclient:4.3.4')
   compile('log4j:log4j:1.2.17')
   compile('org.projectlombok:lombok')
   runtime('com.microsoft:sqljdbc4:4.0')

   testCompile group: 'org.springframework.boot', name: 'spring-boot-starter-test'
   testCompile group: 'junit', name: 'junit'
 }

Я попытался отключить TLSv1.3 через аргумент JVM, но это не сработало:

-Djdk.tls.client.protocols="TLSv1,TLSv1.1,TLSv1.2"

Как мне решить эту проблему? Заранее спасибо.

1 Ответ

1 голос
/ 20 января 2020

Не совсем ответ, скорее подозрение и слишком длинный комментарий:

Поскольку вы получаете Connection reset, а не Connection reset by peer, я подозреваю, что сброс выполняется java само приложение или сервер, на котором оно работает. Я посмотрел на исходный код для SocketInputStream.read. Это чтение на основе значения времени ожидания:

try {
    n = socketRead(fd, b, off, length, timeout);
    if (n > 0) {
        return n;
    }
} catch (ConnectionResetException rstExc) {
    impl.setConnectionReset();
} finally {
    impl.releaseFD();
}

My думаю, означает, что ConnectionResetException выбрасывается из-за сброса с сервера, который также устанавливает значение времени ожидания ( в соединении, а не в чтении).

Я не знаю, есть ли у вас журналы с записями об успехах и с ошибками, но если вы это сделаете, возможно, вы можете проверить временные метки, чтобы узнать, есть ли у меня подозрения движутся в правильном направлении.

...