JRuby String doesn’t seem to be compatible with Java String에서 JRuby 0.9.2는 Non-Ascii 문자를 포함한 Ruby String과 Java String이 서로 호환되지 않음을 지적했습니다. JRuby 0.9.8에서는 이 문제가 더 심각해져서, Non-Ascii 문자를 포함한 String을 제대로 출력하는 것은 Ruby String에서도 Java String에서도 불가능해졌습니다.
이를테면, 지난 번 코드에서 다음과 같은 결과가 나옵니다.
java_string = Foo::getString # yields ‘meme메롱’ in java.lang.String form
puts java_string # outputs ‘memeTq’
System.out.println java_string # outputs ‘memeTq’ruby_string = ‘meme메롱’
puts ruby_string # outputs ‘memeTq’
System.out.println ruby_string # outputs ‘memeTq’
Java String을 System.out.println을 사용해 출력하는 경우도, Ruby String을 puts로 출력하는 경우도, Non-Ascii 문자 부분인 ‘메롱’은 ‘Tq’로 출력됩니다. ‘Tq’의 정체는 ‘메롱’의 codepoint에서 lower byte 를 취한 값이죠.
JRuby 0.9.2에서는 RubyString이라는 내부 클래스에서 java.lang.CharSequence를 통해 Unicode 문자를 보존하고, 이를 Ruby와 Java에서 서로 다르게 취급한 반면, JRuby 0.9.8에서는 org.jruby.util.ByteList라는 내부 클래스를 사용하며, org.jruby.util.ByteList로 변환하는 과정에서 ByteList.plain 메서드를 통해 lower byte만 취하는 것으로 보입니다.
결과적으로, JRuby 0.9.8에서 Non-Ascii 문자를 포함한 String을 사용하는 것은 어떤 식으로든 불가능해보입니다. 메일링 리스트를 보면, 사실상 byte 배열에 불과한 Ruby String과의 호환성과 Unicode 지원 사이에서 고민하고 있지만, 단순히 lower byte를 취하면 될까’ 또는 ‘Unicode 지원 안하면 문제가 될까’ 식으로 생각하고 있어서 암울해집니다. 제 생각으로는 lower byte만 취하기보다는 UTF-8 인코딩 등을 일관되게 사용해주는 방법이 나을 듯 한데요. 호환성 문제 때문에 상당히 저자세를 취하고 있는 것 같습니다. 자기네들은 별 문제가 없으니까 당연히 별로 심각하게 생각하지는 못하는거겠죠. (lower byte를 취하면 umlaut까지는 보이니까 말이죠.)
Non-Ascii 문자에 관한 문제는 Tim Bray에 의해 JRUBY-65로 간단하게나마 보고되어 있는 문제지만, 코드나 메일링 리스트 논의를 보아하니, 해결은 기약이 없을 듯 하군요.
한국어 환경에서 JRuby (특히 0.9.8) 사용을 심각하게 고려하고 계시다면 당분간은 사용하지 않는 것이 좋을 듯 합니다. 제가 실수하지 않았다면요.