Port를 이미 사용 중이라고 하는 문제

Error : org.springframework.boot.web.server.PortInUseException: Port 8080 is already in use

원인

IDE 상에서는 프로세스가 종료되었으나 실제 프로세스가 종료되지 않은 경우

해결

  • macOS 프로세스 종료
    • lsof 명령어로 해당 port를 사용하는 프로세스 조회 후 종료
    • 프로젝트를 하면서 제일 많이 만났던 문제라 이제는 명령어를 눈감고도 친다
lsof -i:8080
COMMAND   PID    USER  FD    TYPE DEVICE    SIZE/OFF   NODE NAME
java      12345  user  128u  IPv6 0x5210d6  0t0        TCP 127.0.0.1:8080 (LISTEN)
kill -9 <조회 시 뜬 PID>

Launching Spring application Address already in use


참고)

lsof -n -i -p | grep 8080  
  • lsof : 현재 실행중인 프로세스 확인
  • -n : 호스트네임 제거
  • -i : IPv[46] 파일들 선택
  • -P : 포트의 이름 제거



LocalDateTime이 Array type으로 응답 가는 현상 발생

  • 트러블까지는 아니나, 프론트에서 날짜관련 라이브러리를 사용하고 있어 String으로 받길 요구

KakaoTalk_Photo_2023-03-08-19-23-47

원인

  • @EnableWebMvc 사용 → @EnableWebMvc가 serializer, deserializer 설정을 가지고 있어 커스텀으로 config를 등록해두어도 덮어씌우기 때문

해결

  • SpringBoot의 경우 spring-boot-starter-web import 해주면 MVC 관련된 bean 들에 대한 설정을 대신 해줌
    그러나 현재 나는 cors 설정을 위해 기본 동작하는 빈 커스터마이징 필요
    • 현재 @EnableWebMvc를 사용했으나 기존에 설정된 bean 설정을 유지하고 기능을 확장하고 싶은 것이므로 @EnableWebMvc없이 WebMvcConfigurer타입의 @Configuration 클래스를 추가하는 것으로도 충분!
    • 별다른 MVC 설정을 한 것은 없지만, @SpringBootApplication 어노테이션을 붙여줌으로써 기본적인 스프링 부트 MVC 설정도 같이 제공 됨
      • @Configuration 과 WebMvcConfigurer 을 같이 쓰면 MVC 확장

@EnableWebMvc 제거

KakaoTalk_Photo_2023-03-08-19-23-41

@EnableWebMvc showing date in array formate
Developing with Spring Boot
@EnableWebMvc



테스트코드 @AfterEach 내에서 deleteAll() 사용 시, 다른 도메인 테스트까지 영향이 가 전체 테스트에서 EntityNotFoundException 발생

> Task :processTestResources
> Task :testClasses
> Task :test

RouteController를 통해 > 후보지를 루트에 등록한다 FAILED
    org.springframework.orm.jpa.JpaObjectRetrievalFailureException at RouteControllerTest.java:89
        Caused by: javax.persistence.EntityNotFoundException at RouteControllerTest.java:89

53 tests completed, 1 failed

원인

  • 테스트 클래스들이 MysqlTestContainer를 상속받아 구현되었기 때문에, 통합 테스트수행시 컨테이너를 공유해서 사용하기 때문
  • 그렇다면 테스트가 병렬로 실행되는건가? 더 알아봐야함

해결

  • deleteAll()을 deleteById()로 수정해 각각의 테스트에서 사용하는 데이터만 삭제



Redis의 BGSAVE 관련 문제

조금 더 자세히 정리한 것

io.lettuce.core.RedisCommandExecutionException: MISCONF Redis is configured to save RDB snapshots

원인

BGSAVE에 의한 Write Block
Persistent를 위해 BGSAVE로 RDB를 만들고, 실패할 경우 Write command를 전부 거부하기 때문에

해결

해당 옵션(BGSAVE 옵션) 해제

[root@localhost ~]# redis-cli
127.0.0.1:6379> config set stop-writes-on-bgsave-error no
OK
127.0.0.1:6379> quit
[root@localhost ~]#

MISCONF Redis is configured to save RDB snapshots



Security ignoring이 적용이 안되는 문제

web.ignoring().antMatchers(..)는 파라미터로 전달하는 패턴에 대해 security filter chain을 생략함
-> 토큰 재발급 요청을 security filter ignoring 되도록 설정했으나,
직접 만든 custom filter를 제외하지 않아 계속해서 header의 만료된 access token을 검증하면서 발생하는 이슈

원인

  • custom filter를 bean으로 등록한 게 문제
    • custom filter를 bean으로 등록하게 되면
      해당 filter가 security filter chain에 포함되는 게 아니라 default filter chain에 포함되게 되기 때문에
      해당 패턴에 접근하게 됐을 때 그대로 filter를 적용하게 되는 것

해결

  • bean으로 등록해주던 걸 아래처럼 변경한다

      .addFilterBefore(new JwtAuthenticationFilter(jwtTokenProvider()), UsernamePasswordAuthenticationFilter.class)
    
  • 또는, OncePerRequestFilter의 shouldNotFilter() 메서드를 재정의해서 custom filter에서 해당 요청을 무시하도록 한다 (내가 적용한 해결법)

    @Override
    protected boolean shouldNotFilter(HttpServletRequest request) {
      return request.getRequestURI().endsWith("reissue")
          && request.getMethod().equalsIgnoreCase("POST");
    }
    

Spring webSecurity.ignoring() doesn’t ignore custom filter



Token 재발급 요청 시 500 error 이슈

{
    "message": "Cannot invoke \"String.equals(Object)\" because the return value of \"org.prgrms.wumo.global.repository.KeyValueRepository.get(String)\" is null"
}

원인

null 가능성이 있는 변수(keyValueRepository.get(memberId))와 equals 과정에서 에러 발생 -> 변수 위치 변경

해결

if (!keyValueRepository.get(memberId).equals(refreshToken)) {
  throw new ExpiredTokenException("인증 정보가 만료되었습니다.");
}
if (!refreshToken.equals(keyValueRepository.get(memberId))) {
  throw new ExpiredTokenException("인증 정보가 만료되었습니다.");
}
  • 결과 : null인 경우더라도 false로 처리되어 의도한 exception throw 함
{
    "message": "인증 정보가 만료되었습니다."
}



CORS 에러

CORS 정리 내용

원인

React와 SpringBoot의 host와 port가 다르기 때문

해결

Java Config를 통해 Spring MVC 설정에서 CORS 설정함
=> Spring MVC쪽에서 설정을 하더라도 security가 자동으로 spring에 선언해 둔 cors 구성을 사용함


  • 그 외 해결법
    • spring에서 설정하는 법 : controller or method에 @CrossOrigin annotation을 달아주면 됨
    • spring security에서 설정하는 법 : CorsWebFilter를 사용하기 위해 CorsConfigurationSource로 설정


업데이트: