IBM Korea Skip to main content
       IBM 홈    |  제품 & 서비스  |  고객지원 & 다운로드  |  회원가입  

기업에서의 RMI-IIOP
목 차:
원격 객체 전송
원격 객체의 위치
RMI 대 CORBA
RMI-IIOP 개요
Do-it-yourself RMI-IIOP
Part 1: 인터페이스 정의하기
Part 2: 서버 구축하기
Part 3: 클라이언트 구축하기
Part 4 :예제 실행시키기
RMI-IIOP와 EJB 컴포넌트
결론
참고 자료
필자 소개
기사에 대한 평가
관련 dW 링크:
Enterprise JavaBeans 기초
Enterprise JavaBeans 컴포넌트 배치 및 사용하기
IBM SDKs for Java technology
US 원문 읽기
IIOP상에 RMI 실행시키기

Damian Hagge
소프트웨어 엔지니어, IBM
2002년 3월

RMI와 CORBA는 종종 경쟁 기술로 비춰진다. 둘 다 원격지로 분산된 객체에 투명하게 접근하도록 해주기 때문이다. 그러나 이 두 기술은 실제로는 보완적이다. 각자가 서로의 약점을 해결해 줄 수 있는 강점을 가지고 있기 때문이다. RMI와 CORBA의 결합은 기업용 서버측 자바 개발의 초석이 된 RMI-IIOP를 낳았다. 이 글에서 자바 개발자인 Damian Hagge는 RMI-IIOP에 대해 간단히 소개하고, 간단한 자바 기반의 RMI-IIOP 클라이언트/서버 애플리케이션을 구축하고 실행시키는 방법을 보여준다. RMI가 IIOP에서 얼마나 잘 작동하는지 보기 바란다.

1997년 IBM과 Sun Microsystems는 기업용 애플리케이션 개발 기술로 자바의 발전을 촉진시키기 위해 공동 노력을 시작했다. 특히 두 회사는 자바가 서버측 언어로 어떻게 사용될 수 있는지에 초점을 맞추었고 기존 아키텍처에 통합될 수 있는 기업 레벨의 코드를 만들었다. 필요한 것은 자바의 RMI (Remote Method Invocation)의 적은 자원을 사용하는 기술과 보다 성숙한 CORBA (Common Object Request Broker Architecture) 기술의 강건성을 결합시키는 기업용 전송 기술이었다. 이러한 필요에 의해 RMI-IIOP가 탄생하였는데, RMI-IIOP는 자바가 현재 선두적인 서버측 기업용 개발 언어로 자리매김하는 데 추진제 역할을 하였다.

이 글에서 나는 RMI-IIOP에 대한 기본 사항들을 소개할 것인데, 여러분이 기업용 개발 솔루션에 이 기술을 사용하기 시작하도록 하는 것이 목표이다. 나는 RMI-IIOP가 실제로 무엇인지를 설명하기 위해 CORBA와 RMI에 대해 소개한 일반 자료들에서 발견할 수 없었던 정보를 제공하는 것이 중요하다고 생각한다. CORBA와 RMI의 기본 사항들에 대해 잘 모른다면 이 글을 계속 읽어나가기 전에 몇 가지 소개 자료들을 읽어보기를 권한다. 참고자료에 정선된 글과 교재들이 나와 있다.

RMI-IIOP에 대해 구체적으로 말하기 전에 우리는 CORBA와 RMI가 요청을 정렬시키기 위해 사용하는 메커니즘을 살펴보자. CORBA가 우리의 주된 예가 될 것이다. RMI-IIOP 정렬화가 CORBA 전송 프로토콜 (IIOP)에 기초하고 있기 때문이다. 우리는 요청을 보내고 원격 객체의 위치를 찾고 네트워크 상에서 그 객체를 전송하는 작업에서 전송 프로토콜과 ORB (object request broker)가 수행하는 기본 기능들을 살펴보겠다.

원격 객체 전송

