# Objetos Distribuídos com RMI

O RMI é uma extensão de software à máquina virtual Java remota (JVM) que permite o envio de mensagens para objetos gerenciados por outra JVM. O RMI propicia uma implementação natural do sistema distribuído em um ambiente Orientados a Objeto.

Objetos de uma determinada máquina poderão enviar mensagens através da rede para objetos presentes em outra máquina.

![RMI](/files/-MIyvgW3huUKhpGC0JWQ)

**Implementação da Tecnologia**

A partir deste momento vamos chamar de “receptor” ao local onde está o objeto que recebe as mensagens remotas e “transmissor” ao local de onde partem as mensagens remotas.

Quando pensamos em uma aplicação cliente-servidor, é comum que no programa servidor haja objetos receptores. Entretanto, é possível que haja uma situação em que objetos do programa cliente também sejam receptores; ou seja, que recebam mensagens vindas do programa servidor.

Assim, a especificação destes passos se refere aos objetos que recebem as mensagens remotas; estes podem estar no programa servidor ou no programa cliente.

Para cada classe que receber mensagens remotas (receptor), criar uma interface que contenha a especificação destes métodos.

A interface deverá ser especialização da interface **Remote**.

Os métodos deverão indicar que **throws RemoteException** (ou seja, podem disparar a exceção **RemoteException**).

**Aplicação Servidor**

Na aplicação servidor defino uma interface estendendo a classe **Remote** do pacote **java.rmi.\***.

```java
package br.com.rmi.control;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface IRmiServidorExemplo extends Remote{

	public String exibirMensagem(String txt) throws RemoteException;
	public Double somar(Double x, Double y) throws RemoteException;

}
```

Logo após crio a classe com a implementação dos métodos de nossa aplicação servidora. A Classe de Implementação dos métodos deve estender **UnicastRemoteObject** e implementar a interface do Servidor.

```java
package br.com.rmi.control;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

@SuppressWarnings("serial")
public class RmiServidorExemplo extends UnicastRemoteObject implements IRmiServidorExemplo{

	protected RmiServidorExemplo() throws RemoteException {
		super();

	}

	@Override
	public String exibirMensagem(String txt) throws RemoteException {
		return "Retorno RMI : "+ txt;
	}
	@Override
	public Double somar(Double x, Double y) throws RemoteException {		
		return x+y;
	}

}
```

Por fim implementamos a classe responsável por publicar o Servidor RMI.

```java
package br.com.rmi.control;

import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;

public class RmiServidor {

	public static void main(String[] args) throws Exception{

		// PORTA PADRÃO DO RMI 1099
		LocateRegistry.createRegistry(1099);

		// Instancia o Objeto do Servidor Remoto
		RmiServidorExemplo serv = new RmiServidorExemplo();

                // Vincula um nome para o objeto Remoto
		Naming.bind("RmiServidor", serv);
		System.out.println("RmiServidor Conectado !!!");
	}
}
```

&#x20;**Aplicação Cliente**

Na aplicação cliente uso a mesma interface definida na aplicação servidor para estabelecer um contrato de comunicação entre as duas partes.

```java
package br.com.rmi.control;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface IRmiServidorExemplo extends Remote{

	public String exibirMensagem(String txt) throws RemoteException;
	public Double somar(Double x, Double y) throws RemoteException;

}
```

Por fim acesso a aplicação rmi através da Url: *rmi://localhost/RmiServidor*, onde RmiServidor foi o nome vinculado ao objeto Remoto, e assim consigo acessar aos métodos do meu objeto remoto.

```java
package br.com.rmi.view;
import java.rmi.Naming;
import br.com.rmi.control.IRmiServidorExemplo;

public class ProgramaClienteRMI {

public static void main(String[] args) throws Exception{

		String urlServidor = "rmi://localhost/RmiServidor";
		IRmiServidorExemplo serv = (IRmiServidorExemplo)Naming.lookup(urlServidor);

		System.out.println(serv.exibirMensagem("Olá Mundo RMI !!!"));
		System.out.println(serv.somar(20.89, 38.25));								

	}
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://pauloricmarinho.gitbook.io/desenvolvimento/java/objetos-distribuidos-com-rmi.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
