However, there is a problem, now I can no longer let MyRemoteDatabase extend
the class MyDatabase, where all the functionality is. MyRemoteDatabase is
simply a shell, making the database class suitable for rmi (implementing a
remote interface and so on). I solved this problem using the delegation
pattern, but in other situations this might not be a sufficient solution
(e.g if I need to override some protected methods in the superclass)
So my question is simply, how can I return a reference to a remote,
non-serializable object whithout having to extend UnicastRemoteObject? I'm
sure it must be possible.
Thor
You only have* to extend UnicastRemoteObject for objects that you want to
"export", i.e. bind to the registry.
If your object gets returned from another remote object, then implementing
Remote is sufficient.
*In fact, you never HAVE to extend UnicastRemoteObject. You can just call
UnicastRemoteObject.export(), which is a static method
kenny
That is weird, because as my program is now, the success or failure of
retrieving remote objects, are merely depending on those objects superclass.
If I extend UnicastRemoteObject, it works fine, if I don't I get the
following exception:
error unmarshalling return; nested exception is:
java.io.WriteAbortedException: Writing aborted by exception;
java.io.NotSerializableException: suncertify.db.RemoteStructuredData
java.rmi.UnmarshalException: error unmarshalling return; nested exception
is:
java.io.WriteAbortedException: Writing aborted by exception;
java.io.NotSerializableException: suncertify.db.RemoteStructuredData
java.io.WriteAbortedException: Writing aborted by exception;
java.io.NotSerializableException: suncertify.db.RemoteStructuredData
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:445)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:236)
at sun.rmi.server.UnicastRef.unmarshalValue(UnicastRef.java:300)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:134)
at suncertify.RMIServer.SkyBaseServer_Stub.getDatabase(Unknown
Source)
at suncertify.db.DataContainer.<init>(DataContainer.java:37)
.....
I don't know why it's happening, but it does, even if I never need to bind
it to registry. It almost seems like to be transmitted as remote object, it
needs to implement certain methods, that exists in UnicastRemoteObject.
Except that in my case, it is never discovered in compile time when it
doesn't implement those methods. Can anyone tell me why?
Thor
OK, well try the approach of explictly calling UnicastRemoteObject.export()
on your RemoteStructuredData object. Do this after you construct the
object. That way, you don't have to extend UnicastRemoteObject.
Thor
in http://java.sun.com/docs/books/tutorial/rmi/implementing.html
the following paragraps are contained:
UnicastRemoteObject is a convenience class, defined in the RMI public API,
that can be used as a superclass for remote object implementations. The
superclass UnicastRemoteObject supplies implementations for a number of
java.lang.Object methods (equals, hashCode, toString) so that they are
defined appropriately for remote objects. UnicastRemoteObjectalso includes
constructors and static methods used to export a remote object, that is,
make the remote object available to receive incoming calls from clients.
A remote object implementation does not have to extend UnicastRemoteObject,
but any implementation that does not must supply appropriate implementations
of the java.lang.Object methods. Furthermore, a remote object implementation
must make an explicit call to one of UnicastRemoteObject's exportObject
methods to make the RMI runtime aware of the remote object so that the
object can accept incoming calls. By extending UnicastRemoteObject, the
ComputeEngine class can be used to create a simple remote object that
supports unicast (point-to-point) remote communication and that uses RMI's
default sockets-based transport for communication.
"Thorvald Bře" <thorva...@tietoenator.com> schrieb im Newsbeitrag
news:BJGR7.2451$RS2....@juliett.dax.net...
> "Thorvald Bře" <thorva...@tietoenator.com> wrote in message
> news:SdFR7.2436$RS2....@juliett.dax.net...
> >
> > So my question is simply, how can I return a reference to a remote,
> > non-serializable object whithout having to extend UnicastRemoteObject? I'm
> > sure it must be possible.
>
> You only have* to extend UnicastRemoteObject for objects that you want to
> "export", i.e. bind to the registry.
> If your object gets returned from another remote object, then implementing
> Remote is sufficient.
this is wrong. "export" does not mean "bind in the registry". it
means something more like "make available for remote calls". also,
implementing Remote is *not* sufficient, at least not for recent
versions of the JDK. in order for a reference to a remote object to
be replaced by its stub on serialization, the reference has to be to
something that implements Remote *and* is currently exported.
> *In fact, you never HAVE to extend UnicastRemoteObject. You can just call
> UnicastRemoteObject.export(), which is a static method
>
this is true. the point is, if you want to return a reference to a
remote object, that object has to be exported at the time of the
call. you can do this either by subclassing UnicastRemoteObject
(which does an export in the constructor) or by calling
UnicastRemoteObject.export() on it.
--
joe
You're right, of course. I was getting myself tied in knots :-)
From http://java.sun.com/j2se/1.3/docs/guide/rmi/spec/rmi-objmodel7.html:
"When passing an exported remote object as a parameter or return value in a
remote method call, the stub for that remote object is passed instead.
Remote objects that are not exported will not be replaced with a stub
instance."
For some reason, I was telling myself that if you have a remote object,
which has a method which returns another remote object, then that returned
type need not explicitly export itself, that it would be done by the RMI
runtime. I was convinced of that before, but I have no idea why :-(
kenny