오류 해결/환경

'setReadTimeout(int)' is deprecated and marked for removal 해결

Kyle H 2023. 9. 11. 23:43
 

1. 문제

RestTemplate를 사용할 때, 연결 타임아웃 시간과 읽기 타임아웃 시간은 기본적으로 셋팅하게 됩니다. 

하지만 spring 6.0 부터는 RestTemplate를 설정할 때, HttpComponentsClientHttpRequestsFactory()에서 setReadTimeout() 메서드를 사용할 수 없습니다.

org.springframework.http.client.HttpComponentsClientHttpRequestFactory

 

 

2. 해결

RestTemplateBuilder를 사용하면 해당 문제를 해결 할 수 있습니다.

@Bean("restTemplateCustom")
fun restTemplate(builder: RestTemplateBuilder): RestTemplate {
    return builder.requestFactory { settings ->
                       BufferingClientHttpRequestFactory(
                           ClientHttpRequestFactories.get(HttpComponentsClientHttpRequestFactory::class.java, settings)
                       )
                   }
                  .setConnectTimeout(Duration.ofSeconds(300))
                  .setReadTimeout(Duration.ofSeconds(300))
                  .build()
}

 

이렇게 설정하고 부트를 재시작하면 또 아래와 같은 에러를 만나게 됩니다.

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'restTemplateCustom' defined in class path resource [com/mybookgal/mybookgallery/configuration/RestTemplateConfig.class]: Failed to instantiate [org.springframework.web.client.RestTemplate]: Factory method 'restTemplate' threw exception with message: org/apache/hc/client5/http/socket/LayeredConnectionSocketFactory
	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:659) ~[spring-beans-6.0.11.jar:6.0.11]
	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:647) ~[spring-beans-6.0.11.jar:6.0.11]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1332) ~[spring-beans-6.0.11.jar:6.0.11]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1162) ~[spring-beans-6.0.11.jar:6.0.11]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:560) ~[spring-beans-6.0.11.jar:6.0.11]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) ~[spring-beans-6.0.11.jar:6.0.11]
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[spring-beans-6.0.11.jar:6.0.11]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.0.11.jar:6.0.11]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[spring-beans-6.0.11.jar:6.0.11]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.0.11.jar:6.0.11]
	at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254) ~[spring-beans-6.0.11.jar:6.0.11]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1417) ~[spring-beans-6.0.11.jar:6.0.11]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1337) ~[spring-beans-6.0.11.jar:6.0.11]
	at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:888) ~[spring-beans-6.0.11.jar:6.0.11]
	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ~[spring-beans-6.0.11.jar:6.0.11]
	... 24 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.client.RestTemplate]: Factory method 'restTemplate' threw exception with message: org/apache/hc/client5/http/socket/LayeredConnectionSocketFactory
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:171) ~[spring-beans-6.0.11.jar:6.0.11]
	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:655) ~[spring-beans-6.0.11.jar:6.0.11]
	... 38 common frames omitted
Caused by: java.lang.NoClassDefFoundError: org/apache/hc/client5/http/socket/LayeredConnectionSocketFactory
	at org.springframework.boot.web.client.ClientHttpRequestFactories.get(ClientHttpRequestFactories.java:124) ~[spring-boot-3.1.3.jar:3.1.3]
	at com.mybookgal.mybookgallery.configuration.RestTemplateConfig.restTemplate$lambda$0(RestTemplateConfig.kt:19) ~[main/:na]
	at org.springframework.boot.web.client.RestTemplateBuilder.buildRequestFactory(RestTemplateBuilder.java:662) ~[spring-boot-3.1.3.jar:3.1.3]
	at org.springframework.boot.web.client.RestTemplateBuilder.configure(RestTemplateBuilder.java:628) ~[spring-boot-3.1.3.jar:3.1.3]
	at org.springframework.boot.web.client.RestTemplateBuilder.build(RestTemplateBuilder.java:603) ~[spring-boot-3.1.3.jar:3.1.3]
	at com.mybookgal.mybookgallery.configuration.RestTemplateConfig.restTemplate(RestTemplateConfig.kt:24) ~[main/:na]
	at com.mybookgal.mybookgallery.configuration.RestTemplateConfig$$SpringCGLIB$$0.CGLIB$restTemplate$0(<generated>) ~[main/:na]
	at com.mybookgal.mybookgallery.configuration.RestTemplateConfig$$SpringCGLIB$$2.invoke(<generated>) ~[main/:na]
	at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:258) ~[spring-core-6.0.11.jar:6.0.11]
	at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331) ~[spring-context-6.0.11.jar:6.0.11]
	at com.mybookgal.mybookgallery.configuration.RestTemplateConfig$$SpringCGLIB$$0.restTemplate(<generated>) ~[main/:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:139) ~[spring-beans-6.0.11.jar:6.0.11]
	... 39 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.apache.hc.client5.http.socket.LayeredConnectionSocketFactory
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) ~[na:na]
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) ~[na:na]
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520) ~[na:na]
	... 55 common frames omitted

이 이유는 위에서 javadoc의 클래스 이름들이 빨간색으로 나오는 이유와 동일합니다. 말 그대로 클래스를 찾을 수 없는 상태입니다. 

`HttpComponentsClientHttpRequestFactory`를 들어가보면..

Apche HttpComponents 5.1 이상의 버전이 필요하다고 나와있습니다.

build.gradle.kts에 의존성을 추가해주겠습니다.

implementation("org.apache.httpcomponents.client5:httpclient5:5.2.1")

https://mvnrepository.com/artifact/org.apache.httpcomponents.client5/httpclient5

 

gradle 새로고침을 하고나면, 다음과 같이 라이브러리를 불러온 것을 확인할 수 있습니다.

다시 부트를 재시작하면 정상적으로 시작됨을 확인 할 수 있습니다. 

3. 링크

해당 문제에 대한 spring-boot issue 링크입니다.

https://stackoverflow.com/questions/75242683/i-am-migrating-spring-boot-version-2-7-3-to-spring-boot-3-0-0-so-existing-code-i

 

I am migrating spring boot version 2.7.3 to spring-boot 3.0.0 so existing code is breaking related to HttpClients

import org.apache.http.conn.ssl.NoopHostnameVerifier; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.springframework.context.anno...

stackoverflow.com

https://github.com/spring-projects/spring-boot/issues/35658

 

RestTemplate builder: HttpComponentsClientHttpRequestFactory has the setReadTimeout method marked as deprecated · Issue #35658

Spring boot version: 3.x Cannot instantiate RestTemplate with HttpComponentsClientHttpRequestFactory, it raises Caused by: java.lang.IllegalStateException: Request factory org.springframework.http....

github.com