Re: What causes an object to be removed from the ObjectTable?
Peter Jones - JavaSoft East <[email protected]> Sat, 17 Dec 2005 13:23:28 -0500
| Newsgroups | gmane.comp.java.sun.rmi |
|---|---|
| Message-ID | <20051217182328.GB16360@east> |
It's not obvious to me why either version wouldn't work, because the
registry binding should keep the remote object alive through DGC.
It's tempting to think that the difference between the two examples is
related to this bug:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4114579
but as I described in this previous post:
http://archives.java.sun.com/cgi-bin/wa?A2=ind0509&L=rmi-users&P=617
the fact that you're invoking a registry stub, returned from
LocateRegistry.getRegistry (instead of a direct reference to a
registry remote object, returned from LocateRegistry.createRegistry),
should avoid the effect of 4114579 in the second example.
Do you see an incoming DGC "dirty" call logged synchronous with the
rebind invocation, for either the first or the second example? Is the
registry in the same VM or a different VM?
The example code does not use a non-null client socket factory, but
just to be sure, is that true of your actual case that exhibits this
problem too? If not, and the registry is in a separate VM, does its
security policy grant the client socket factory class SocketPermission
to connect to the server? That's a common issue, although it wouldn't
explain the difference between passing the stub and passing the remote
object, which (with JRMP) just gets replaced with the stub anyway.
-- Peter
Quoting Robert DiFalco <[email protected]>:
> Ok, I answered my own question:
>
> The first example is fine, it is the second example that uses m_stub
> that has a problem.
>
> public class FooService extends UnicastRemoteObject implements Foo
> {
> private Foo m_stub;
>
> public FooService() throws RemoteException
> {
> m_stub = (Station)UnicastRemoteObject.toStub( this );
> LocateRegistry.getRegistry(
> getLocalServicePort() ).rebind(
> Foo.class.getName(),
> m_stub );
> }
>
> ....
> }
>
> The constructor to UnicastRemoteObject will export "this". Basically
> wrapping it in a Target and adding it (as a WeakReference) to
> ObjectTable. Because I'm still in the constructor, toStub has no problem
> looking up that target in the ObjectTable again. Unfortunately, I am
> binding "m_stub" and not "this". So while "this" AND the regsitry are
> maintaining a strong reference to "m_stub", nothing is maintaining a
> strong reference to "this". Once the constructor exits, "this" can be
> collected and when the reaper runs (however often it runs) it will
> remove the Target for FooService from the ObjectTable. Duh.
>
> R.
>
> -----Original Message-----
> From: Robert DiFalco
> Sent: Friday, December 16, 2005 2:48 PM
> To: [email protected]
> Cc: Brian McFeely
> Subject: What causes an object to be removed from the ObjectTable?
>
> I'm really confused at this point. It is my understanding that if I have
> code like this:
>
> public class FooService extends UnicastRemoteObject implements Foo {
> public FooService() throws RemoteException
> {
> super();
>
> LocateRegistry.getRegistry(
> getLocalServicePort() ).rebind(
> Foo.class.getName(), this );
> }
>
> ...
> }
>
> Then if I have a client of Foo that always looks the class up in the
> remote registry that I should NEVER get a NoSuchObjectException. (Maybe
> it could get this exception if it cached the stub and the server
> restarted, but not otherwise).
>
> However, what I'm seeing is very strange and different.
>
> Eventually, in the sever log I see this:
>
> Dec 16, 2005 1:24:00 PM sun.rmi.transport.tcp.TCPChannel$Reaper run
> FINER: RMI ConnectionExpiration-[10.69.10.62:9898]: exit Dec 16, 2005
> 1:25:31 PM sun.rmi.transport.ObjectTable removeTarget
> FINER: RMI Reaper: remove object [0] <<--- [0] is Foo
>
> Next, when the client would like to get the Foo stub/objid to invoke a
> method on the FooServer I see this in the server's log (which seems to
> succeed):
>
> FINER: RMI TCP Connection(99)-10.69.10.62: [10.69.10.62:
> sun.rmi.registry.RegistryImpl[0:0:0, 0]: java.rmi.Remote
> lookup(java.lang.String)]
>
> Finally, when the client invokes a method on the Foo stub I get:
>
> FINE: RMI TCP Connection(99)-10.69.10.62: [10.69.10.62] exception:
> java.rmi.NoSuchObjectException: no such object in table
> at sun.rmi.transport.Transport.serviceCall(Transport.java:112)
> at
> sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
> at
> sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.ja
> va:701)
> at java.lang.Thread.run(Thread.java:534)
>
> And that is pretty much game over.
>
> So somehow the WeakRef to the impl in the server's ObjectTable is being
> cleaned up, causing the reaper to remove the target from the table all
> together. Any idea how this could happen?
>
> All clients and agents have these settings:
>
> -Dsun.rmi.dgc.server.gcInterval=3600000
> -Dsun.rmi.dgc.client.gcInterval=3600000
> -Dsun.rmi.dgc.checkInterval=1800000
>
> Finally, if the above code were re-written like this (using the stub
> directly) could that create the problem I am seeing?
>
>
> public class FooService extends UnicastRemoteObject implements Foo {
> private Foo m_stub;
>
> public FooService() throws RemoteException
> {
> m_stub = (Station)UnicastRemoteObject.toStub( this );
> LocateRegistry.getRegistry(
> getLocalServicePort() ).rebind(
> Foo.class.getName(),
> m_stub );
> }
> }
>
> Not the registration of m_stub instead of "this".
>
> R.
>
===========================================================================
To unsubscribe, send email to [email protected] and include in the body
of the message "signoff RMI-USERS". For general help, send email to
[email protected] and include in the body of the message "help".
For a list of frequently asked RMI questions please refer to:
http://java.sun.com/j2se/1.3/docs/guide/rmi/faq.html
To view past RMI-USERS postings, please see:
http://archives.java.sun.com/archives/rmi-users.html