wood burning stoves 2.0*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes java.rmi.NoSuchObjectException Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "java.rmi.NoSuchObjectException" Watch "java.rmi.NoSuchObjectException" New topic
Author

java.rmi.NoSuchObjectException

Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5266
    
  13

Hi all,

I finished the coding part this weekend, big

I started testing my final application and the standalone reacts well, but with my test of the RMI i experienced something weird.

I start my RMI server, give settings and start the server. It runs fine. On another pc (in the same network) i start the client in networked mode, give the correct connection settings and the application starts without any error. I try to find some rooms and application behaves as expected. so far so good.

If i wait for an hour and then i start my client application again. It is started, so the rmi registry is accessible and i'm able to get a proxy (otherwise it would not start) but when i try to search for rooms, i get the following stacktrace:


Anyone experienced this behavior and how did you cope with it?

Kind regards,
Roel


SCJA, SCJP (1.4 | 5.0 | 6.0), SCJD
http://www.javaroe.be/
K. Tsang
Bartender

Joined: Sep 13, 2007
Posts: 2409
    
    7

Hi Roel, you may want to check this thread


K. Tsang JavaRanch SCJP5 SCJD/OCM-JD OCPJP7 OCPWCD5
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5266
    
  13

I found this thread too, but i don't restart my server with another port number. Just trying to access my server a 2nd time.

I googled also around a bit about and found this thread on the java forum. and the cause + solution would be:

probably the server has collected (gc) the object that it has bound to the registry.
Maybe holding a strong reference to the object in the server app's main (or in a static variable) will help.


I'm a bit confused that i seem to be the only one with this exception. did you guys test it like this and how is your server exposed with rmi. my code goes as follows. In a seperate class, with 1 static register method i do the following:
- create service
- create stub
- create RMI-registry on the given port
- register stub on the RMI-registry

all variables are just local ones.

Regards,
Roel
K. Tsang
Bartender

Joined: Sep 13, 2007
Posts: 2409
    
    7

If you get this WITHOUT running client code, how do you start your server? If you get this in client code, how does the client code connect to the RMI server?

According to your brief error, it looks like something to do with not able to get data for the JTable. Do you cache your data in some collection for output? And when something changes or get updated, you can't update your cache due to that object is GCed - if so, shouldn't you "new" object and replace that object in the cache...

Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5266
    
  13

This is
- start server on pcA
- enter db-location + port (19791) and click start-button
- server is up and running on pcA

- start client on pcB (same network as pcA)
- enter ip pcA + port (19791) and click connect
- client application starts and main window is loaded
- i press search-button and my list of hotel rooms is loaded into my JTable
- close application
- go watch Match of the Day on television
- start client on pcB (same network as pcA)
- enter ip pcA + port (19791) and click connect
- client application starts and main window is loaded
- when i press search-button the exception in the 1st thread is thrown

client and server are created just like in this Getting Started Using JavaTM RMI tutorial, so no rocket science there. I'm able to get a stub in my client, but when i invoke a method on it, like searchRooms it throws the error
K. Tsang
Bartender

Joined: Sep 13, 2007
Posts: 2409
    
    7

Interesting. Have you tried running clients and server on the same machine and get this exception? From the RMI specs page I believe you are experiencing the problem of the below quote from that page:

Note that if a network partition exists between a client and a remote server object, it is possible that premature collection of the remote object will occur (since the transport might believe that the client crashed). Because of the possibility of premature collection, remote references cannot guarantee referential integrity; in other words, it is always possible that a remote reference may in fact not refer to an existing object. An attempt to use such a reference will generate a RemoteException which must be handled by the application.


IMO, if it is really GC prematurely, your second attempt after the game would not able to connect in the first place.
Roberto Perillo
Bartender

Joined: Dec 28, 2007
Posts: 2265
    
    3

Howdy, Roel!


- close application
- go watch Match of the Day on television


Maybe the problem is here. Are you taking a beer for this step?

Ok, I'm kidding partner, I'm not really sure if we have a problem here. Honestly, I didn't test such situation. All I did was start the server and have 2 clients connect to it. If you are able to do so, than I think you're fine.


Cheers, Bob "John Lennon" Perillo
SCJP, SCWCD, SCJD, SCBCD - Daileon: A Tool for Enabling Domain Annotations
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5266
    
  13

Roberto Perillo wrote:Maybe the problem is here. Are you taking a beer for this step?

No, I don't drink alcohol. Maybe that's the problem

Roberto Perillo wrote:All I did was start the server and have 2 clients connect to it. If you are able to do so, than I think you're fine.

I tested that and booked a room from clientA and tried to book the same record from clientB and there i got the message "room already booked", so that's working all fine. The only problem i have is the NoSuchObjectException
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5266
    
  13

K. Tsang wrote:Have you tried running clients and server on the same machine and get this exception?

I tried that already, but not with the long idle time between the starting of 2 clients, so i'll give that a shot tonight.

K. Tsang wrote:IMO, if it is really GC prematurely, your second attempt after the game would not able to connect in the first place.

I would also expect something like that, but it doesn't happen, because the exception is really thrown at line 2 and not at line 1

Roberto Perillo
Bartender

Joined: Dec 28, 2007
Posts: 2265
    
    3

Roel, I believe it is indeed being garbage-collected prematurely. Maybe this bug has something to do with it.

But as I said previously, I'm not sure if you have a problem... if you are able to start up your server and have one client connect to it before this interval and work normally, then I think you're fine.
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5266
    
  13

K. Tsang wrote:Have you tried running clients and server on the same machine and get this exception?


Like I promised, i tried it this evening. But running servers and clients on the same machine gives the same exception (after waiting for an hour). I tried it after 25-30 minutes and everything went well. But after 1 hour (and more) the exception was there again

So I hope examiner doesn't start RMI-server and then goes out for a lunch of 1 hour and then test my client application
K. Tsang
Bartender

Joined: Sep 13, 2007
Posts: 2409
    
    7

Hi Roel, try this to see if it is really GC. Pass in your remote object to the search class (class B). When you run this you should get NullPointerException after say 1 hour. If so it really is the server problem. You may then need to set that lease time value. If you don't get the NullPointerException beats me.

Or do you have a server keep-alive action listener checking if the server is "available"? Maybe this can help and when this listener detects not available it informs the client the server is shutdown and closes the client upon clicking an error popup.
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5266
    
  13

Hi K. Tsang,

I don't have any keep-alive actionlistener

i get my remote object successfully (in class a). so like i said no RemoteException is being thrown. Then i pass it through to class B and there i have following code:


My code enters the catch of RemoteException, so my remoteObj is definitely not null.

I found this explanation about the NoSuchObjectException:

A NoSuchObjectException will be thrown when a client that has a reference to a remote object and attempts to use it, discovers that the object in question is no longer there on the server side. The question then is "how can this happen" - and the answer has to do with RMI's remote garbage collection: RMI does not guarantee to remove a remote object when it can prove that there are no remote references to it - only when it thinks it likely that there aren't any. A tempporary network outage between client and server, for example, could fool RMI into thinking that the client is not there. It would remove the server object, then later it could find itself attempting to use that object from that client...
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5266
    
  13

Started my server like this: java -jar -Djava.rmi.server.logCalls=true C:\runme_orig.jar server

Got this console output:

