Porque não implementaram no RMI um modo de tratamento a referências?

No RMI é preciso definir uma interface para a comunicação, caso sejam passados objetos eles tem de implementar serializable, o problemas é que uma vez que esse objetos são passados são modificados localmente e nenhuma alteração ocorre no servidor até que estes objetos modificados sejam setados no servidor.
A dúvida é porque o RMI não implementou um tratamento para que a modificação em objetos passados de maneira distribuída refletisse devidas modificações no servidor ou a execução de chamas remotas?
É preciso fazer a vinculação e pesquisa para todos objetos distribuídos até mesmo os passados por referência!?

Mas, java não tem apenas passagem por valor?

Isso para tipos primitivos, instancias de classes são referências a objetos (implicitamente), a passagem de uma instância não é feita por valor.

Vou devolver a pergunta a você.

Se você fosse implementar o tratamento a referências, como é que você poderia fazer isso?

(Dica: veja como foi implementado o tratamento de referências no ObjectInputStream/ObjectOutputStream, e veja se isso é aplicável ao RMI, que usa extensivamente o conceito de serialização de objetos.
Vai ver que isso não é trivial de fazer e não será possível para muitos casos de uso.
Em vez de prometer algo que não é possível em todos os casos, e que acaba tendo comportamentos distintos do realmente esperado, acho que o pessoal que definiu o RMI preferiu um comportamento previsível e fácil de entender.)

Isso para tipos primitivos, instancias de classes são referências a objetos (implicitamente), a passagem de uma instância não é feita por valor.[/quote]

Não, em Java todas as passagens são por valor. Um método que recebe um objeto não recebe a referência ao objeto, recebe uma cópia da referência por valor.

Perdão se não consegui me expressar, quero dizer o seguinte:

[code]/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.
    */
    package test;

class Person {
private String name;
//…
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
//…
}

class SimplePersonFactory {
public Person person;

public SimplePersonFactory() {
    person = new Person();
}

public Person getPerson() {
    return person;
}

}

/**
*

  • @author david
    */
    public class Test {

    /**

    • @param args the command line arguments
      */
      public static void main(String[] args) {
      SimplePersonFactory factory = new SimplePersonFactory();

      Person person = factory.getPerson();

      person.setName(“david”);

      person = factory.getPerson();

      System.out.println(person.getName());
      }
      }[/code]

Saída:

david

As alterações no objeto são refletidas, já que não há realização de cópia do objeto como um todo, apenas cópia da referência a memória.

ok, no java tudo é objeto, mas as instâncias de objetos nada mais são que referências a endereços de memória.

[code]public class Test {

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    SimplePersonFactory factory = new SimplePersonFactory();
    
    Person person = factory.getPerson();
    
    System.out.println(person);
    
    person = factory.getPerson();
    
    System.out.println(person);
}

}[/code]

Saída:

test.Person@1b4920f8 test.Person@1b4920f8
Emfim isso não é tratado com o RMI, porque provavelmente o rmi realiza uma cópia do contexto do objeto como um todo, o que é natural, mas porque não foi implementado um tratamento?

Uma tentativa de implementar o exemplo acima com um objeto remoto não funciona como seria o esperado localmente.

ps.: passagens por valor conceitualmente são cópias completas de contexto (trata-se da criação de uma nova instância idêntica, as alterações em um clone não deve afetar sua fonte), passagens por referência são passagens de apontadores, endereços, label de memória, por fim até mesmo em linguages como C as passagem por referencia são mascaradas com o uso de passagens por valor de ponteiros, isso não as classifica como passagem por valor, continuam sendo passagens por referência com recuso de apontadores de memória.

Não! Ainda é passagem por valor. Se o Java passasse objetos por referência, você poderia usar o operador “=” para alterá-lo (a famosa funçao “swap” de variáveis, por exemplo). A complicação vem de frases como “No Java, os tipos primitivos são passados por valor e os objetos, por referência!”. No caso dos objetos, suas referências são passadas por valor e isso é bem claro na especificação da linguagem:

Não é possivel fazer isso e não faz sentido fazer isso tbm.

O Objeto é serializado, um processo custoso, se a toda modificação de valor de objeto tivesse que atualizar o valor no outro lado RMI ia virar uma carroça. Imagine a mesma coisa com um banco de dados, qualquer modificação no objeto criar uma transação e comitar.

