• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Why does the RMI Reaper remove my object from the object table

 
Bartender
Posts: 1638
IntelliJ IDE MySQL Database Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,
I have the following sample code to bind a test remote object to the RMI registry



Now, when i run the above program with the following parameters:
-Dsun.rmi.loader.logLevel=VERBOSE -Dsun.rmi.dgc.logLevel=VERBOSE
I get the following log:
Mar 26, 2007 2:27:26 PM sun.rmi.transport.WeakRef pin
FINER: main: strongRef = sun.rmi.transport.DGCImpl@17a8913
Mar 26, 2007 2:27:26 PM sun.rmi.transport.ObjectTable putTarget
FINER: main: add object [0:0:0, 2]
Mar 26, 2007 2:27:26 PM sun.rmi.transport.WeakRef pin
FINER: main: strongRef = RegistryImpl[UnicastServerRef [liveRef: [endpoint:[10.10.2.67:1098](local),objID:[0:0:0, 0]]]]
Mar 26, 2007 2:27:26 PM sun.rmi.transport.ObjectTable putTarget
FINER: main: add object [0:0:0, 0]
Mar 26, 2007 2:27:26 PM sun.rmi.transport.ObjectTable putTarget
FINER: main: add object [0]
Mar 26, 2007 2:27:26 PM sun.rmi.transport.ObjectTable removeTarget
FINER: RMI Reaper: remove object [0]

If you see the last log, it indicates that the RMI Reaper thread has removed an object. However, it does not give the detail of the object removed but i assume that it is the object that i have added because, when i try to execute a method on the object that i have bound(by name "nitesh") i get the following exception:

Exception in thread "main" java.rmi.NoSuchObjectException: no such object in table
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:247)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:223)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:126)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:179)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:132)
at $Proxy0.hello(Unknown Source)

Is it so, that the RMI reaper has removed the bound object from the object table, as soon as it is bound?
Just to mention, the above exception come while calling the method hello on the remote interface. I can lookup the object from the registry.
Also, i am not generating any stubs, so dynamic proxy will be used in this case.

I am sure i am missing something.

Just a nasty fact. If i make this thread sleep for some time just before the bind to the registry, everything works fine .... can somebody help me understand this

code for the remote interface, implementation and client for reference:


[ March 26, 2007: Message edited by: Nitesh Kant ]
 
Ranch Hand
Posts: 291
Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
registry.rebind("nitesh", testRemote);

rebind testRemote not remoteStub

You bind the implementation code (remote object), not a stub.
 
Nitesh Kant
Bartender
Posts: 1638
IntelliJ IDE MySQL Database Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Edward Harned:
registry.rebind("nitesh", testRemote);

rebind testRemote not remoteStub

You bind the implementation code (remote object), not a stub.



Hi Edward,
Actually, thats how i learned RMI too
Actually, all this came from this sun tutorial trail
One of my friend was going through this and asked me to give a reason for the same :roll:
The tutorial, clearly specifies that the stub is bound to the registry. So, i was confused. Actually, binding the remote object works fine but i just wanted to know the reason as to why this is happening with the stub, as the stub is also a remote object anyways.
 
Nitesh Kant
Bartender
Posts: 1638
IntelliJ IDE MySQL Database Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Phew, i got the answer ....
Actually, the object created in

was getting garbage collected
I had the following findings:

1) The problem was not with the registry.bind().
2) The problem was with the export.
3) Since i was exporting the above mentioned implementation which was going out of scope and was getting garbage collected, so, it was also removed from the ObjectTable. ObjectTable holds a reference queue for the weak reference of the object being exported. So, as soon as it was GCed, it was removed from the object table.

Now, few findings on the difference between binding the stub and the object itself to the rmi registry:
1) When i bind the actual object implementation with the registry, then, the rmi registry holds a remote reference to my server implementation, so by the laws of DGC, this will not be garbage collected.
2) When i bind the stub to the registry, then the rmi registry holds a remote reference to this stub and not of the actual object implementation and so it will be garbage collected.

Also, about the nasty fact ... as to why a Thread.sleep() in the callMe() method makes everything run nicely. This is so because a Thread.sleep() made the GC to run with the method still executing and the object implementation still in scope. So the GC did not collect the object. I confirmed this by printing the verbose GC messages!!! Also, i called System.gc() after the callMe() method returned. That collected the object and subsequently, it got removed from the ObjectTable.

Ranchers, (if anyone listening) do let me know if any of the above findings are wrong.
 
Edward Harned
Ranch Hand
Posts: 291
Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
GC is always a problem.

Save a reference to your implemented class in your start up method/class.

To avoid GC, I always issue a never ending wait() in the the start-up class. Since there are keep alive threads in RMI, the server needs to issue a System.exit() when it wants to end.

Thanks for the research.
 
Nitesh Kant
Bartender
Posts: 1638
IntelliJ IDE MySQL Database Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Edward Harned:
GC is always a problem.

Save a reference to your implemented class in your start up method/class.


Yeah thats what i did!


To avoid GC, I always issue a never ending wait() in the the start-up class. Since there are keep alive threads in RMI, the server needs to issue a System.exit() when it wants to end.


Actually, do we need this? May be i am wrong. I think if you just make the implementation a static variable in the start-up class, it should work. It will not be GCed till the class is unloaded from the VM i.e. essentially when the classloader gets garbage collected. But, yeah a never ending wait() will make sure that whatever may come .. i will be alive
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic