•원격
객체에 대한 reference가
실제로 원격 객체에 대한 stub
객체를
통해 클라이언트에 참조로 전달된다면 참조로 전달되는 원격
메소드의
파라미터나
반환데이터는
복사본이 전송된다(pass-by-value)
이때
RMI는
객체 직렬화를 이용
한다.
•결국
marshalling과
unmarshalling은
객체 직렬화와 환원이다.
•그러므로
기본적으로 원격 메소드의
파라미터나
리턴 타입은 객체 직렬화가 가능 해야 한다.
•자바에서
직렬화가 가능한 조건은 다음과
같다.
- 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으로
직렬화 되어 전송된다.
만약
sayHello의
return
형이
Serializable을
구현하지 않았다면 java.rmi.MarshalException
이
발생 한다.
•조금만
더 깊이 들어가 보자…
자바
RMI에서
원격 메소드의 호출은 stub/skeleton을
통해 이루어지며 데이터 전송을 위해서는 marshalling과
unmarshalling을
한다고 했으며 이는 직렬화 및 환원 과정
이라고 했다.
•결국
stub과
skeleton에서는
직렬화 및 환원을 위해 ObjectOutputStream과
ObjectInputStream이
필요하다는 것에 대해 감을 잡았을 것이다.
다시
말하면 marshalling을
위해 ObjectOutputStream.writeObejct(…)
, unmarshalling을
위해 ObjectInputStream.readObject(…)를
사용한다.
댓글 없음:
댓글 쓰기