한 CORBA 요청이 정렬되면 그것은 IIOP 프로토콜을 사용하여 수행된다. 간단히 말해, IIOP는 IDL (Interface Definition Language) 생성자의 요소들을 일련의 바이트로 된 표준화된 포맷으로 표시한다. 따라서 한 자바 클라이언트가 CORBA 요청을 C++ 서버에게 보내고 있다고 가정해보자. 클라이언트 애플리케이션은 원격 객체에 대한 참조를 자바 인터페이스 형태로 가지고 있고, 그 인터페이스상에 작업을 호출한다. 보다 자세히 말하면, 인터페이스는 그에 상응하는 작업의 구현을 호출하며, 이러한 구현은 스텁에 위치하고 있을 것이다.(이 스텁은 여러분이 idlj를 이용해 IDL로부터 만들어낼 것이다)

스텁은 메소드 호출을 ORB로 내려보내는데, 이것은 클라이언트 ORB와 서버 ORB의 두 부분으로 구성되어 있다. 클라이언트 ORB의 일은 요청을 특정 위치로 향하는 네트워크에 정렬시키는 것이다. 서버 ORB의 일은 네트워크에서 들어오는 요청을 듣고 이들을 언어 구현이 이해할 수 있는 메소드 호출로 변환하는 것이다. CORBA ORB의 역할에 대한 보다 심도 깊은 설명은 참고자료 부분을 참조한다.

스텁이 메소드 호출을 보낸 후에 클라이언트 ORB는 모든 매개변수를 포함해 작업 수행 요청을 표준화된 바이트 포맷으로 변환하는데, 이 경우에는 IIOP로 변환한다. 그리고 나서 들어올 요청을 위해 대기하고 있는 서버 ORB에게 내트워크를 통해 작업을 보내게 된다. 서버측 ORB는 데이터를 바이트 단위로 읽어 나가고, 그 요청을 C++ 서버 구현에게 의미있는 것으로 변환한다. C++ 서버 메소드는 자신의 역할 (즉 요청된 메소드 호출)을 수행하고, 결과값을 위와 동일한 메커니즘을 사용해 IIOP상의 클라이언트에게 반환할 것이다.

RMI도 요청을 이와 비슷하게 처리하지만, 대신 전송 프로토콜로 JRMP (Java Remote Messaging Protocol)을 사용한다. 그리고 물론 RMI 전송 작업은 자바 객체의 직렬화를 포함한다.

CORBA와 RMI간의 차이
  • CORBA는 IIOP 프로토콜상에서 실행된다; RMI는 JRMP를 사용한다.
  • CORBA는 언어에 독립적이다; RMI는 순수하게 자바 대 자바이다.
  • RMI는 원격 객체의 위치를 찾기 위해 JNDI를 사용한다; CORBA는 CosNaming을 사용한다.
  • RMI는 객체를 직렬화한다; CORBA는 그렇게 하지 않는다.

원격 객체의 위치

CORBA는 원격 객체를 찾기 위해 CosNaming 이름 서비스를 사용한다. CosNaming은 이름 서버가 CORBA 서버 프로세스에 대한 바인딩 (혹은 참조)을 가지도록 하기 위한 프레임워크를 제공한다. CORBA 클라이언트가 어떤 이름의 한 서버 프로세스를 찾기 위해 CosNaming 요청을 이름 서버에게 보내면, 이름 서비스는 그 프로세스에 대한 양방향 객체 참조 (interoperable object reference,IOR)를 반환한다. 그러면 클라이언트는 그 IOR를 사용하여 서버 프로세스와 직접 통신한다.

IOR은 서버의 위치등 서버 프로세스에 대한 정보를 가지고 있다. CosNaming 서비스의 단점 중 하나는 사람이 IOR을 판독할 수 없다는 것이다. 적어도 사이보그 두뇌를 가지지 않은 사람은 말이다. 반면 RMI는 좀 더 사용자에게 친근하다. RMI는 JNDI에서 실행되는 레지스트리 (이름 서비스와 유사)를 사용해 원격 객체를 찾는다. RMI 레지스트리는 원격 객체를 확인하고 위치를 찾기 위해 RefAddr 객체로 구성된 자바 Reference 객체를 사용한다. 이 자바 객체들은 IOR보다 사용자에게 친근하다.

CORBA는 아주 최근에 상호작용 가능한 이름 서비스 (Interoperable Naming Service : INS)를 자신의 객체 위치 스키마에 구체화시켰다. INS는 사람이 읽을 수 있는 URL을 객체 위치로 사용하며 CosNaming 상에서 작동한다. INS는 이름 서비스를 사용하지 않는다. 대신 지정된 URL에 직접 호출을 보낸다. INS에 대한 상세 정보는 참고자료를 참조한다.

