반응형
Jake Seo
제이크서 위키 블로그
Jake Seo
전체 방문자
오늘
어제
  • 분류 전체보기 (715)
    • 일상, 일기 (0)
    • 백준 문제풀이 (1)
    • 릿코드 문제풀이 (2)
    • 알고리즘 이론 (10)
      • 기본 이론 (2)
      • 배열과 문자열 (8)
    • 데이터베이스 (15)
      • Planet Scale (1)
      • MSSQL (9)
      • 디비 기본 개념 (1)
      • SQLite 직접 만들어보기 (4)
    • 보안 (7)
    • 설계 (1)
    • 네트워크 (17)
      • HTTP (9)
      • OSI Layers (5)
    • 회고 (31)
      • 연간 회고 (2)
      • 주간 회고 (29)
    • 인프라 (52)
      • 도커 (12)
      • AWS (9)
      • 용어 (21)
      • 웹 성능 (1)
      • 대규모 서비스를 지탱하는 기술 (9)
    • 깃 (7)
    • 빌드 도구 (7)
      • 메이븐 (6)
      • 그레이들 (0)
    • Java (135)
      • 이펙티브 자바 (73)
      • 자바 API (4)
      • 자바 잡지식 (30)
      • 자바 디자인 패턴 (21)
      • 톰캣 (Tomcat) (7)
    • 프레임워크 (64)
      • next.js (14)
      • 스프링 프레임워크 (28)
      • 토비의 스프링 (6)
      • 스프링 부트 (3)
      • JPA (Java Persistence API) (5)
      • Nest.js (8)
    • 프론트엔드 (48)
      • 다크모드 (1)
      • 노드 패키지 관리 매니저 (3)
      • CSS (19)
      • Web API (11)
      • tailwind-css (1)
      • React (5)
      • React 새 공식문서 요약 (1)
      • HTML (Markup Language) (5)
    • 자바스크립트 (108)
      • 모던 자바스크립트 (31)
      • 개념 (31)
      • 정규표현식 (5)
      • 코드 스니펫 (1)
      • 라이브러리 (6)
      • 인터뷰 (24)
      • 웹개발자를 위한 자바스크립트의 모든 것 (6)
      • 팁 (2)
    • Typescript (49)
    • 리눅스와 유닉스 (10)
    • Computer Science (1)
      • Compiler (1)
    • IDE (3)
      • VSCODE (1)
      • IntelliJ (2)
    • 세미나 & 컨퍼런스 (1)
    • 용어 (개발용어) (16)
      • 함수형 프로그래밍 용어들 (1)
    • ORM (2)
      • Prisma (2)
    • NODEJS (2)
    • cypress (1)
    • 리액트 네이티브 (React Native) (31)
    • 러스트 (Rust) (15)
    • 코틀린 (Kotlin) (4)
      • 자바에서 코틀린으로 (4)
    • 정규표현식 (3)
    • 구글 애널리틱스 (GA) (1)
    • SEO (2)
    • UML (2)
    • 맛탐험 (2)
    • 리팩토링 (1)
    • 서평 (2)
    • 소프트웨어 공학 (18)
      • 테스팅 (16)
      • 개발 프로세스 (1)
    • 교육학 (1)
    • 삶의 지혜, 통찰 (1)
    • Chat GPT (2)
    • 쉘스크립트 (1)
    • 컴파일 (2)
    • Dart (12)
    • 코드팩토리의 플러터 프로그래밍 (4)
    • 플러터 (17)
    • 안드로이드 스튜디오 (1)
    • 윈도우즈 (1)
    • 잡다한 백엔드 지식 (1)
    • 디자인 패턴 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • item7
  • 자료구조
  • 스프링 검증
  • 자바 검증
  • 이펙티브 자바
  • Java
  • prerendering
  • serverless computing
  • Pre-rendering
  • 플라이웨이트패턴
  • 이펙티브자바
  • 싱글턴
  • rust
  • 객체복사
  • Javadoc 자바독 자바주석 주석 Comment
  • 빈 검증
  • 도커공식문서
  • item9
  • 디자인패턴
  • 프로그래머의 뇌
  • 참조 해제
  • 작업기억공간
  • 싱글톤
  • 슬로우 쿼리
  • bean Validation
  • 메이븐 페이즈
  • MSSQL
  • 추상 팩터리 패턴
  • 토비의 스프링
  • 싱글톤 패턴
  • 메이븐 라이프사이클
  • Next.js
  • 자바
  • item8
  • 메이븐 골
  • NEXT JS
  • 러스트
  • 이펙티브 자바 item9
  • 서버리스 컴퓨팅
  • 자바스크립트 인터뷰
  • 자바스크립트 면접
  • pnpm
  • 자바스크립트
  • 자바 디자인패턴
  • 외래키 제약조건
  • next js app
  • 느린 쿼리
  • 알고리즘
  • try-with-resources
  • 팩터리 메서드 패턴

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Jake Seo

제이크서 위키 블로그

회고/주간 회고

message_en_US.properties 파일을 찾지 못하는 에러 발생 회고

2023. 4. 13. 23:37

