Aug 26 2008

순수 자바를 이용하여 JVM을 죽게 하는 프로그램을 어떻게 짤까?

분류: Lang.Java 태그: ,, , , Heart @ 1:36 오전

Trackback : http://dev.heartsavior.net/archives/182/trackback/

순수 자바를 이용하여 JVM을 죽게 하는 프로그램을 어떻게 짜죠?

‘사랑하지 않으면 떠나라’ 의 한 챕터에서 제시하는, 자바 고급 프로그래머에 대한 면접 내용이다.

처음에 이 문제를 접했을 때 잠깐 착각을 해서 ‘순수 자바를 이용하여’ 라는 부분을 염두에 두지 못했다.

이 전제가 없으면 가장 편하게 생각할 수 있는 방법은 JNI 이다. JNI에서 C/C++ 라이브러리를 호출하고, 라이브러리 내부에서 런타임 에러로 crash 상태를 만들면(잘못된 메모리 참조 같은 쉬운 방법을 이용하자) JVM 도 crash 가 발생하게 된다. 견고한 JVM 을 피해서 돌아가는 답안이라고 할 수 있다. 그만큼 JNI 라이브러리를 작성할 때는 심혈을 기울여야 한다는 뜻이기도 하다.

하지만, ‘순수 자바를 이용하여’ 라는 전제가 붙는 것을 확인하고는 답을 낼 수 없었다. 자바 코드 내에서 발생하는 오류는 모두 Exception 이나 Error 로 잡힌다고 생각했던 것도 있고, JVM 내부는 공부해 본 적이 없기 때문이기도 했다.

그러다 오늘, 프로그래밍 갤러리에서 DriverManager Vulnerability 라는 글이 올라왔고, 약간의 논쟁 후에 immutable 속성인 String 클래스의 private field 를 수정하는 아이디어가 나타났다.
reflection을 몰라서 가능할 것이라고는 전혀 생각하지 못했다.
근데… reflection을 통해서 String 클래스의 private field 를 변경하는 글이 올라왔다. (첫번째 글 / 두번째 글)
이것 자체로도 나에게는 상당히 신기한 일이었다.
C/C++ 언어를 주로 다뤘던지라, 캡슐화는 견고함을 보장한다라고 생각을 하고 있었는데, reflection 으로 private field의 access 권한을 획득해버렸다.

근데, 첫번째 글의 결과를 보니… JVM이 죽었다!?

글에 적힌 crash 로그를 살펴보니 jre 1.5 버전이다.
같은 코드를 eclipse 에서 구현하여 해당 프로젝트의 JDK와 JRE를 1.5로 맞추었다.

String abc = "abc";
String def = "abc";
Field declaredField = String.class.getDeclaredField("value");
declaredField.setAccessible(true);
char[] abcArray = (char[]) declaredField.get(abc);
 
abcArray[0] = 'd';
 
System.out.println(def);

해당 코드를 호출했다. 역시, JVM이 crash되었다.

#
# An unexpected error has been detected by HotSpot Virtual Machine:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0×00aea4fc, pid=1764, tid=1672
#
# Java VM: Java HotSpot(TM) Client VM (1.5.0_16-b02 mixed mode, sharing)
# Problematic frame:
# j  net.heartsavior.dev.JVMDeath.crashJVMUsingStringObject()V+24
#
# An error report file with more information is saved as hs_err_pid1764.log
#
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp
#

뭐… 그래서 결론은 JVM 이 죽는 코드를 ‘구현했다’ 가 아닌 ‘발견했다’ 이고, 그나마 위의 코드는 1.6에서는 통하지 않는다…;;
위의 코드를 1.6에서 돌리면 정상적으로(라고 해야될라나) ‘def’ 가 출력된다.
( 이게 1.5만의 버그인지, 1.5 이하 공통 버그였다가 1.6에서 수정된 것인지는 잘 모르겠다. 귀찮다;; )

ps. 잘 생각해 보면 1.6도 JVM 이 죽지 않는다 뿐이지, String 클래스가 immutable 에서 해방될 수 있다…
즉, ” ‘뻘짓을 하지 않고 정식 루트로 접근할 경우’ String 클래스는 immutable 이다 ” 라고 할 수 있겠다. -_-;;


Aug 25 2008

XP tweak 배포판 고발 건에 대한 생각

분류: Dev.Think 태그: ,, , Heart @ 1:35 오전

Trackback : http://dev.heartsavior.net/archives/180/trackback/

아는 사람은 알겠지만, JMXP 라는 Windows XP tweak 배포판이 MS에 의해 고발되었다.
무려 합의금으로 6억원이 제시되었다는데… 6억원이면 XP 1부 를 아주 넉넉하게 40만원씩 잡아도 1500부 에 상당하는 액수이다.
게다가 개인이 6억원을 합의로 처리할 리가 없는 일… 당연히 합의해 줄 의향이 없다는 표현으로 제시한 액수일 것이다.

tweak 자체가 합법적이지 않기 때문에 제작자가 죄값을 치러야 하는 것은 어쩔 수 없는 일이라 쳐도…
분명 현실적인 합의금을 제시하여 경각심도 주고 일도 너무 크게 벌이지 않을 수도 있는데, 합의 자체를 못하게 만들어서 굳이 배포자 인생에 빨간 줄을 그어버리겠다 - 적어도 한국에서 빨간 줄이 그어진다라는 것은 엄청난 낙인이라고 생각한다 - 는 MS의 정책은 조금 아쉽다. 아니, 무섭다.

MS가 배포판에 대해 사전 경고를 했는지 안했는지가 나로써는 정말 궁금하다.
사전 경고 조치라는 노력 정도는 MS에서 했었길 바란다.
해결책으로 꼭 여러 사람 빨간 줄 긋는 방법만 있는 건 아닐 것이다.
다른 방법이 있다면, 먼저 시도를 해서 통하지 않으면 그 때 조치를 취해도 되지 않을까?
힘 있는 기업이 힘 없는 개인 찍어누르는 데 온 힘을 기울일 필요는 없는 것 아닌가…

다시 한 번 정리하자면, JMXP 제작자가 죄를 저지른 것도 사실이고 죄 값을 치러야 하는 것도 사실이지만, 개인을 상대로 한 소송에서 극단적인 처벌을 요구한다는 면은 솔직히 좀 아쉬울 따름이다.
뭐라 할 처지는 안되고, 그저 아쉽다고…

ps. 솔직히 XP 를 tweak 해서 드라이버를 포함시키는 방법이 정말 유용한 방법이긴 하다.
SATA 드라이버나 RAID 드라이버가 XP 순정에 없으면… 정말 좌절의 상황이 오기 때문이다.
XP 가 처음 등장했을 때에도 플로피 드라이브를 장착하는 PC들이 별로 없었거나 감소 추세였던 것으로 아는데, 지금이라도 다른 개선을 보여 줄 수는 없는 것인가?
‘Vista 는 그럴 필요 없으니 Vista 를 사라’ 는 답이라고 할 수는 없을 것 같다.


Aug 11 2008

Thread Pool 을 별다른 설정 없이 간단하게 사용하는 방법

분류: Lang.Java 태그: ,, Heart @ 6:14 오후

Trackback : http://dev.heartsavior.net/archives/177/trackback/

* Thread Pool 을 별다른 설정 없이 간단하게 사용하는 방법

ExecutorService service = Executors.newFixedThreadPool(CONCURRENT_THREAD_COUNT);

service.execute(new Runnable() { public void run() { … } });

service.shutdown();

(짧기 때문에 code-highlight 를 적용하지 않았음)

java.util.concurrent.Executor와 그의 친구들을 사용하면 두세 줄로 해결

이런 유용한 메소드를 지원해 준다는 건 상당히 마음에 든다. J2SE 만세~!!

ps. 좀 더 복잡하게 사용하는 방법은 아래 링크 참조(매번 이런 식이지…)

@ ThreadpoolExecutor


뒷 쪽 »