RMI 대 CORBA

그렇다면 CORBA와 RMI 중 어떤 것이 나은가? 대답은 여러분이 무엇을 하고 싶은가에 달려 있다. CORBA는 업계 표준의 3세대, 혹은 4세대 프로토콜상에서 작동하는 거대하고 검증된 아키텍처이다. 여러분이 COBA가 제공하는 모든 추가 기능들 (트랜잭션 처리, 보안을 위한 인터셉터, 이벤트 채널등)을 고려한다면 CORBA가 기업 애플리케이션에 대한 답처럼 보일 것이다. CORBA의 큰 결점은 복잡하다는 것이다. 개발자들이 CORBA에 능숙해지려면 보통 아주 힘든 학습 과정을 거쳐야 한다.

반면 RMI는 아주 배우기 쉽다. RMI를 사용해 클라이언트/서버 구현을 생성하고 레지스터리와 원격 객체를 결합시키고 요청을 호출하고 받는 것은 매우 간단하다. RMI는 또한 CORBA보다 훨씬 적은 자원을 사용한다. JRMP가 IIOP보다 상당히 비용이 덜 드는 프로토콜이기 때문이다. 그러나 RMI는 CORBA가 가진 강력한 추가 기능이 없고 순수하게 자바에 기반한 메커니즘이다. 따라서 우리가 실제로 원하는 것은 RMI의 유연성 및 사용의 용이성을 CORBA가 가진 기업 컴퓨팅에 대한 준비성과 결합시킨 것이다. 그렇지 않은가? 이제 RMI-IIOP로 들어가 보자.

왜 RMI-IIOP인가?
  • RMI-IIOP는 CORBA의 강력함을 RMI의 유연성과 결합시킨다.
  • RMI-IIOP는 개발자들이 사용하기 쉽고 대부분의 기업 인프라에 쉽게 통합된다.

RMI-IIOP 개요

RMI-IIOP는 RMI 호출을 거의 수정 없이 IIOP에서 실행시키도록 해준다. RMI-IIOP로 여러분은 직접적인 자바 코드를 작성할 수 있고, 또한 CORBA가 제공하는 풍부한 기업 컴퓨팅 지원 기능을 사용할 수 있다. 더 나아가 코드는 RMI에서든 IIOP에서든 실행될 수 있을만큼 유연하다. 이것은 적은 자원 사용과 유연성이 중요한 문제가 되는 경우에 여러분의 코드를 순수 자바 환경에서 실행시킬 수도 있고, 혹은 최소한의 코드 변경으로 기존의 CORBA 인프라에 통합시킬 수도 있음을 의미한다.

RMI-IIOP의 매우 강력한 기능 중 하나가 RMI 클래스 직렬화의 유연성을 잃지 않으면서 순수 자바 클라이언트/서버 구현을 작성하도록 해준다는 것이다. RMI-IIOP는 자바 직렬화를 오버라이드하고 자바 클래스를 IIOP로 변환하여 네트워크에 실어 내림으로써 이를 가능케 한다. 다른 한 쪽에서는 자바 클래스가 네트워크로부터 IIOP로 읽혀 올려지며, 해당 클래스에 대해 그 멤버들의 값이 전혀 변하지 않은 채 새로운 인스턴스가(reflection을 사용하여) 생성되어진다 - 보시라: 이것이 IIOP상의 자바 직렬화이다.

RMI-IIOP가 투명하게 객체 위치를 찾게 하기 위해 ORB 벤더들은 역사적으로 Java CosNaming service provider (비전문가 용어로는 플러그인)를 사용해 왔다. 플러그인은 JNDI API 하에서 작동하여 CORBA 이름 서비스에 접근한다. 이 글에서는 그 이유를 설명할만큼 여유가 없지만, 이 이름 서비스는 이상적이지 않다. 그 결과 수많은 벤더 -특히 애플리케이션 서버 벤더 -들이 RMI-IIOP에 대해 독자적인 객체 위치 메커니즘을 개발해 왔다.

RMI-IIOP는 또한 자바 CosNaming 서비스에 대한 확장자로 INS를 지원한다. 나는 INS가 향후 객체 위치 기능을 이끌 것이라고 믿기 때문에 우리가 이 글에서 작업할 코드 예제에서 INS를 사용한다.

