자바 원격 함수 호출
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.
1. 개요
자바 원격 함수 호출(RMI)은 서로 다른 자바 가상 머신(JVM) 상의 객체 메서드를 호출하는 분산 객체 기술이다. 초기에는 자바 전용 프로토콜인 JRMP를 사용했으나, 다양한 언어 및 플랫폼과의 상호 운용성을 위해 CORBA의 IIOP를 채택하여 RMI-IIOP가 개발되었다. RMI는 전송 계층을 숨겨 투명성을 제공하며, Jini와 같은 발전된 버전도 존재한다. RMI는 `java.rmi` 패키지를 통해 API를 제공하며, 클라이언트-서버 프로그램 구현 예시를 통해 사용법을 확인할 수 있다.
더 읽어볼만한 페이지
- 원격 프로시저 호출 - D-Bus
D-Bus는 2002년에 시작된 프로세스 간 통신 시스템으로, 시스템 버스와 세션 버스를 통해 정보 공유, 모듈성, 권한 격리를 제공하며, 일대일 요청-응답 및 발행/구독 통신 방식을 지원한다. - 원격 프로시저 호출 - DCE/RPC
DCE/RPC는 분산 컴퓨팅 환경에서 원격 프로시저 호출을 가능하게 하는 프로토콜로, 오픈 소프트웨어 재단에서 개발되었으며, 다양한 운영체제와 환경에서 사용된다. - 자바 플랫폼 - 블루레이
블루레이 디스크는 DVD 후속 매체로, 청색 레이저를 사용하여 고화질 영상과 음향을 제공하며 HD DVD와의 경쟁 후 고밀도 광디스크 표준으로 자리 잡았으나 스트리밍 서비스 성장으로 녹화용 디스크 생산이 중단되는 추세이다. - 자바 플랫폼 - 자바 플랫폼, 마이크로 에디션
자바 ME는 임베디드 및 모바일 장치에서 자바 앱을 실행하는 플랫폼으로, 피처폰에서 주로 사용되었으며 다양한 프로파일과 에뮬레이터, 개발 도구를 제공하고 JSR을 통해 기능이 확장된다.
자바 원격 함수 호출 | |
---|---|
기본 정보 | |
![]() | |
유형 | API |
개발자 | 썬 마이크로시스템즈 |
첫 출시 | 1997년 |
최신 버전 | Java SE 17 (2021년 9월 14일) Java SE 18 (2022년 3월 22일) |
상태 | 활성 |
운영체제 | 크로스 플랫폼 |
라이선스 | 썬 마이크로시스템즈 라이선스 |
기술 정보 | |
프로그래밍 언어 | 자바 |
플랫폼 | 자바 VM |
프로토콜 | JRMP, IIOP (선택 사항) |
외부 링크 | |
웹사이트 | 공식 웹사이트 |
2. 역사
2. 1. JRMP (Java Remote Method Protocol)
자바 원격 함수 호출 (RMI)는 서로 다른 자바 가상 머신(JVM) 상에 있는 객체의 메서드를 호출하는 구조(분산 객체 기술)이다. RMI는 전송 계층 등을 보이지 않게 하는 투명성을 제공하며, 소켓을 통한 통신을 사용한다.초기 RMI 구현 방식인 JRMP (Java Remote Method Protocol)는 자바 가상 머신(JVM) 간의 통신만 지원하는 자바 전용 프로토콜이었다. 이후 비 JVM 환경에서의 코드 실행을 지원하기 위해 CORBA (Common Object Request Broker Architecture)가 개발되었다.
2. 2. CORBA (Common Object Request Broker Architecture)
JVM 환경 밖에서도 운행시키기 위해 CORBA (Common Object Request Broker Architecture)가 개발되었다.2. 3. RMI-IIOP
RMI는 초기에는 자바만을 위한 프로토콜인 JRMP (Java Remote Method Protocol)를 사용했다. 이후 다양한 언어 및 플랫폼과의 상호 운용성을 제공하기 위해 CORBA (Common Object Request Broker Architecture)의 IIOP를 채택하여 RMI-IIOP가 개발되었다. RMI-IIOP는 JRMP 구현과 그 인터페이스가 완전히 동일하지는 않다.2. 4. Jini
지니(Jini)는 자바에서 더 발전된 버전의 RMI를 제공한다. 이는 유사하게 작동하지만, 분산 객체 애플리케이션을 위한 더 발전된 보안, 객체 발견 기능 및 기타 메커니즘을 제공한다.[1]3. 특징
3. 1. 분산 객체 기술
RMI는 서로 다른 자바 가상 머신에 있는 객체의 메서드를 호출하는 구조(분산 객체 기술)이다. 전송 계층 등을 보이지 않게 하여 투명성을 보장한다.RMI의 API에는 두 가지 공통된 구현이 있다. 본래의 구현은 자바 가상 머신에 의존하며, 하나의 JVM에서 다른 JVM으로 호출하는 것만 지원한다. 이 프로토콜은 JRMP(Java Remote Method Protocol)라고 알려져 있다. 비 JVM 컨텍스트에서의 코드 실행을 지원하기 위해 CORBA(Common Object Request Broker Architecture) 대응이 나중에 개발되었다.
RMI-IIOP는 RMI 인터페이스가 CORBA 구현 지원 기능의 많은 부분을 대표한다는 것을 의미한다. 본래의 RMI API는 HTTP 전송과 같은 다른 구현을 어느 정도 개괄했으며, CORBA 대응으로 값 전달 기능을 추가하고 RMI 인터페이스를 지원했다. RMI-IIOP와 JRMP 구현은 해당 인터페이스 내에서 완전히 동일하지 않다.
RMI 패키지 이름은 `java.rmi`이다.
3. 2. 전송 계층 은폐
3. 3. 투명성
4. 구현
4. 1. 일반적인 코드 (Generalized code)
RMI API의 프로그래머들은 원래 HTTP 전송과 같은 다양한 구현을 지원하기 위해 코드를 다소 일반화했다. 또한 RMI 인터페이스와의 호환성을 위해 CORBA에 "값에 의한 호출" 인수를 전달하는 기능이 추가되었다. 그럼에도 불구하고, RMI-IIOP와 JRMP 구현은 완전히 동일한 인터페이스를 가지고 있지 않다.RMI 기능은 `java.rmi` 패키지에 있으며, Sun의 구현의 대부분은 `sun.rmi` 패키지에 있다. Java 5.0 이전 버전에서는 개발자가 `'''rmic'''`을 사용하여 RMI 스텁을 별도의 컴파일 단계로 컴파일해야 했지만, Java 5.0 이상 버전에서는 이 단계가 더 이상 필요하지 않다.
4. 2. 인터페이스
4. 3. 스텁(Stub) 컴파일
5. 예제
다음은 메시지를 표시하는 RMI를 사용하여 간단한 클라이언트-서버 프로그램을 구현한다.
=== RmiServerIntf 인터페이스 ===
`RmiServerIntf` 인터페이스는 클라이언트에서 사용하고 서버에서 구현하는 인터페이스를 정의한다. 이 인터페이스는 `java.rmi.Remote`를 확장하며, `getMessage()` 메서드를 정의하고 있다.
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface RmiServerIntf extends Remote {
String getMessage() throws RemoteException;
}
=== RmiServer 클래스 ===
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.registry.*;
public class RmiServer extends UnicastRemoteObject implements RmiServerIntf {
public static final String MESSAGE = "Hello World";
public RmiServer() throws RemoteException {
super(0); // 'rmic' 단계를 피하기 위해 필요하다.
}
@Override
public String getMessage() {
return MESSAGE;
}
public static void main(String args[]) throws Exception {
System.out.println("RMI 서버 시작");
try { // 레지스트리 생성을 위한 특수 예외 처리
LocateRegistry.createRegistry(1099);
System.out.println("java RMI 레지스트리가 생성되었습니다.");
} catch (RemoteException e) {
// 아무것도 하지 않음, 오류는 레지스트리가 이미 존재함을 의미
System.out.println("java RMI 레지스트리가 이미 존재합니다.");
}
// RmiServer 인스턴스화
RmiServer server = new RmiServer();
// 이 객체 인스턴스를 "RmiServer"라는 이름에 바인딩
Naming.rebind("//localhost/RmiServer", server);
System.out.println("PeerServer가 레지스트리에 바인딩되었습니다");
}
}
`RmiServer` 클래스는 `RmiServerIntf` 인터페이스를 구현하며, RMI 요청을 수신하고 클라이언트가 원격 메서드를 호출하는 데 사용된다. 이 클래스는 `UnicastRemoteObject`를 상속하여 원격 객체로 동작한다. `MESSAGE` 상수는 "Hello World" 문자열을 저장하며, `getMessage()` 메서드는 이 상수를 반환한다.
`main` 메서드는 RMI 서버를 시작하는 역할을 한다. 먼저, `LocateRegistry.createRegistry(1099)`를 호출하여 RMI 레지스트리를 생성하거나, 이미 존재하는 경우 기존 레지스트리를 사용한다. 그런 다음, `RmiServer` 객체를 생성하고 `Naming.rebind`를 사용하여 "//localhost/RmiServer"라는 이름으로 레지스트리에 바인딩한다.
J2SE 버전 5.0부터 동적으로 생성된 stub 파일에 대한 지원이 추가되어 `rmic`를 사용하지 않고도 원격 객체를 내보낼 수 있게 되었다. `RmiServer` 생성자에서 `super(0)` 호출은 이러한 동적 stub 생성을 가능하게 한다.
=== RmiClient 클래스 ===
import java.rmi.Naming;
public class RmiClient {
public static void main(String args[]) throws Exception {
RmiServerIntf server = (RmiServerIntf)Naming.lookup("//localhost/RmiServer");
System.out.println(server.getMessage());
}
}
`RmiClient` 클래스는 서버에 있는 원격 객체에 대한 참조(프록시)를 가져와서 해당 메서드를 호출하여 메시지를 가져온다.[2] 서버 객체가 `java.rmi.Remote` 대신 `java.io.Serializable`을 구현한 경우 직렬화되어 값으로 클라이언트에 전달된다.[2]
5. 1. RmiServerIntf 인터페이스
`RmiServerIntf` 인터페이스는 클라이언트에서 사용하고 서버에서 구현하는 인터페이스를 정의한다. 이 인터페이스는 `java.rmi.Remote`를 확장하며, `getMessage()` 메서드를 정의하고 있다.```java
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface RmiServerIntf extends Remote {
String getMessage() throws RemoteException;
}
5. 2. RmiServer 클래스
javaimport java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.registry.*;
public class RmiServer extends UnicastRemoteObject implements RmiServerIntf {
public static final String MESSAGE = "Hello World";
public RmiServer() throws RemoteException {
super(0); // 'rmic' 단계를 피하기 위해 필요하다.
}
@Override
public String getMessage() {
return MESSAGE;
}
public static void main(String args[]) throws Exception {
System.out.println("RMI 서버 시작");
try { // 레지스트리 생성을 위한 특수 예외 처리
LocateRegistry.createRegistry(1099);
System.out.println("java RMI 레지스트리가 생성되었습니다.");
} catch (RemoteException e) {
// 아무것도 하지 않음, 오류는 레지스트리가 이미 존재함을 의미
System.out.println("java RMI 레지스트리가 이미 존재합니다.");
}
// RmiServer 인스턴스화
RmiServer server = new RmiServer();
// 이 객체 인스턴스를 "RmiServer"라는 이름에 바인딩
Naming.rebind("//localhost/RmiServer", server);
System.out.println("PeerServer가 레지스트리에 바인딩되었습니다");
}
}
```
`RmiServer` 클래스는 `RmiServerIntf` 인터페이스를 구현하며, RMI 요청을 수신하고 클라이언트가 원격 메서드를 호출하는 데 사용된다. 이 클래스는 `UnicastRemoteObject`를 상속하여 원격 객체로 동작한다. `MESSAGE` 상수는 "Hello World" 문자열을 저장하며, `getMessage()` 메서드는 이 상수를 반환한다.
`main` 메서드는 RMI 서버를 시작하는 역할을 한다. 먼저, `LocateRegistry.createRegistry(1099)`를 호출하여 RMI 레지스트리를 생성하거나, 이미 존재하는 경우 기존 레지스트리를 사용한다. 그런 다음, `RmiServer` 객체를 생성하고 `Naming.rebind`를 사용하여 "//localhost/RmiServer"라는 이름으로 레지스트리에 바인딩한다.
J2SE 버전 5.0부터 동적으로 생성된 stub 파일에 대한 지원이 추가되어 `rmic`를 사용하지 않고도 원격 객체를 내보낼 수 있게 되었다. `RmiServer` 생성자에서 `super(0)` 호출은 이러한 동적 stub 생성을 가능하게 한다.
5. 3. RmiClient 클래스
javaimport java.rmi.Naming;
public class RmiClient {
public static void main(String args[]) throws Exception {
RmiServerIntf server = (RmiServerIntf)Naming.lookup("//localhost/RmiServer");
System.out.println(server.getMessage());
}
}
```
`RmiClient` 클래스는 서버에 있는 원격 객체에 대한 참조(프록시)를 가져와서 해당 메서드를 호출하여 메시지를 가져온다.[2] 서버 객체가 `java.rmi.Remote` 대신 `java.io.Serializable`을 구현한 경우 직렬화되어 값으로 클라이언트에 전달된다.[2]
6. 한국에서의 활용
6. 1. 전자정부 프레임워크
6. 2. 기업 환경
6. 3. 기타 응용 분야
참조
[1]
서적
From P2P to Web Services and Grids : Peers in a Client/Server World
https://archive.org/[...]
Springer-Verlag
[2]
웹사이트
Get smart with proxies and RMI
https://www.infoworl[...]
2000-11-10
[3]
웹사이트
Java RMI Release Notes
http://docs.oracle.c[...]
Oracle
2012-05-09
[4]
문서
オブジェクト指向と組み合わさったRPC (Remote Procedure Call)
본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.
문의하기 : help@durumis.com