2013년 10월 18일 금요일

I 객체 직렬화

원격 객체에 대한 reference가 실제로 원격 객체에 대한 stub 객체를 통해 클라이언트에 참조로 전달된다면 참조로 전달되는 원격 메소드의 파라미터나 반환데이터는 복사본이 전송된다(pass-by-value) 이때 RMI는 객체 직렬화를 이용 한다.
결국 marshallingunmarshalling은 객체 직렬화와 환원이다.
그러므로 기본적으로 원격 메소드의 파라미터나 리턴 타입은 객체 직렬화가 가능 해야 한다.



자바에서 직렬화가 가능한  조건은 다음과 같다.
  - java.io.Serializable 인터페이스를 직/간접적으로 구현해야 한다.
  - 내장 데이터 타입은 기본적으로 직렬화 가능하다.
  - 멤버변수에 transient로 선언하면 직렬화에서 제외된다.(멤버 변수중 직렬화가 불가능한 변수등이 있을 경우 객체 자체가 직렬화 되지 못하는 오류가 발생 할 수 있으므로 이를 해결하기 위해 “이 멤버는 직렬화에서 제외 하세요” 라는 뜻이다.)
  - static 멤버 변수는 직렬화 되지 않는다.
 
 
“Hello World” RMI Application에서 Hello.java의 원격 메소드인 sayHello를 살펴보자. RMI 클라이언트에서 stub을 통해 sayHello 메소드를 호출시 name pass-by-value방식으로 복사되어 원격 서버로 전송된다. 이때 파라미터 name은 형이 String이므로 직렬화 되어 전송된다.
만약 직렬화 불가능한 파라미터등이 전달된다면 java.rmi.MarshalException 이 발생 한다.
sayHello의 반환 값 역시 Skeleton을 통해 클라이언트의 stub으로 직렬화 되어 전송된다. 만약 sayHelloreturn 형이 Serializable을 구현하지 않았다면 java.rmi.MarshalException 이 발생 한다.
 
조금만 더 깊이 들어가 보자 자바 RMI에서 원격 메소드의 호출은 stub/skeleton을 통해 이루어지며 데이터 전송을 위해서는 marshallingunmarshalling을 한다고 했으며 이는 직렬화 및 환원 과정 이라고 했다.
결국 stubskeleton에서는 직렬화 및 환원을 위해 ObjectOutputStreamObjectInputStream이 필요하다는 것에 대해 감을 잡았을 것이다. 다시 말하면 marshalling을 위해 ObjectOutputStream.writeObejct(…) , unmarshalling을 위해 ObjectInputStream.readObject(…)를 사용한다.
 
 
 

댓글 없음:

댓글 쓰기