Java RMI - Naming.Rebind(...)

c1t1z3n

Power Member
Boas

Ando a fazer um trabalho para a universidade... e isto quando andava a fazer os tutorials funcionava, mas agora nem por isso :mad:

Isto primeiro lança o rmiregistry na porta defeito (1099) e depois devia fazer bind da minha aplicaçao "servidor"...
Código:
try {
                    LocateRegistry.createRegistry(1099);
                } catch (RemoteException ex) {
                    Logger.getLogger(wndField.class.getName()).log(Level.SEVERE, null, ex);
                }



try {
                    refField = new FieldImpl(n1, n2, ef, eri, es, ns);
                    Naming.rebind("rmi://localhost:1099/Field", refField);
                    Remote rmt = Naming.lookup("rmi://localhost:1099/Field");

                } catch (RemoteException e) {
                    e.printStackTrace();
                } catch (Exception ex) {
acontece é que ali ao fazer Naming.rebind(...) acontece o seguinte:

Código:
java.rmi.MarshalException: error marshalling arguments; nested exception is: 
        java.io.NotSerializableException: java.awt.image.BufferedImage
        at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
        at java.rmi.Naming.rebind(Naming.java:160)
        at GUI.wndField$frameField.launchField(wndField.java:119)
        at GUI.wndField$frameField$3.actionPerformed(wndField.java:420)
        at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
        at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
        at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
        at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
        at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
        at java.awt.Component.processMouseEvent(Component.java:6216)
        at javax.swing.JComponent.processMouseEvent(JComponent.java:3265)
        at java.awt.Component.processEvent(Component.java:5981)
        at java.awt.Container.processEvent(Container.java:2041)
        at java.awt.Component.dispatchEventImpl(Component.java:4583)
        at java.awt.Container.dispatchEventImpl(Container.java:2099)
        at java.awt.Component.dispatchEvent(Component.java:4413)
        at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4556)
        at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4220)
        at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4150)
        at java.awt.Container.dispatchEventImpl(Container.java:2085)
        at java.awt.Window.dispatchEventImpl(Window.java:2475)
        at java.awt.Component.dispatchEvent(Component.java:4413)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Caused by: java.io.NotSerializableException: java.awt.image.BufferedImage
        at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1156)
        at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509)
        at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1474)
        at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
        at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
        at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
        ... 29 more
alguem tem alguma ideia sobre como por o rebind a funcionar como devia? :P

ja agora, a excepção queixa-se de "NotSerializableException" eu la fiz um implements Serializable na classe que o pedia, e agora ele queixa-se numa classe na qual nao posso mexer (java.awt.image.BufferedImage) será disso?/porquê?

nao sei até que ponto as duvidas serão estupidas ou nao :P mas isto é a primeira vez que mexo em java, de modo que ser noob ja é elogio xD

agradeço qualquer ajuda =)
 
eu nao quero enviar nada xD

eu quero é que o objecto (que por acaso inclui a criaçao duma gui) esteja disponivel por RMI :P

posso tentar mudar a criaçao da GUI da aplicação... mas ainda vai ser complicado... de qualquer maneira, todas as ideias sao bem vindas..

edit:
ja agora, alguem me sabe dizer porque nao funciona o rmic?

Código:
rmic Field.FieldImpl
C:\...\Field\FieldImpl_Stub.java:8: Interface Field.Field. Field of class Field.FieldImpl_Stub not found.
    implements Field.Field
               ^
1 error
 
Última edição:
Serializable

É o seguinte, tudo que seja passado por RMI tem de ser serializable, isto é não só a classe em questão, mas todos os atributos dessa mesma classe.
Isto é, mesmo que tenhas uma classe serializable, mas dentro desta tenhas um atributo de uma classe que não o seja, vai dar esse erro.
Das duas uma, ou tens tudo serializable ou declaras os atributos que não queres passar como transient.
Imagina que tens 2 ou 3 atributos duma classe, mas não são precisos transmitir via RMI, na sua declaração usas a keyword transient.
Isso assegura que essas variáveis não vão ser usadas, logo não há problema que não sejam declaradas.
É claro que se não podes "descartar" esses atributos tens de ter tudo serializável.e
 
passei o uso do BufferedImage para outro lado...
agora queixa-se do PrintWriter.... =(

Acho que tens um problema estrutural (arquitectura) no teu código, e estás a misturar coisas que não deves.

Não me parece logico querer passar por RMI um objecto do tipo PrintWriter :)

Se quiseres dar umas dicas da arquitectura da tua aplicação, talvez te possamos ajudar a melhorar isso..
 
a entrega ja foi, aquilo levou uns bugs, mas foi o que deu para fazer

eu precisava, ou achava que precisava vá, do printwriter ja que os varios clientes do meu servidor têm de, em determinados momentos, mandar escrever no log. claro que provavelmente (uma vez que isto tava a dar barraca) teria de arranjar um metodo alternativo para o fazer.

a arquitectura da aplicaçao, quanto mais tempo eu passava a codar, mais percebia que nao estava adaptada ao que eu queria. Este era o terceiro de um conjunto de tres trabalhos, e a estrutura foi mais ou menos mantida ao longo dos tres, e neste caso nao se adaptava tao bem. Se eu tivesse feito tudo de raiz (e se percebesse melhor o funcionamento de RMI :D ) provavelmente teria corrido melhor... enfim

ainda assim mto obrigado pela ajuda, ja que sempre consegui resolver muitos dos problemas (nao todos... mas paciencia..:D)
 
Só agora vi a tua thread... Mas também me parece um problema de arquitectura. Não podes registar directamente os objectos que queres que os clientes usem, do tipo, se queres que um cliente possa imprimir qualquer coisa no outro lado, não vais passar o printwriter, mas sim uma interface que vai ser chamada e por sua vez chamar o printwriter, ou seja algo deste genero:
cliente -> RMI interface Cliente -> RMI inteface Servidor -> RMI Implementation Servidor -> PrintWriter

E dentro do "RMI Implementation Servidor" fazes o que quiseres: imprimir para o log, interagir com uma BD, fazer um sysout, whatever...

Espero ter ajudado (a perceber, já que o trab já foi :) ), se não era bem esta a tua dúvida paciencia :P
 
Back
Topo