Categories
Uncategorized

피아노 연습 영상 – 터키행진곡, 클레멘티 Op.36

삼십대가 되어 연주해보는 소나티네를 포스팅한지 어느덧 2주가 지났습니다. 

 

저번에 올렸던 영상보다 조금은 더 부드러워졌습니다. 인내심을 가지고 즐감하실 분은 즐감하시고요. 그렇지 않으면 썸네일만 보시고 가시길 바랍니다.

 

  모짜르트의 터키행진곡입니다. (베토벤 아닙니다)

   

 

  지난번에 올렸던 소나티네 클레멘티 Op.36 No.1~3 입니다. 작티 배터리가 오래못가서.. No.3 마지막 2페이지는 짤렸네요.

   

 

3월이 끝나가네요. 주말 준비 알차게 하셔서 편안한 주말 보내시길 바랍니다. 🙂 

Categories
Uncategorized

꾸물거림을 없애줄 초간단 가이드라인

오랜만에 zebhabits에 깔끔한 글이 올라와 번역해봅니다.

 

Dead Simple Guide to Beating Procrastination 

 

최근에 아주 많이 밍기적 대본 적이 있었습니다. 저는 꾸물거림을 진정 사랑하며, 그것을 없애기 위한 일을 하지 않습니다. 

하지만 꾸물거림을 없애버리고 싶어하는 분들을 위해 10개의 과정으로 구성된 간단한 방법을 소개하겠습니다.

 

  1. 당신이 정말 정말 정말 하고 싶어하는 것이 무엇인지 확인하세요. 농담아닙니다. 이 과정을 지나치지 마세요.
  2. 일들을 간단하게 유지하세요. – 도구들과 형식, 그 어느것들도 늘어놓지 마세요. 바로 시작하세요.
  3. 이메일을 확인하거나 다른 작업을 하기 전에 오늘 해야할 일을 가장 먼저 하세요.  
  4. 그 일을 하는데 방해가 되는 모든 것들을 치워버리세요. – 인터넷 선을 뽑아버리는 것까지 포함하시고요.
  5. 시작하세요. 방해가 되는 것들이 있다면 나누어 두시고요.
  6. 스스로에게 ‘난 딱 10분만 이 일을 할꺼야’ 라고 말씀하세요.
  7. 망설여지고 자꾸 피하게 되는 작업을 할 일 목록 맨 위에 올려넣으세요. – 다른 작업을 먼저 하면서 계속 그 일을 안하게 될테니까요. (구조화된 꾸물거림)
  8. 여러분을 신나게 해줄 일을 찾으세요.
  9. 완벽주의는 잊어버리시고요. 일단 시작하세요. 나중에 고치시고요.
  10. 아직도 밍기적대고 있다면.. 당신이 정말 하고 싶어하는 게 무엇인지 재평가해보세요. 그 일을 안해도 되는지 고민해보시고요, 안해도 된다면 미뤄버리시길.

 

만약 이 모든 과정들이 꾸물거림을 없애는데 도움이 되지 않았나요? 그렇다면 낮잠을 자거나 밖에 나가서 놀아보세요. 아니면 아무 일도 안하시거나요. 인생은 생산성이 전부가 아닙니다. 조금만 하세요.

 

비도 오고 날씨가 춥네요. 비오는 날엔 일하지 말고 친구들과 재미난 이야기하며 즐기시길! 🙂

Categories
Daily Development

ServletRequest.getContentLength() always returns -1 on Resin

Resin 3.2의 getContentLength() 버그

Resin 3.2.x를 mod_caucho 뒤에서 사용시 ServletResponse.getContentLength() 가 항상 -1를 리턴한다. 올초에 버그 리포팅 되어 고쳐졌고 4.0 브랜치에 적용했다고 한다. 3.1.x 까지만 해도 없던 버그라고 함. 위 링크에는 https에서 생기는 문제라고 했지만 http 에서도 똑같이 안된다.

어휴, 이래서 함부로 WAS 버전 올리면 안되는 것인가.

물론 getHeader(“Content-Length”)로 가져오면 정상 작동한다. 어쩌라구.

Content-Length must be specified.

p.s. mantis를 잘 보면, 버그 리포팅된지 3개월만에 고쳐준거다. 난 고쳐진지 2달후에야 발견했으니 얼마나 다행인가.

Categories
Daily Life

Do, or do not. There is no try.

Rebel Zen에서 포스트 하나를 읽다가 간지 대마왕 요다의 인용구에 흥건히 젖어버렸습니다.

“Try not. Do, or do not. There is no try.”

  • 시도는 해봤어.
  • 그래, 한 번 해볼께.
  • 시간날 때 한 번 해보지.
  • 내일은 꼭 해봐야겠어.
  • 노력은 해봤어.

이들에게 마스터 요다가 말씀하십니다.

There is no try.

그리고 마스터 요다는 루크에게 포스를 쓰기 위한 조언도 해주셨습니다.

LUKE: Master, moving stones around is one thing. This is totally different.

YODA: No! No different! Only different in your mind. You must unlearn what you have learned.

어휴, 말을 어쩜 그리 간지나게 하시는지. You must unlearn what you have learned. 는 GWT in practice 챕터 4 core application structure 앞부분에도 인용되기도 했습니다.

이 글은 스프링노트에서 작성되었습니다.

Categories
Daily Development

When you pass an object via AMF3 with Red5, be careful.

Flash나 Flex를 프론트 엔드로 쓰는 네트워크 프로그램을 개발한다면 Red5를 사용해볼 것을 추천한다. Red5는 FMS(Flash Media Server)의 자바 구현체이며 오픈소스이다. 많은 사람들이 red5를 오디오나 비디오를 스트리밍할 용도로 많이 사용하고 있는데, 나는 그런 것에는 별로 관심이 없고 그저 AMF를 쓸 수 있기 때문에 사용한다.

AMF는 Active Message Format의 약자이며 위키백과 페이지에서 볼 수 있듯이 대부분의 언어에서 사용할 수 있도록 오픈소스로 개발된 라이브러리들이 많다. AMF는 그저 serialize 포맷의 하나다. Java의 ObjectOutputStream/ObjectInputStream, ruby의 marshal load/dump 처럼 ActionScript 에서 int, string, array, dictionary, object 들을 serialize 하는데 사용하는 것이다. 그나저나 Flash 9 부터 포함되기 시작한 성능 좋은 AVM2 위에서는 AMF3가 들어갔는데 이전 버전의 AMF(version 0)보다 빨라졌다. (AMF1 이나 AMF2 같은 것은 존재한 적이 없다.)

아래 James Ward의 벤치마크 결과는 text based format과 binary based format 과의 치사한 비교이긴 하지만, 괜시리 내 마음을 끌기에는 충분했다.

아이고 치사하다. 아무튼 Red5에서도 AMF3를 지원하므로 POJO를 flash side로 보낼 수 있다.

  1. package a.b.c;
  2. import java.io.Serializable;
  3. import java.util.List;
  4. import java.util.Map;
  5. public class Melong implements java.io.Serializable {
  6. private String a;
  7. private String b;
  8. private List<Integer> c;
  9. private Map<Integer, String> d;
  10. public String getA() { return a; }
  11. public String getB() { return b; }
  12. public List<Integer> getC() { return c; }
  13. public Map<Integer> getD() { return d; }
  14. }

물론 getter/setter 메서드들은 만들지 않아도 된다. 그저 public variable들만 선언해도 무난히 전송된다. Flex의 NetConnection으로 객체를 집어 던질때처럼 registerClassAlias 같은 것으로 등록해줄 필요도 없다. 대신 이 객체를 받아먹을 flex 사이드의 클래스 선언 위에 살포시..

  1. package qqq.www.eee {
  2. [RemoteClass(alias=”a.b.c.Melong”)]
  3. public class Melong {
  4. }
  5. }

RemoteClass alias로 red5 사이드의 fqdn을 넣어주기만 하면 된다.