[quote=mcarabolante]Não é possivel fazer isso e não faz sentido fazer isso tbm.

O Objeto é serializado, um processo custoso, se a toda modificação de valor de objeto tivesse que atualizar o valor no outro lado RMI ia virar uma carroça. Imagine a mesma coisa com um banco de dados, qualquer modificação no objeto criar uma transação e comitar.[/quote]

Existem até padrões de projeto justamente para se lidar com isso e diminuir o overhead. Impossível eu acho que não é o caso, mas é completamente desnecessário em quase todos os casos porque você acaba trazendo mais problemas do que resolvendo os que precisa pra manter uma solução dessas.

[quote=mcarabolante]Não é possivel fazer isso e não faz sentido fazer isso tbm.

O Objeto é serializado, um processo custoso, se a toda modificação de valor de objeto tivesse que atualizar o valor no outro lado RMI ia virar uma carroça. Imagine a mesma coisa com um banco de dados, qualquer modificação no objeto criar uma transação e comitar.[/quote]

Se fosse o GUJ Respostas eu iria botar um +1 nessa resposta. É realmente isso que eu queria dizer, mas não sabia como :slight_smile:

Não! Ainda é passagem por valor. Se o Java passasse objetos por referência, você poderia usar o operador “=” para alterá-lo (a famosa funçao “swap” de variáveis, por exemplo). A complicação vem de frases como “No Java, os tipos primitivos são passados por valor e os objetos, por referência!”. No caso dos objetos, suas referências são passadas por valor e isso é bem claro na especificação da linguagem:

Muito Obrigado, realmente após a sua afirmação e a leitura da especificação, consegui clarear o conceito, a passagem é feita por valor, no caso a referência é passada por valor, assim conseguimos o mesmo comportamento de uma passagem por referência. :slight_smile:

[quote=Ataxexe][quote=mcarabolante]Não é possivel fazer isso e não faz sentido fazer isso tbm.

O Objeto é serializado, um processo custoso, se a toda modificação de valor de objeto tivesse que atualizar o valor no outro lado RMI ia virar uma carroça. Imagine a mesma coisa com um banco de dados, qualquer modificação no objeto criar uma transação e comitar.[/quote]

Existem até padrões de projeto justamente para se lidar com isso e diminuir o overhead. Impossível eu acho que não é o caso, mas é completamente desnecessário em quase todos os casos porque você acaba trazendo mais problemas do que resolvendo os que precisa pra manter uma solução dessas.[/quote]

Sim pelo que conheço da construção de compiladores e interpretadores é sim algo possível e relativamente simples, o que me preocupa é a afirmação “um objeto distribuído pode ser manipulado como se a chamada a seus métodos fossem locais”, creio que isso deve se referir a sintaxe utilizada, pois como no caso que tento compreender o comportamento não é o mesmo que uma instância local, realmente ha um custo associado a abordagem que eu esperava o que poderia ter algum tratamento, como por exemplo, objetos vinculados (no servidor de registros do rmi) terem passagem da referência tratada já que o recurso já está sendo compartilhado de forma distribuída, o usuário concorda com os custos associados ao acesso a um objeto distribuído.

[quote=entanglement]Vou devolver a pergunta a você.

Se você fosse implementar o tratamento a referências, como é que você poderia fazer isso?

(Dica: veja como foi implementado o tratamento de referências no ObjectInputStream/ObjectOutputStream, e veja se isso é aplicável ao RMI, que usa extensivamente o conceito de serialização de objetos.
Vai ver que isso não é trivial de fazer e não será possível para muitos casos de uso.
Em vez de prometer algo que não é possível em todos os casos, e que acaba tendo comportamentos distintos do realmente esperado, acho que o pessoal que definiu o RMI preferiu um comportamento previsível e fácil de entender.)[/quote]

Apenas para facilitar o entendimento, pode citar um caso de uso onde tal tratamento é impossível?
Quanto aos custos de serialização de objetos, não deveria ser uma escolha a nível de projeto do usuário final, se algo é viável ou não aos seus requisitos?

Como exemplo a uma adaptação trivial, os objetos passados não poderiam ter uma interface e vinculação como a dos objetos distribuídos explicitamente pelo usuário?

Você deve estar falando de Enterprise Java Beans.