본문 바로가기
  • _^**_
무근본 IT 지식 공유/무근본 자바(JAVA)

[무근본 자바] restapi patch 요청 테스트 중 : java.lang.NoClassDefFoundError 해결 방안

by 크리드로얄워터 2023. 4. 20.
반응형

[질문사항]

현재 restapi patch요청 테스트 중인데 java.lang.NoClassDefFoundError: org/apache/hc/client5/http/classic/HttpClient 이런 오류가 납니다. 구글에서 찾아봐도 안나와서 질문드립니다.

아래 테스트 코드입니다.
class ArticleApiControllerTest {
    @LocalServerPort
    private int port;
    @Autowired
    private TestRestTemplate restTemplate;
    @Autowired
    private ArticleServiceImpl articleService;
    @Autowired
    private ArticleRepository articleRepository;
    @Before
    public void setup() {
    restTemplate.getRestTemplate().setRequestFactory(new HttpComponentsClientHttpRequestFactory());
    }
    @Test
    void updateArticle() {
        Long id = 1L;
        String title = "update title";
        String content = "update content";

        ArticleForm expend = new ArticleForm(title, content);
        expend.setId(id);

        String url = "http://localhost:" + port + "/api/article/" + id;
    RestTemplate restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactory());
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity requestEntity = new HttpEntity(expend, headers);


        //when
        ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.PATCH, requestEntity, Article.class);
    }
}


build.gradle 파일

plugins {
id 'java'
id 'org.springframework.boot' version '3.0.5'
id 'io.spring.dependency-management' version '1.1.0'
}

group = 'com.kdo'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '20'

configurations {
compileOnly {
extendsFrom annotationProcessor
}
}

repositories {
mavenCentral()
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-mustache'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.jetbrains:annotations:24.0.0'
testImplementation 'org.testng:testng:7.1.0'
testImplementation 'junit:junit:4.13.1'
testImplementation 'junit:junit:4.13.1'
testImplementation 'org.projectlombok:lombok:1.18.26'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'javax.servlet:jstl:1.2'
implementation 'org.apache.tomcat.embed:tomcat-embed-jasper'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
runtimeOnly 'com.microsoft.sqlserver:mssql-jdbc'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
implementation 'org.apache.httpcomponents:httpclient:4.5.6'
}


tasks.named('test') {
useJUnitPlatform()
}

compileJava.options.encoding = 'UTF-8'

tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}

 

[답변]

java.lang.NoClassDefFoundError: org/apache/hc/client5/http/classic/HttpClient 오류는 httpclient5 의존성이 클래스 패스에 존재하지 않기 때문에 발생하는 오류입니다.

현재 build.gradle 파일에서 httpclient 의존성을 추가하였으나, 테스트 코드에서는 RestTemplate 객체를 생성할 때 HttpComponentsClientHttpRequestFactory를 사용하고 있습니다. HttpComponentsClientHttpRequestFactory는 httpclient5 라이브러리에 포함된 클래스를 사용하기 때문에 해당 의존성도 추가해야 합니다.

다음과 같이 httpclient5 라이브러리를 추가해 주세요.

 

dependencies {
    //...
    implementation 'org.apache.httpcomponents:httpclient:5.1.4'
    //...
}

 

그리고, ArticleApiControllerTest 클래스에서 restTemplate.getRestTemplate() 대신 new RestTemplate(new HttpComponentsClientHttpRequestFactory())를 사용하고 있습니다. 이 부분도 아래와 같이 수정해 주세요.

 

@Test
void updateArticle() {
    // ...
    RestTemplate restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactory());
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    HttpEntity<ArticleForm> requestEntity = new HttpEntity<>(expend, headers);

    //when
    ResponseEntity<Article> responseEntity = restTemplate.exchange(url, HttpMethod.PATCH, requestEntity, Article.class);
}

 

이렇게 수정하면 HttpComponentsClientHttpRequestFactory에서 httpclient5 클래스를 참조할 수 있게 되어 오류가 해결될 것입니다.

반응형

댓글