다국어를 못찾는 에러

  • 자바에서 new Location("en_US") 등으로 로케일 설정을 했을 때 message_en_US.properties 파일을 정상적으로 찾지 못했다.
    • 대신 message_en_us.properties 파일을 찾아냈다.

아래 원인을 보면 알겠지만, 대소문자 일반화에 대해서 Locale.defaultLocale() 과 new Locale("ko_KR") 의 결과가 달라서 발생했다.

원인

근본적 원인

  • Locale 클래스의 Locale.defaultLocale() 이라는 정적메서드의 미묘한 동작 때문에 발생했다.
  • 운영체제에 있는 로케일 정보를 가져올 때는 ko_KR 과 같이 대소문자에 대한 일반화를 안하고 가져오고, 내가 직접 생성자로 new Locale("ko_KR") 과 같이 생성하면 대소문자에 대한 일반화를 수행한다.
  • 그래서 Locale.defaultLocale() 은 예상한대로 ko_KR 을 가져오는데, new Locale("ko_KR") 은 예상한대로 ko_KR 을 가져오지 않고, ko_kr 을 가져온다.

나의 케이스

  • 나는 영문이 기본 로케일로 설정된 톰캣을 썼다.
  • 그래서 Locale.defaultLocale() 은 en_US 가 뜨고, ko_KR 을 반환받으려면 new Locale("ko_KR") 을 사용해야 했다. 이 과정에서 계속 ko_kr 을 응답받아서 예상과 다른 결과가 나왔다.

에러를 확인한 방법

  • 디버깅 브레이크 포인트 걸기
  • try ... catch 문으로 익셉션 스택 트레이스 확인
  • 테스트 환경과 운영 환경에서는 정상적으로 동작했다.
    • 테스트 환경과 운영 환경이 다른 점이 무엇인지 생각해봄

조치

  • 일단 운영에서 Locale.defaultLocale() 을 ko_KR 으로 쓰고 있으니 내가 운영 환경에 맞추는게 무조건 맞다.
    • 그래야 프로덕션에서 내 코드가 돈다고 그나마 조금 더 확신할 수 있으니까.
  • 그런데 추후에 이러한 문제가 또 생길지도 모르니 어디서든 잘 돌게 고쳐놓을 것이다.

이후 재확인

다시 보다가 뭔가 이상한 걸 발견했다. 여태까지 추측했던 가설이 전부 틀렸다.

picture 2

  • Locale 의 파라미터는 2개인데, 첫번째가 language 고 두번째가 country 였던 것이다.
  • ko_KR 은 결국 language_COUNTRY 였던 것이다.
  • language 부분에 ko_KR 을 주면 대소문자 일반화를 수행하지만, country 부분에 KR 을 따로 주면 대소문자 일반화를 수행하지 않는다.
  • 아래는 이해를 돕기 위한 테스트코드이다.
@Test
public void getMessage() {
    Locale wrongLocale = new Locale("ko_KR");
    Locale correctLocale = new Locale("ko", "KR");

    Assertions.assertEquals("ko_kr", wrongLocale.toString());
    Assertions.assertEquals("ko_KR", correctLocale.toString());
}

추가적인 편의 상수 확인

  • Locale 클래스 내부에는 아래와 같이 편의를 위한 상수가 존재했다.
  • 처음부터 이 사실을 알았다면 당연히 존재했을 것이라 생각했을텐데 그러지 못했다.
static public final Locale KOREA = createConstant("ko", "KR");
static public final Locale US = createConstant("en", "US");
Locale.KOREA; // ko_KR 과 같다.
Locale.US; // en_US 와 같다
반응형
저작자표시 비영리 (새창열림)

'회고 > 주간 회고' 카테고리의 다른 글

스프링 초기 세팅 시 뜬 에러 메세지 관련 회고 (Invalid bean definition with name 'xxx' defined in null)  (0) 2023.04.17
JS 에서 selector 를 이용할 때 NPE 를 늦게 캐치하는 문제에 대한 회고  (0) 2023.04.14
AWS 타겟 그룹 헬스체크 설정으로 인한 장애 회고  (0) 2023.03.03
2023년 2월 3.5주차 회고  (0) 2023.02.22
쿠키와 Iframe 으로 인한 트러블 슈팅 회고  (0) 2023.02.14
    '회고/주간 회고' 카테고리의 다른 글
    • 스프링 초기 세팅 시 뜬 에러 메세지 관련 회고 (Invalid bean definition with name 'xxx' defined in null)
    • JS 에서 selector 를 이용할 때 NPE 를 늦게 캐치하는 문제에 대한 회고
    • AWS 타겟 그룹 헬스체크 설정으로 인한 장애 회고
    • 2023년 2월 3.5주차 회고
    Jake Seo
    Jake Seo
    ✔ 잘 보셨다면 광고 한번 클릭해주시면 큰 힘이 됩니다. ✔ 댓글로 틀린 부분을 지적해주시면 기분 나빠하지 않고 수정합니다. ✔ 많은 퇴고를 거친 글이 좋은 글이 된다고 생각합니다. ✔ 간결하고 명료하게 사람들을 이해 시키는 것을 목표로 합니다.

    티스토리툴바