10:05:17 - RMI TCP Connection(1)-127.0.0.1: [127.0.0.1: sun.rmi.registry.RegistryImpl[0:0:0, 0]: java.rmi.Remote lookup(java.lang.String)]
10:05:17 - RMI TCP Connection(2)-192.168.194.1: [192.168.194.1: sun.rmi.transport.DGCImpl[0:0:0, 2]: java.rmi.dgc.Lease dirty(java.rmi.server.ObjID[], long, java.rmi.dgc.Lease)]
10:05:18 - RMI TCP Connection(2)-192.168.194.1: [192.168.194.1: MyInterfaceImpl[-157eb793:120f60e0448:-7fff, 5446953437020301599]: findRooms() ]
11:35:54 - RMI TCP Connection(3)-127.0.0.1: [127.0.0.1: sun.rmi.registry.RegistryImpl[0:0:0, 0]: java.rmi.Remote lookup(java.lang.String)]
11:35:54 - RMI TCP Connection(4)-192.168.194.1: [192.168.194.1: sun.rmi.transport.DGCImpl[0:0:0, 2]: java.rmi.dgc.Lease dirty(java.rmi.server.ObjID[], long, java.rmi.dgc.Lease)]
11:35:56 - RMI TCP Connection(4)-192.168.194.1: [192.168.194.1] exception: java.rmi.NoSuchObjectException: no such object in table
at sun.rmi.transport.Transport.serviceCall(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)


According to my previous post i changed my program, keeping a reference to the object i'm exporting and the stub itself and did the same, resulting in following console output:

13:29:32 - RMI TCP Connection(1)-127.0.0.1: [127.0.0.1: sun.rmi.registry.RegistryImpl[0:0:0, 0]: java.rmi.Remote lookup(java.lang.String)]
13:29:32 - RMI TCP Connection(2)-192.168.194.1: [192.168.194.1: sun.rmi.transport.DGCImpl[0:0:0, 2]: java.rmi.dgc.Lease dirty(java.rmi.server.ObjID[], long, java.rmi.dgc.Lease)]
13:29:34 - RMI TCP Connection(2)-192.168.194.1: [192.168.194.1: MyInterfaceImpl[65dce669:120f6c8deb1:-7fff, 3498042718003588991]: findRooms() ]
16:32:01 - RMI TCP Connection(3)-127.0.0.1: [127.0.0.1: sun.rmi.registry.RegistryImpl[0:0:0, 0]: java.rmi.Remote lookup(java.lang.String)]
16:32:01 - RMI TCP Connection(4)-192.168.194.1: [192.168.194.1: sun.rmi.transport.DGCImpl[0:0:0, 2]: java.rmi.dgc.Lease dirty(java.rmi.server.ObjID[], long, java.rmi.dgc.Lease)]
16:32:03 - RMI TCP Connection(4)-192.168.194.1: [192.168.194.1: MyInterfaceImpl[65dce669:120f6c8deb1:-7fff, 3498042718003588991]: findRooms() ]


So no exception is thrown anymore and program keeps working as expected
Roman Traze
Greenhorn

Joined: Feb 10, 2009
Posts: 14
Roel De Nijs,

I'm having exactly the same problem as you, as you did to keep a reference to the object?
I used static but did not work, as was your code?

Thanks
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5266
    
  13

Hi Roman,

I did nothing more than what I said earlier: keeping a static reference to my remote service implementation.



Kind regards,
Roel
Olu Shiyan
Ranch Hand

Joined: Jun 10, 2010
Posts: 57

Hi guys,

Just thought I should test my program a couple more times before submitting and behold this ugly 'NoSuchObjectException' pops up sometimes when my client is trying to display the full set of rooms after connecting to the server. The randomness of this problem (in my case) is making it difficult for me to figure out. That is sometimes 'NoSuchObjectException' is thrown and sometimes clients connect to server and display rooms fine. I'd say the exception is thrown one out of every five tries. However not knowing the cause of this exception and hence how to reproduce it is making it difficult for me to solve.

So annoying. Thought I had this thing wrapped.

I have got a class with one static method for starting the RMI server. Snippets of the method are below



Ideas?

Thanks


SCJP 6, OCMJD6
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5266
    
  13

Hi Olu,

Certainly I have an idea It's even very simple: you are making the wrong object static.

This is how I did it, applied to your code:

So you have to keep track of the actual object, not the exported object

Kind regards,
Roel
Olu Shiyan
Ranch Hand

Joined: Jun 10, 2010
Posts: 57


Ah! I see. Thanks Roel, I'll try that out.


Cheers!
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: java.rmi.NoSuchObjectException