Note: Sun이 OMG INS 표준을 아직 완전히 컴파일하지 않았고 org.omg.CORBA.ORB 인터페이스에 register_initial_reference를 공개하지 않았기 때문에 이 글에 나온 소스 코드는 Sun JDK와는 작동하지 않을 것이다. 여러분은 IBM Developer Kit for Java technology, version 1.3.1 이상을 사용해야 할 것이다. 그러나 나는 이름 서비스를 사용하는 Sun 호환 예제를 만들었는데, 참고 자료 섹션에서 다운로드받을 수 있다.

Do-it-yourself RMI-IIOP

이야기는 충분히 했으니 이제 코드를 작성해 보자. 다음 섹션에서 우리는 간단한 자바 기반의 클라이언트/서버 RMI-IIOP 애플리케이션을 구축할 것이다. 이 애플리케이션은 세 부분으로 구성되어 있다.: RMI 인터페이스와 서버 애플리케이션 및 클라이언트 애플리케이션이 그것이다. 예제는 IIOP 상에 자바 직렬화 기능을 구현하는데, 여러분은 자바 클래스가 클라이언트에 의해 어떻게 인스턴스화되고, 서버에게 전달되고, 서버에 의해 어떻게 변경되고, 그리고 어떻게 그 변경 사항들이 손상되지 않은 채 클라이언트에게 전달되는지를 볼 수 있을 것이다.

Part 1: 인터페이스 정의하기

RMI-IIOP에서 우리는 RMI나 IDL 중에서 선택해 인터페이스를 정의할 수 있다. 우리는 RMI가 IIOP에서 어떻게 작동하는지를 보고 싶기 때문에 RMI를 사용해 예제 인터페이스를 정의할 것이다. Listing 1은 우리의 간단한 예제에 대한 RMI 인터페이스이다:

Listing 1. RMIInterface.java

/*
 * Remote interface
 */
public interface RMIInterface extends java.rmi.Remote {
    public String hello() throws java.rmi.RemoteException;
    public SerClass alterClass(SerClass classObject) 
       throws java.rmi.RemoteException;
}

RMIInterfacehello() 메소드와 alterClass(SerClass) 메소드를 정의한다. 이 메소드는 Serializable을 구현하는 자바 클래스인 SerClass를 취하고 동일한 유형의 클래스를 반환한다. SerClass는 몇 개의 멤버와 대응하는 getter 메소드를 가진 간단한 클래스이다. Listing 2에 이 메소드가 나와 있다:

Listing 2. SerClass.java

/**
 *  This class is intended to be serialized over RMI-IIOP.
 */
public class SerClass implements java.io.Serializable {
	// members
	private int x;
	private String myString;

	// constructor
	public SerClass(int x, String myString) 
	   throws java.rmi.RemoteException {
		this.x=x;
		this.myString=myString;
	} 
	
	// some accessor methods
	public int getX() {  return x;}
	public void setX(int x) { this.x=x; }
	public String getString() {  return myString;  }
	public void setString(String str) { myString=str; }
}

우리의 간단한 인터페이스는 이것이 전부이다. 이제 서버 클래스를 살펴 보자.

Part 2: 서버 구축하기

우리는 RMIInterface 구현 클래스로 작동하고 우리의 서비스를 구동시킬 주 메소드를 포함하고 있는 서버 클래스 (Server.java) 를 사용할 것이다. Server.javajavax.rmi.PortableRemoteObject를 확장한다. 이런 식으로 Server.java는 자신을 Remote 인터페이스로 ORB에 결합시키고 요청이 있는지 대기하기 위해 필요한 모든 기능을 가지게 된다. Listing 3은 서버용 코드이다:

Listing 3. Server.java

/*
 * Simple server
 */
import java.util.*;
import java.rmi.Remote;
import java.rmi.RemoteException;
import javax.rmi.PortableRemoteObject;
import javax.rmi.CORBA.Tie;
import javax.rmi.CORBA.Util;
import org.omg.PortableServer.POA;
import org.omg.PortableServer.*;
import org.omg.PortableServer.Servant;
import org.omg.CORBA.ORB;

public class Server extends PortableRemoteObject 
    implements RMIInterface {
    // must explicitly create default constructor 
    // to throw RemoteException
    public Server() throws RemoteException {
    }

    // implementation of RMIInterface methods
    public String hello() throws RemoteException {
    	return "Hello there!";
    }

    public SerClass alterClass(SerClass classObject) 
        throws RemoteException {
    	// change the values of SerClass and return it.
	// add 5 to X
    	classObject.setX( 
    	   classObject.getX() + 5 ); 
	// alter the string
    	classObject.setString( 
    	   classObject.getString() + " : I've altered you" ); 
    	return classObject;
    }	

    public static void main(String[] args) {
    	try {
    	    // create the ORB passing in the port to listen on
    	    Properties props = new Properties();
    	    props.put("com.ibm.CORBA.ListenerPort","8080");
    	    ORB orb = ORB.init(args, props);
    
    	    // instantiate the Server
    	    // this will automatically call exportObject(this)
    	    Server s = new Server();
            
    	    // now get the Stub for our server object - 
         // this will be both
    	    // a remote interface and an org.omg.CORBA.Object
    	    Remote r=PortableRemoteObject.toStub(s);        		
    
    	    // register the process under the name 
         // by which it can be found	
    	    ((com.ibm.CORBA.iiop.ORB)orb).
    		register_initial_reference("OurLittleClient",
			(org.omg.CORBA.Object)r);
    
    	    System.out.println("Hello Server waiting...");
    	    // it's that easy - 
	    // we're registered and listening for incoming requests
    	    orb.run();
    	} catch (Exception e) {
    	    e.printStackTrace();
    	}
    }
}

여기에서 무슨 일이 일어났는가?

서버 애플리케이션은 많은 코드를 가지고 있다. 이를 나누어 보자. 우선 위에서 언급한대로 Server 클래스는 RMIInterface를 구현하고 모든 메소드에 대한 구현을 제공한다. 여러분은 코드의 서두에서 RMIInterface의 hello()alterClass(SerClass) 메소드의 구현을 볼 수 있다. hello() 메소드는 간단히 'Hello there"라는 문자열을 반환한다. alterClass(SerClass)메소드는 SerClass 객체를 취해 멤버의 값을 변경한 후 새로운 객체를 반환하는데, 이 모든 작업에 RMI-IIOP를 사용한다.

Server.java의 주 메소드는 ORB를 초기화하고, 8080으로 설정된 com.ibm.CORBA.ListenerPort 특성을 매개변수로써 전달한다. 그러면 ORB는 8080 포트에 요청이 들어옴을 알게 될 것이다. om.ibm.CORBA.ListenerPort는 IBM의 독자적인 특성임에 주의한다. 여러분이 이 코드를 다른 벤더의 ORB에서 실행시키고 싶다면 그 벤더의 문서를 참조하여 적절한 특성을 찾아야 한다. (Sun은 com.sun.CORBA.POA.ORBPersistentServerPort를 사용하지만, 이 특성은 여러분이 POA (portable object adapter)를 사용할 때만 작동한다.)

ORB가 초기화되면 주 메소드는 Server 객체를 인스턴스화한다. 서버 객체는 또한 PortableRemoteObject이기 때문에, 기본 생성자가 자동으로 exportObject(this)를 호출한다. 객체는 이제 원격 호출을 받을 준비가 되었다.

다음에 우리는 객체를 ORB.register_initial_reference(String,orb.omg.CORBA.Object)에 대한 호출에 등록해야 한다. 이제, 우리는 이 객체를 호출을 통해 ORB.register_initial_reference(String,orb.omg.CORBA.Object)에 등록할 필요가 있다. 이를 위해 우리의 서버 객체에 대한 참조를 omg.CORBA.Object로 가지고 있어야 한다. PortableRemoteObject.toStub(s) 호출이 이를 수행하게 되는데, 반환되는 객체가 java.rmi.Remoteorg.omg.CORBA.Object 모두를 구현하기 때문이다.

반환된 org.omg.CORBA.Object 객체는 서버측 ORB에 "OurLittleClinet"로 등록된다. INS 요청이 객체를 찾을 수 있도록 하기 위해 우리는 등록 호출 register_initial_reference을 사용한다. INS 호출이 ORB에 들어 오면 ORB는 요청된 이름 하에 등록된 객체를 찾을 것이다. 우리가 객체를 "OurLittleClient"로 등록했기 때문에 우리는 INS 호출이 "OurLittleClient"를 찾기 위해 우리의 서버 ORB에 들어 올 때 클라이언트가 어떤 객체를 찾고 있는지 알 것이다.

