Thanks for the clarification Peter, excellent reference material too,
much appreciated.
- Peter Firmstone.
Peter Jones wrote:
What transport layer implementation are you using?
Here is the way that this case is supposed to be covered:
- The OutputStream returned by InboundRequest.getResponseOutputStream on the
server side implements net.jini.io.ObjectStreamContext, which contains an
element that implements net.jini.io.context.AcknowledgmentSource.
- BasicObjectEndpoint.writeObject (which represents the "live references" in
the DGC sense) detects this element during marshalling and registers an
AcknowledgmentSource.Listener with it, which keeps the BasicObjectEndpoint strongly
referenced until its acknowledgmentReceived method is invoked.
- When its acknowledgmentReceived method is invoked, either with true to
indicate that the reading side has successfully unmarshalled the data (and thus
registered the BasicObjectEndpoint with DGC) or with false to indicate that the
transport layer has failed or given up, then the listener drops its strong
reference.
The standard net.jini.jeri.* transport layer implementations should implement
this AcknowledgmentSource protocol, but I'm wondering if you are using some
other implementation that doesn't, or a layered implementation that needs to
expose the underlying functionality.
I'm surprised (or I should say embarrassed) to see that the relationship
between DGC and this AcknowledgmentSource protocol is not clearly called out in
the net.jini.jeri package spec-- the mechanism only seems to be covered in the
serialized form spec for BasicObjectEndpoint.writeObject.
FYI, this return value case was well anticipated (back to [1]), it's actually
the parameter case that can be surprisingly vulnerable to modern JVM GC
improvements:
http://bugs.sun.com/view_bug.do?bug_id=6181943
although that bug was for JRMP, and JERI's BasicInvocationHandler is
incidentally not susceptible to that problem because of the
OutboundRequestIterator.
-- Peter
[1] http://www.hpl.hp.com/techreports/Compaq-DEC/SRC-RR-116.pdf
On Mar 5, 2010, at 5:51 AM, Sim IJskes - QCG wrote:
Peter Firmstone wrote:
Note that when you export your service it's proxy is stored in Marshalled form until the client discovers it, while in Marshalled form
Eh, that isn't exactly true is it? After export, you get a Proxy with a
reference to a BasicInvocationHandler with a reference to a BasicObjectEndpoint
with a reference to a ImplContainer with a reference to your service.
As long as you keep the reference to the exported service, the service is
'strongly reachable' from the exported service.
The problem starts when you marshall it in
BasicInvocationDispatcher.marshalReturn(), and the reply has enough latency to
arive 'late' at the client side.
In this window the service becomes 'weakly reachable' and if the GC kicks in
before DgcServer.dirty the object gets finalized.
Gr. Sim
--
QCG, Software voor het MKB, 071-5890970, http://www.qcg.nl
Quality Consultancy Group b.v., Leiderdorp, Kvk Leiden: 28088397