메소드 호출과 힙 원격 메소드 호출 서블릿 엔터프라이즈 자바 빈즈 18. RMI를 이용한 원격 배포 메소드 호출과 힙 원격 메소드 호출 서블릿 엔터프라이즈 자바 빈즈
메소드 호출과 힙 메소드 호출은 항상 같은 힙에 들어있는 두 객체 사이에서 이루어집니다. class Foo { void go() { Bar b = new Bar(); b.doStuff(); } public static void main(String[] args) { Foo f = new Foo(); f.go(); doStuff() Bar 객체 Foo 객체
다른 시스템에서 돌아가는 객체의 메소드 JVM JVM 리틀 빅
RMI(원격 메소드 호출; Remote Method Invocation) !!! 다른 시스템에서 돌아가는 객체의 메소드 doCalcUsingDatabase() B A 리턴값 리틀 빅 A와 B가 같은 힙에 들어있지 않기 때문에 A에서 B에 있는 메소드를 호출할 수가 없습니다. RMI(원격 메소드 호출; Remote Method Invocation) !!!
원격 메소드 호출 클라이언트 힙 서버 힙 클라이언트 객체 서비스 객체
원격 메소드 호출 클라이언트 힙 서버 힙 클라이언트 객체 클라이언트 보조 객체 서비스 객체 서비스 보조 객체
원격 메소드 호출 클라이언트 힙 서버 힙 클라이언트 객체 서비스 객체 doBigThing() 클라이언트 보조 객체 서비스 보조 객체
원격 메소드 호출 클라이언트 힙 서버 힙 클라이언트 객체 서비스 객체 doBigThing() 클라이언트에서 메소드 호출한대요. 클라이언트 보조 객체 서비스 객체 서비스 보조 객체
원격 메소드 호출 클라이언트 힙 서버 힙 클라이언트 객체 서비스 객체 doBigThing() doBigThing() 클라이언트에서 메소드 호출한대요. 클라이언트 객체 클라이언트 보조 객체 서비스 객체 서비스 보조 객체
보조 객체 보조 객체(helper object) 실제 통신 작업을 처리함 소켓 및 스트림과 관련된 자질구레한 작업 처리 클라이언트가 로컬 객체에 있는 메소드를 “호출하는 척”하는 것을 가능하게 해 줌 “클라이언트에서 호출하려고 하는 메소드를 가지고 있는 객체인 척”하는 객체 서버 쪽에서는 서비스 보조 객체에서 클라이언트 보조 객체에서 보낸 요청을 받아서 호출에 대한 정보를 열어보고 진짜 서비스 객체에 있는 진짜 메소드를 호출 리턴값을 받아서 포장해서 다시 클라이언트 객체로 보냄
RMI RMI (Remote Method Invocation) 원격 메소드를 호출하는 데 필요한 메커니즘을 제공 사용할 수 있는 규약 JRMP – 자바로 원격 호출하기 위한 용도만으로 쓰임 IIOP – CORBA용 규약. 서버 힙 클라이언트 힙 RMI 스켈레톤 RMI 스터브 클라이언트 객체 서비스 보조 객체 서비스 객체 클라이언트 보조 객체
원격 서비스를 만드는 방법 원격 인터페이스 만들기 원격 인터페이스를 구현한 클래스 만들기 rmic를 이용하여 스터브와 스켈레톤 생성 RMI 레지스트리(rmiregistry) 실행 원격 서비스 시작
1. 원격 인터페이스 만들기 java.rmi.Remote 확장 모든 메소드에서 RemoteException 선언 인자나 리턴값이 직렬화 가능한 유형인지 확인 import java.rmi.*; public interface MyRemote extends Remote { public String sayHello() throws RemoteException; … }
2. 원격 인터페이스를 구현한 클래스 원격 인터페이스 구현 UnicastRemoteObject 확장 RemoteException을 선언하는 생성자 만들기 서비스를 RMI 레지스트리에 등록 puglic class MyRemoteImpl extends UnicastRemoteObject implements MyRemote { public MyRemoteImpl() throws RemoteException { } public String sayHello() { return “Server says, ‘Hey’”; … } try { MyRemote service = new MyRemoteImpl(); Naming.rebind(“Remote_Hello”, service); } catch(Exception ex) { … }
3. 스터브/스켈레톤 생성 원격 인터페이스를 구현한 클래스에 대해 rmic를 실행 MyRemoteImpl_Stub.class 101101 11010101 10101101 1010111 0100110 101101 11010101 10101101 1010111 0100110 MyRemoteImpl_Stub.class MyRemoteImpl_Skel.class
4. rmiregistry 실행 터미널을 열고 rmiregistry 시작 % rmiregistry
5. 서비스 시작 다른 터미널을 열고 서비스 시작 % java MyRemoteImpl 설명 끝나고 579 페이지에 서버용 코드가 있는데요, 그 코드는 간단한 원격 인터페이스하고 원격 서비스를 만들어놓은 것입니다. 이 코드는 나중에 클라이언트를 만들고 나서 클라이언트 코드와 함께 살펴보도록 하겠습니다.
클라이언트에서 스터브를 받는 방법 클라이언트에서 메소드를 호출할 때 스터브 객체에 대해 메소드를 호출 반드시 스터브 객체를 방아야 함 RMI 레지스트리에서 스터브를 찾아냄 MyRemote service = (MyRemote) Naming.lookup(“rmi://127.0.0.1/Remote_Hello”);
클라이언트에서 스터브를 받는 방법 서버 스켈레톤 서비스 객체 스터브 스터브 RMI 레지스트리 클라이언트 lookup() 클라이언트 객체 스켈레톤 스터브 서비스 객체 Remote Hello lookup() 스터브 RMI 레지스트리
스터브 클래스를 받는 방법 스터브 클래스를 직접 클라이언트로 복사 동적 클래스 다운로딩 클래스 파일을 찾을 수 있는 URL을 알려주는 정보가 스터브 객체에 기록됨 역직렬화 과정에서 RMI 시스템에서 클래스를 로컬 시스템에서 찾을 수 없으면 그 URL로 HTTP Get 요청을 하여 클래스를 받아옴
필요한 클래스 파일 서버 스켈레톤 서비스 객체 스터브 스터브 클라이언트 클라이언트 객체 MyRemoteClient.class 101101 11011 101011 101101 11011 101011 101101 11011 101011 MyRemoteClient.class 101101 11011 101011 MyRemoteImpl.class MyRemoteImpl_Stub.class MyRemoteImpl_Stub.class 101101 11011 101011 101101 11011 101011 101101 11011 101011 MyRemote.class MyRemoteImpl_Skel.class MyRemote.class
서블릿 (Servlet) HTTP에서 웹 서버와 함께 돌아가는 자바 프로그램 CGI 프로그래밍을 하는 데 자바를 사용한다고 볼 수 있음 J2EE 서블릿과 EJB(Enterprise Java Beans)를 혼합하기 위한 용도로 많이 쓰임 서블릿은 EJB의 클라이언트 역할을 함 서블릿과 EJB 사이에서 RMI를 통해 정보를 주고받음
서블릿 서블릿을 저장해야 하는 위치 확인 servlets.jar를 구해서 클래스 경로에 추가 HttpServlet을 확장하여 서블릿 클래스 만들기 public class MyServletA extends HttpServlet { … } 서블릿을 호출하는 HTML 페이지 만들기 <a href=“Servlets/MyServletA”>This is the most amazing servlet.</a> 서블릿과 HTML을 웹 서버에서 사용할 수 있도록 만들기
서블릿과 JSP JSP (Java Server Page) 서블릿에서는 출력 선언문에 HTML이 들어가는 자바 클래스를 만들어야 함 JSP에서는 자바 코드가 들어있는 HTML 페이지를 만들어야 함 서블릿을 사용하는 경우에 비해 사용하기가 상당히 편함 자바 개발자는 서블릿을 만들고 웹 페이지 개발자는 JSP를 만들어서 작업을 분리할 수 있음
EJB RMI만 가지고는 하기 힘든 다양한 서비스를 제공 보조객체 클라이언트 보조객체 클라이언트 객체 엔터프라이즈 빈
지니 (Jini) 어댑티브 디스커버리 (Adaptive discovery) 자가치유 네트워크 (self-healing network) 서비스에서 어떤 인터페이스를 구현했는지만 알면 필요한 서비스를 찾을 수 있음
어댑티브 디스커버리 안녕하세요. 제가 왔어요. 지니 룩업 서비스
scientificCalculator 구현합니다. 등록해주세요. 어댑티브 디스커버리 scientificCalculator 구현합니다. 등록해주세요. 지니 서비스 지니 룩업 서비스
scientificCalculator 구현한 거 있어요? 어댑티브 디스커버리 지니 서비스 지니 룩업 서비스 자바 애플리케이션 scientificCalculator 구현한 거 있어요?
어댑티브 디스커버리 지니 서비스 지니 룩업 서비스 자바 애플리케이션 예, 있습니다. 여기 직렬화된 객체 있어요.
자가치유 네트워크 임차권 여기 있습니다. 잘 갱신해주세요. 지니 서비스 지니 룩업 서비스
자가치유 네트워크 임차권을 갱신하지 않는군. 목록에서 빼야지. 지니 룩업 서비스
범용 서비스 브라우저
범용 서비스 브라우저 서버 서비스 브라우저 Remote Hello 스터브 RMI 레지스트리
범용 서비스 브라우저 서버 서비스 브라우저 getServiceList() getService(svc)
범용 서비스 브라우저 서비스 브라우저
600~607 페이지에 나와있는 코드를 직접 실행해봅시다. 범용 서비스 브라우저 – 클래스/인터페이스 ServiceServer getServicesList() getService() Service getGuiPanel() ServiceServerImpl getServicesList() getService() 600~607 페이지에 나와있는 코드를 직접 실행해봅시다. DiceService getGuiPanel() ServiceBrowser main() DayOfTheWeekService getGuiPanel() MiniMusicService getGuiPanel()
숙제 본문을 꼼꼼하게 읽어봅시다. 본문 및 코드 중간에 있는 ‘연필을 깎으며’ 문제를 모두 해결해봅시다. 모든 코드를 직접 입력해서 실행시켜보고 코드를 다시 한 번 보면서 코드를 다른 사람한테 소개하는 연습을 해 봅시다. API 문서에서 이 장에 나와있는 클래스 및 메소드에 대한 내용을 직접 찾아봅시다.