마지막으로, 여러분은 ORB를 com.ibm.CORBA.iiop.ORB로 변환했음을 알아차렸을 것이다. Sun은 아직 org.omg.CORBA.ORB 인터페이스에 register_initial_reference를 공개하지 않았고, IBM SDK도 공개할 수 없기 때문이다. 따라서 우리는 ORB를 IBM ORB로 변환해야 한다. SUN의 OMG 지원이 발전함에 따라 JDK 향후 버전 (1.4.0 이후)에서는 아마도 이러한 변환이 필요 없을 것이다.

이게 전부다. 우리 서버는 이제 들어오는 클라이언트 INS 요청을 기다리고 있다. 그렇다면 클라이언트는 어떠한가?

Part 3: 클라이언트 구축하기

클라이언트 애플리케이션용 코드가 Listing 4에 나와 있다:

Listing 4. Client.java

/*
 * Client application
 */
import javax.rmi.PortableRemoteObject;
import org.omg.CORBA.ORB;

public class Client {
  public static void main(String[] args) {
    try {
      ORB orb = ORB.init(args, null);
    
    	 // here's the URL for the local host
    	 String INSUrl = 
        "corbaloc:iiop:1.2@localhost:8080/OurLittleClient";	 
       
    	 // get the reference to the remote process
    	 org.omg.CORBA.Object objRef=orb.string_to_object(INSUrl);
    	 // narrow it into our RMIInterface
    	 RMIInterface ri = 
  (RMIInterface)PortableRemoteObject.narrow(objRef, RMIInterface.class);
    	
      // call the hello method
    	 System.out.println("received from server: "+ri.hello()+"\n");  
    
      // try RMI serialization
    	 SerClass se = new SerClass(5, "Client string! ");
    	 // pass the class to be altered on the server
    	 // of course behind the scenes this class is being 
      // serialized over IIOP
    	 se = ri.alterClass(se);
    	 // now let's see the result
    	 System.out.println("Serialization results :\n"+
    	    "Integer was 5 now is "+se.getX()+"\n"+
    	    "String was \"Client String! \" 
         now is \""+se.getString()+"\"");   
    	} catch (Exception e) {
    	    e.printStackTrace();
    	}
    }
}

클라이언트 코드를 나누는 방법

클라이언트 코드는 서버 코드보다 다소 간단하다. 우리는 ORB를 초기화하고 string_to_object(String)을 호출하는데, 여기서 string은 우리의 INS URL이다. INS URL을 구성하는 것은 비교적 간단하다. : 먼저 우리가 corbaloc URL (참고 자료)과 IIOP 프로토콜 v.1.2를 사용하고 있음을 지정한다. 다음에 호스트명(www.whatever.com)과 접속할 포트를 추가한다. 마지막으로 우리가 찾고 있는 서비스 이름을 지정한다. 그 결과 corbaloc:iiop:1.2@localhost:8080/OurLittleClient라는 INS URL이 나온다.

우리가 이 URL을 ORB.string_to_object(String)에 전달하면 ORB는 요청된 서비스가 지정된 서버에게 요청을 보낼 것이다. 모든 것이 제대로 작동한다고 가정하면 ORB는 서비스에 대한 객체 참조 (실제로는 IOR)를 돌려 받을 것이다. 그러면 우리는 객체 참조를 우리가 사용할 수 있는 것, 즉 RMIInterface로 좁힌다. 이제 우리는 메소드 호출을 시작할 준비가 되었다.

간단한 hello 메소드 (설명이 필요 없을 것이다.)를 호출한 후 우리는 RMI-IIOP의 직렬화 기능에 대한 탐사를 시작할 수 있다. 우선 직렬화 가능한 자바 클래스인 SerClass를 만들고 그 멤버 변수를 초기화한다. 그리고 IIOP를 통해 서버에게 이 클래스를 적어 내보낼 우리의 메소드로 이 클래스를 보낸다. 서버는 클래스를 읽고 이를 서버측 자바 객체로 재생성하고, 그 멤버 값을 변경한 후 우리 메소드의 반환값으로써 (IIOP를 사용하여) 반환한다. 원격 메소드 호출 후 우리가 재생성된 객체를 받았을 때 우리는 그 멤버가 서버에 의해 실제로 변경되었음을 알 수 있다. IIOP에서의 자바 직렬화는 이처럼 간단하다.

Part 4: 예제 실행시키기

우리가 여기에서 개발한 예제는 IBM Developer Kit for Java technology, version 1.3.1 이상과 함께 실행되어야 함에 주의한다. Sun JDK를 사용하고 싶다면 Sun에 독자적인 소스 코드를 다운받기 바란다. 이 코드는 Sun 1.4.0 JDK 이상에서 실행되어야 한다. 이 소스 코드에는 IBM SDK와 Sun JDK간의 차이를 설명한 readme.txt 파일이 들어 있다. IBM Developer Kit for Java technology는 지금 다운로드받을 수 있다. 무료이다.

예제를 실행시키는 방법은 다음과 같다:

  1. 소스 파일을 다운로드받는다.

  2. javac *.java를 입력하여 모든 파일을 javac로 컴파일한다.

  3. rmic -iiop Server라는 IIOP falg로 서버 클래스에 rmic를 실행시킨다.

  4. 서버를 구동시킨다. : 윈도우에 start java Server를 입력한다.

  5. 클라이언트를 구동시킨다. : 윈도우에 start java Client를 입력한다.

RMI-IIOP와 EJB 컴포넌트에 대한 노트

EJB 2.0 사양에는 EJB 컴포넌트가 RMI와 RMI-IIOP모두에서 실행될 수 있어야 한다고 나와 있다. RMI-IIOP를 EJB 컴포넌트에 대한 전송 프로토콜로 추가하면 대부분 매우 CORBA 집약적인 기존의 기업 인프라에 J2EE 환경을 통합시키는 것을 상당히 도와준다. 그러나 몇 가지 문제도 있다.

간단하게 말하자면 사용자 정의 컴포넌트와 EJB 컴포넌트를 통합하면, 통합되지 않았을 경우 EJB 아키텍처가 요약하여 여러분에게 전달했을 plumbing을 여러분 (개발자)이 다루어야 한다. 아직 이 문제에 대한 간단한 솔루션이 나와 있지 않으며, 앞으로도 힘들 것이다. 웹서비스와 같이 떠오르는 기술들로부터 솔루션이 나올 수 있을 것이지만, 아직은 알려져있지 않다.

결론 : 여기에서 어디로 가야 할 것인가?

이 글이 여러분에게 RMI-IIOP 클라이언트/서버 애플리케이션을 개발하고 실행하는 것이 얼마나 쉬운지를 보여 주었기를 바란다. 우리가 사용한 예제에서 클라이언트와 서버를 순수 CORBA로 바꾸어 활용할 수 있다. 그러나 그렇게 하면 자바 직렬화가 애플리케이션에서 빠질 것이다.

RMI-IIOP를 CORBA 환경에서 사용하는 것을 고려하고 있다면 IDL이 자바에 어떻게 대응되는지, 그리고 자바가 IDL에 어떻게 대응되는지를 보는 것이 도움이 될 것이다. RMI-IIOP를 안전하지 않은 환경 (여러분들의 PC를 이야기하는 것은 아니고)에 배치할 것을 고려하고 있다면 인터셉터나 CORBA 보안 모델과 같은 CORBA 보안 기능과 트랜잭션 처리와 같은 CORBA의 다른 기업용 기능들을 살펴보는 것이 좋을 것이다. RMI-IIOP를 사용하면 CORBA의 풍부한 모든 기능을 이용할 수 있다.

나에게 직접, 혹은 discussion forum을 통해 이 글에 관한 여러분의 의견을 자유롭게 제공하기 바란다. 나는 여러분의 생각에 관심을 가지고 있다.

참고자료

필자소개
Damian Hagge는 IBM의 Hursley Development Laboratories에서 일하고 있다.



이 기사에 대하여 어떻게 생각하십니까?

정말 좋다 (5) 좋다 (4) 그저그렇다 (3) 수정보완이 필요하다(2) 형편없다 (1)

  회사소개  |  개인정보 보호정책  |  법률  |  문의