그런데 오늘 포스팅의 목적은 이것이 아니다.  메서드 하나 잘못 추가했다가 패닉할 수 있다. 자, 여러분이 서버 사이드에서 사용할 목적으로 d Map의 모든 values를 뽑아오는 유틸리티 메서드를 만들었다고 치자. 구현은 다음과 같을 것이다.

  1. public class Melong implements java.io.Serializable {
  2. [생략]
  3. private Map<Integer, String> d;
  4. public List<String> getAllValuesFromD() {
  5. return new ArrayList<String>(this.d.values());
  6. }
  7. }

이렇게 getAllValuesFromD 란 메서드를 구현한 다음, 이 객체를 flash에 전송해본다. 어랏. 이상한 예외가 발생하네 -_-?

  1. org.red5.server.net.rtmp.codec.RTMPProtocolEncoder – Error encoding object:
    java.lang.NullPointerException
    at org.red5.io.object.Serializer.serializeField(Serializer.java:317)
    at org.red5.io.amf3.Output.writeObject(Output.java:483)
    at org.red5.io.object.Serializer.writeObjectType(Serializer.java:274)

거참, 불친절하기도 하다. NullPointerException이 발생했다는데 힌트가 하나도 없다 stacktrace 최상단을 보면 serializeField 란 메서드에서 났다고 한다. 허허.. 요즘 세상에 기본 컬렉션이나 primitive type들도 serialize가 안되는건가. ㄱ- 게다가 이 오류가 발생하면 flex side에 어떠한 신호도 보내주지 않아 로그를 주시하고 있지 않았다면 더욱 황당한 일일 것이다.

이것때문에 1시간 넘게 삽질에 삽질을 거듭했었다. 원인은.. red5의 미숙한 배려였다. 필드를 전송할 때 reflection api로 get으로 시작하는 모든 메서드를 불러와서 get을 떼고 나머지 문자열의 맨 앞 글자를 대문자로 만든 뒤 getField를 해서 null check 없이 다음 프로세스를 처리하는 것이다. 만약 getD() 라는 메서드를 서버 사이드에 구현해뒀다면 getD의 실행결과가 amf3로 전달될 것이다. 하지만 getAllValuesFromD 메서드를 구현한 뒤에는, 황당하게도 어떠한 메시지도 없이 위와 같은 예외를 뱉어버린다. encoding object에 null pointer exception 이라니.. 개발자로 하여금 serializable을 다시 확인하게 하기만 한다.

절대로 절대로 유틸리티성 메서드를 AMF로 전송할 클래스에 선언하지 마라.

이 오류를 뱉는 것은 red5 0.8RC1 포함한 이전 버전에서만 생긴다. 물론 svn trunk를 이용하면 이 오류가 발생하지 않는다. (지금은 RC3 까지 나온 상태이다) 하지만 깔끔하게 처리된 것은 결코 아니다. 오늘 svn update 한 red5 에서 실행해본 결과 값을 잘 전달하고, red5는 어떠한 오류도 뱉지 않지만 flex side에서 오류가 발생한다. flex의 Melong 클래스에 allValuesFromD 란 필드가 없다고. 이것은 당황스럽게 보일 수 있겠지만 대단히 편리한 수단이 될 수도 있다. 만약 Melong 플렉스 클래스에 public var allValuesFromD:Array 를 선언해뒀다면 서버 사이드의 getAllValuesFromD 메서드 실행 결과가 allValuesFromD:Array 필드에 바로바로 박혀주기 때문.

이 사건을 긍정적으로 살펴보면, 모델 클래스에는 절대로 로직 넣지 말라는 조언 정도로 볼 수 있겠다. 메서드가 getter 형태를 띌 경우 remote field에 바로 대입해주는 것은 얼핏보면 편리해보이지만 규칙이 없고 잘 정리된 문서가 없기 때문에 개발자를 혼란에 빠트릴 위험이 많기 때문이다.

이 글은 스프링노트에서 작성되었습니다.