Win a copy of The Little Book of Impediments (e-book only) this week in the Agile and Other Processes forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Can't get MVC through RMI

 
Rikardo Alvarez
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello there !!

Here is my story... In the server side, i have published succesfully via RMI a Model implementation with a List of UpdatableObjects (They are JFrames). Whenever a new JFrame (or UpdatableObject i may say) is created, i want it to get registered on the model. So i take my quite brand new JFrame, and the model instance i get from the RMI registry in the client side, and i try to add the frame to the model with no success at all.

The exception that i get, complains about using a GroupLayout... it says that is not serializable!!

I use the GroupLayout in order to organize the components on my JFrames... there's no crime about that. But, in an effort to make it Serializable, i use my own Serializable-GroupLayot version (A created a new class that implements Serializable and extends GroupLayout... that's all).

Well... the complains continues.... here's what it says:


RemoteException occurred in server thread; nested exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.io.InvalidClassException: suncertify.gui.MyGroupLayout; suncertify.gui.MyGroupLayout; no valid constructor
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.io.InvalidClassException: suncertify.gui.MyGroupLayout; suncertify.gui.MyGroupLayout; no valid constructor
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:336)
at sun.rmi.transport.Transport$1.run(Transport.java:159)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:155)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:255)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:233)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:142)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:178)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:132)
at $Proxy1.addChangeListener(Unknown Source)
at suncertify.gui.factory.FrameGUIFactory.createFrameGUI(FrameGUIFactory.java:72)
at suncertify.network.ServerProxy.createFrameGUI(ServerProxy.java:177)
at suncertify.gui.MainGUI$ClickHandler.actionPerformed(MainGUI.java:195)
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.AbstractButton.doClick(AbstractButton.java:357)
at javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:809)
at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(BasicMenuItemUI.java:850)
at java.awt.Component.processMouseEvent(Component.java:6267)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
at java.awt.Component.processEvent(Component.java:6032)
at java.awt.Container.processEvent(Container.java:2041)
at java.awt.Component.dispatchEventImpl(Component.java:4630)
at java.awt.Container.dispatchEventImpl(Container.java:2099)
at java.awt.Component.dispatchEvent(Component.java:4460)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4577)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4238)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
at java.awt.Container.dispatchEventImpl(Container.java:2085)
at java.awt.Window.dispatchEventImpl(Window.java:2478)
at java.awt.Component.dispatchEvent(Component.java:4460)
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)


Are you kidding me ???... "no valid constructor"??? what is this all about ???... can somebody tell me??

Please somebody help me, i'm so close to hang up myself !!
 
Matthew Brown
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you have a serializable class with a non-serializable parent class, then that parent class needs to have a no-argument constructor, as it will get called during the deserialization process. GroupLayout doesn't have one. So you can't make it serializable by subclassing. You're going to need a different mechanism.

It also strikes me as very strange, though, trying to pass presentation components through a business interface.

 
Roberto Perillo
Bartender
Posts: 2271
3
Eclipse IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Howdy, Rikardo. Welcome to JavaRanch!!!

In the server side, i have published succesfully via RMI a Model implementation with a List of UpdatableObjects (They are JFrames).


Well champ, I don't get why you are doing this... your server doesn't have to have references to any JFrame. It just has to expose methods that allow the client side to do its job. For instance, if you want to have a thin client, you'll have methods like bookRoom() and search(), and if you have a thick client, then you'll have methods like lock(), update(), unlock()...

I think you want to do this because you want to update all clients with new information when one client books a room, right? Well, if that's the case, that's an example of something that doesn't have to be done. Of course, you'll may add an entry in your choices.txt file, saying that your clients do not observe the server because it wasn't required.
 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Like Roberto already pointed out: I can not think of any reason why you would send your client through RMI to your server. Your client is your client, only data transfer (or value) objects should travel from client to server and vice versa.
 
Rikardo Alvarez
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the responses you guys...

Well... i feel i'm doing something i should not be doing. Passing Views references through the server, it feels to be wrong. But how can i update them, accordingo to changes received by another client?.

Independently, of if it should be done or not in order to accomplish the assignment (I'll re-check tonight my spec), i wonder... how to accomplish that goal?... it shouldn't be so damn difficult to implement, don't you think ?

...

 
Roberto Perillo
Bartender
Posts: 2271
3
Eclipse IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Howdy, Rikardo!

Well... i feel i'm doing something i should not be doing. Passing Views references through the server, it feels to be wrong. But how can i update them, accordingo to changes received by another client?


Well champ, I strongly advise you not to do it. Because updating clients with new data is not required.

Independently, of if it should be done or not in order to accomplish the assignment (I'll re-check tonight my spec), i wonder... how to accomplish that goal?... it shouldn't be so damn difficult to implement, don't you think ?


Well, you are right. Please take a look at the Observer pattern. It proposes a structure where you have something that is observed and has observers registered in it, and when the state of the observed object changes, you notify all observers so they can do whatever they have to do.
 
Rikardo Alvarez
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ohh thanks a lot Roberto, that link help me a lot. Though i was familiarized with the Observer Pattern i didn't know about the existence of the Observer and Observable interface/class.

I finally made a kind of duplex Observer implementation (a local observer implementation, and a remote one)... may be i patent it someday !!

... About the reqs... you're right, that kind of things are not required, but i'm so into this, that can't retreat (or don't want to?)

Now is about tests, concurrency and stuff (is there some advices for my tests?), and complete the documentation in order to submit it !!... I finally see the light at the end of the tunnel !!

Thank you again !!
 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rikardo Alvarez wrote:Now is about tests, concurrency and stuff (is there some advices for my tests?)

To test concurrency, you'll have Roberto's Data Class Test (a link is provided in the ScjdFaq). And you can create a JUnit test to have full test coverage for the most important classes (Data class, business service implementation classes,...). That's what I did
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic