Java 한글 깨짐 방지를 위한 javac 컴파일 옵션

하드 코딩된 한글 메시지가 있는 java파일을  컴파일하는 경우, runtime때 한글 출력이 깨지지 않도록 하기 위해서는 주의가 필요한다. 

특히 소스 작성은 Windows에서 하고 Unix서버에서 해당 소스를 컴파일 후, 실행하는 경우 컴파일 인코딩 옵션을 주의해야 한다.  runtime시 한글 출력이 올바르게 되기 위해서는 먼저 컴파일 하는 시점에서 한글이 올바른 unicode로 변환되는게 중요하다. 이를 위해 컴파일 시에  한글메시지가 들어가 있는 java파일 자체의 인코딩을 고려하여 javac의 인코딩 옵션을 설정해야 한다. 

예를 들어 해당 파일이 Windows의 MS949로 작성되었다면 MS949 인코딩 옵션(javc -encoding=ms949)으로 컴파일 해야 한다. MS949(=CP949)는 MS에서 만든거라, Unix에서 이 파일을 컴파일 할려면 MS949인코딩과 거의 호환되는 euc-kr을 인코딩 옵션으로 주어서 컴파일 해야만 한글이 깨지지 않고 unicode로 잘 바뀌어 클래스안에 살포시 예쁘게 들어간다.

위에서 그냥 호환되지 않고 , “거의” 호환 된다고 한 이유를 설명하자면,
MS949는 (그냥 한글 완성형이 아닌) 확장 한글 완성형이므로, (그냥) 한글 완성형인 euc-kr보다 표현할 수 있는 한글이 문자들이 더 많으며, 통상적으로 쓰이는 한글에서는 큰 무리가 없지만, MS949로 표현 할 수 있는 몇몇 한글문자는 euc-kr로 표현이 안되기 때문이다. 

이를테면 MS949로 “찦차타고 온 똠방각하”표현이 가능하지만 , euc-kr인코딩에는 “찦”, “똠”에 대한 인코딩 룰이 없으므로 euc-kr로 해당 파일을 읽어보면 “찦”, “똠” 글자는 깨진다. 해당 파일이 utf8로 인코딩되어 있다면 컴파일시에도 uf8인코딩으로 컴파일하면 된다. (javac 컴파일 할 때 encoding 옵션을 주지 않으면, jvm의 시스템 인코딩이 자동으로 세팅된다.)

컴파일 시에 한글이 unicode로 잘 변환되어 컴파일 되었다면, class를 실행할 때는  실행환경의 encoding으로 java명령을 수행하면 된다(즉 별도의 -Dfile.encoding옵션을 주지 않아도 된다는 말). 

오히려 실행환경의 인코딩과는 다른 별동의 인코딩을 준다면 한글이 깨진다.예를 들어 실행환경은 euc-kr이 인코딩으로 설정되어 있는데, -Dfile.encoding=utf8로 설정하여 java명령을 실행하는 경우, JVM이 byte code로 부터 한글을 읽어일일때 utf8로 읽어들여서 OS영역으로(console)로 넘겼는데, console에서는 넘겨받은 놈을 euc-kr 인코딩 방식으로 해석하려 들면서 한글이 깨지게 된다.

이 때 주의할점은 jvm 인코딩(-Dfile.encoding)과 OS의 인코딩이 일치한다하더라도 SSH 툴의 인코딩이 다르면 또한 한글이 깨질 수 있으며(SSH의 인코딩도 해당 툴 환경설정에서 일치시켜주자), 셋 다 일치시켰다 하더라도 해당 인코딩이 ISO-8859_1이라면 한글이 깨진다. 왜냐하면, ISO-8859_1에는 한글을 표현하는 문자셋이 없기 때문이다. 이 경우에는 한글을 표현할 수 있는 문자셋과 인코딩으로 OS인코딩을 변경한 후 3개의 인코딩을 일치시켜야 한다.

추가

하기처럼 코딩된 Java 파일의 인코딩 형식이 (Windows에서 작성된)  MS949이며 ISO-8859_1환경의 Unix서버에서 컴파일되는 경우 컴파일 옵션을  ISO-8859_1로 주어야, runtime시 한글이 깨지지 않을 것이다.

System.out.println(new String( “한글”.getBytes(“ISO8859_1”), “EUC_KR” ));

 

댓글 남기기