Spring devtools classLoader 오류

Allow·2023년 11월 23일
0

현상

Local에서 Spring Project API호출시 다음와 같은 오류가 발생했다.

{
    "timestamp": 1696997788477,
    "status": 500,
    "error": "Internal Server Error",
    "message": "loader constraint violation: when resolving method '***.***.***.***.request.SignInRequest$SignInRequestBuilder ***.***.***.signin.request.SignInRequest$SignInRequestBuilder.snsType(***.***.***.enums.SnsType)' the class loader org.springframework.boot.devtools.restart.classloader.RestartClassLoader @30c4828b of the current class, ***/***/***/login/mapper/LoginMapperImpl, and the class loader 'app' for the method's defining class, ***/***/***/signin/request/SignInRequest$SignInRequestBuilder, have different Class objects for the type ***/***/***/enums/SnsType used in the signature (***.****.***.login.mapper.LoginMapperImpl is in unnamed module of loader org.springframework.boot.devtools.restart.classloader.RestartClassLoader @30c4828b, parent loader 'app'; ***.***.***.signin.request.SignInRequest$SignInRequestBuilder is in unnamed module of loader 'app')",
    "path": "/member/login"
}

원인

loader constraint violation: when resolving method '***.***.***.signin.request.SignInRequest$SignInRequestBuilder ***.***.***.signin.request.SignInRequest$SignInRequestBuilder.snsType(***.***.common.enums.SnsType)' the class loader org.springframework.boot.devtools.restart.classloader.RestartClassLoader @30c4828b of the current class, ***/***/***/login/mapper/LoginMapperImpl, and the class loader 'app' for the method's defining class, ***/***/***/signin/request/SignInRequest$SignInRequestBuilder, have different Class objects for the type ***/***/common/enums/SnsType used in the signature (***.***.***.login.mapper.LoginMapperImpl is in unnamed module of loader org.springframework.boot.devtools.restart.classloader.RestartClassLoader @30c4828b, parent loader 'app'; ***.***.***.signin.request.SignInRequest$SignInRequestBuilder is in unnamed module of loader 'app')"

devtools에서 base class loader와 restart class loader 2개의 클래스 로더가 있고 application에서 개발된 클래스는 restart class loader를 사용한다.

기본적으로 IDE에서 open한 프로젝트는 restart loader가 load하고 .jar class들은 class loader가 로드한다.

멀티모듈 프로젝트이거나 해당 프로젝트의 모든 모듈이 IDE에서 open한게 아니라면 수정이 필요할 수 있다.


해결방법

아래 방법 중에서 선택하여 해결할 수 있다.
1. devtools을 제거

# build.gradle
 
dependencies {
    // developmentOnly 'org.springframework.boot:spring-boot-devtools'
}
  1. META-INF/spring-devtools.properties 파일을 생성하여 restart class loader 설정
restart:
  exclude:
    companycommonlibs: "/mycorp-common-[\\w\\d-\\.]+\\.jar"
  include:
    projectcommon: "/mycorp-myproj-[\\w\\d-\\.]+\\.jar"
  1. devtools Restart 비활성화
@SpringBootApplication
public class MyApplication {
    public static void main(String[] args) {
        System.setProperty("spring.devtools.restart.enabled", "false");
        SpringApplication.run(MyApplication.class, args);
    }
}

주의사항

  • DevTools는 기본적으로 개발시에만 사용되며, prod환경에서는 사용되지 않는다.
  • VM 옵션에 -Dspring.devtools.restart.enabled=true를 줘서 프로덕션 레벨에서도 켤 수 있다.
  • 프로덕션 레벨에서 spring-boot-devtools를 켜면 보안상의 취약점이 생길 수 있음으로 켜지 않는 것을 권장
  • -Dspring.devtools.restart.enabled=false로 확실히 끌 수 있다.

참고문서

https://docs.spring.io/spring-boot/docs/current/reference/html/using.html#using.devtools.restart.customizing-the-classload

https://docs.spring.io/spring-boot/docs/1.5.16.RELEASE/reference/html/using-boot-devtools.html

https://jake-seo-dev.tistory.com/60#Restart-�%-E��%-B%-C�%-E%---%--�%B-%--�%--%-C�%--%B-�%--%--�%--%--�%B-%B-

profile
반갑습니다!

0개의 댓글