aspose file tools*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes NX:contractor - stubs 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 "NX:contractor - stubs" Watch "NX:contractor - stubs" New topic
Author

NX:contractor - stubs

Mike Southgate
Ranch Hand

Joined: Jul 18, 2003
Posts: 183
my assignment says when running in non-networked mode I can't use any networking (loop-back or otherwise) and I must not involve the serialization of any objects when communicating between the gui and database elements.
the data class and the interface it implements (DBAccess) do not extend remote. So what I did was to create a new interface that does extend remote with the same methods as the DBAccess interface. I then have to classes that implement this new interface. My server class and a localdata class. The server class extends unicastremoteobject but the localdata class doesn't.
I just noticed that eclipse has created some stubs for my localdata class (probably because it implements an interface that extends remote). I've tried running it without the stub for the localdata class and it seems to work fine. Am I ok here?
ms


ms<br />SCJP, SCJD
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Am I ok here?
Probably, but it sounds a bit iffy to me. So, a programmer seeking to understand your DB and maybe GUI code will see classes that implement Remote? What would happen if someone wanted to replace RMI with sockets? How many places would your code have to change?
I kept any mention of networking classes completely out of my db and gui classes - it's all in my suncertify.network package. The only mention outisde that package is in my "main" class, which interprets the initial command line arguments to decide whether to create a local client or one that uses a network connection. The network package includes an adaptor to catch RemoteExceptions and rewrap them as DBExceptions (a RuntimeException subclass). So viewed from the outside, the networked connection implements an API that makes no mention at all of anything network-specific.
Dunno if it's worthwhile to rework your code over this. Depends how much effort it is given your current design. (Though one could argue that if it's a lot of work to relocate networking references, that indicates that your current design isn't as modular as might be desireable.)


"I'm not back." - Bill Harding, Twister
Tankred Smult
Greenhorn

Joined: Jul 15, 2003
Posts: 16
Originally posted by Mike Southgate:

the data class and the interface it implements (DBAccess) do not extend remote. So what I did was to create a new interface that does extend remote with the same methods as the DBAccess interface. I then have to classes that implement this new interface. My server class and a localdata class. The server class extends unicastremoteobject but the localdata class doesn't.

I've done a simular thing regarding remote data acess vs. local access. My plan was just to have an interface called something like DataProxy, which have methods that throws RemoteException, and have my remote and local access classes extend that interface:


However, by not letting DataProxy extend Remote, I've got an ClassCastException when trying to cast RemoteDataProxy to DataProxy on the client (or, actually I'm trying to cast the RemoteDataProxy_Stubs to DataProxy). It seems it can only be casted to interfaces extending Remote for some (probably good) RMI reason that I don't see, as I'm not an RMI expert.

Anyway, I'm currently having DataProxy extend Remote, even though I would prefere it if I were able to cast the RemoteDataProxy_Stub to DataProxy even when DataProxy is not extending Remote. Because having DataProxy extend Remote indicates that the DataProxy is available remote (which is not the case for the LocalDataProxy).
Can anyone explain why DataProxy has to extend Remote, or has a link that explains this, or have a more elegant workaround for this problem?
Tankred
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Can anyone explain why DataProxy has to extend Remote, or has a link that explains this, or have a more elegant workaround for this problem?
If you want the client to be able to treat the remote object as a DataProxy, the client stub class generated by rmic has to implement DataProxy. The way rmic works, it looks at Remote implementation class and generates a stub class which implements the same remote interfaces as the implementation. Note I said remote interfaces. The definition of a remote interface is, an interface that extends Remote. rmic studies the implementation declaration, looks for any implemented interfaces that extend Remote, and makes sure that the stub class implements those same interfaces, since Remote implies they're intended to be exported to remote proxies. If rmic finds any non-remote interfaces (like the current version of your DataProxy), it assumes that's an implementation detail which is none of the remote stub class' business.
So - to use a remote object client side, you have to be able to refer to it by an interface that describes what it does; in order to get the generated stub class to actually implement a particular interface, the interface must extend Remote. If you're using rMI, I don't think there's any way around this.
Now, you can till convert this remote object into a non-remote interface (with no RemoteException declarations) by wrapping it in some sort of adapter class. This class has methods that catch RemoteExceptions and do deal with them somehow. Maybe it logs them, maybe it re-throws them as RecordNotFoundException or SomeCustomRuntimeException. That's your choice. One way or another though, the adapter hides the RMI-specific stuff from the outside world - meaning all your other non-networked client-side classes.
Tankred Smult
Greenhorn

Joined: Jul 15, 2003
Posts: 16
I've now studied a book called "The Sun Certified Java Developer Exam with J2SE 1.4". In regards to RMI it seems like a remote object is indeed casted to a non-remote object:

Where DBClient is a interface not extending Remote in any way. So it seems to me it is possible to cast a remote object (or actually it's stubs) into a interface not implementing Remote. Or have I missed something? If not, why doesn't the books code get a Cast-exception as I do?
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11423
    
  85

Hi Tankred
DVDDatbaseImpl extends UnicastRemoteObject implements DVDDatabaseRemote
DVDDatabaseRemote extends Remote, DBClient
So therefore the remote object can be cast as a DBClient.
Does this make sense?
Regards, Andrew


The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Note that Max's code is sort of a special case. The any remote methods need to throw RemoteException, which means that any interface they implement needs to allow them to throw RemoteException. Max set up the DBClient interfae so that every method is declared to throw IOException, which is actually a superclass of RemoteException. So when you look at the DBClient interface you don't see any explicit mention of Remote or RemoteException. But the RemoteExceptions are covered by the IOExceptions, and the actual implemenint class does implement Remote.
Tankred Smult
Greenhorn

Joined: Jul 15, 2003
Posts: 16
Thanks for answering!
Still, I don't quite get it.
It seems to me that what I've done is quite simular to what's been done in the book.
To review the code fragment I posted earlier:

The RemoteDataProxy is the made the remote object:

On the client I connect to the remote object:

But when I try to cast the remoteObject into DataProxy, I get a cast-exception. I don't see how this is different from whats been done in the book.
If I understand the earlier post by Jim Yingst correctly; rmic, when generating the stubs, considers all non-Remote interfaces the remote object implements as implementation details that should be hidden from the client. Hence, the generated stubs do not implement any non-Remote interfaces.
However, looking at the code in the book it seems to me the generated stubs do implement non-Remote interfaces, as it is casted to one:

What I would like to know is; in which cases the remote object can be casted to a non-Remote interface, and in which cases it cannot (obviously in mine, at least ). I would like to get it by teaspoon (don't know if this makes sense to you, it what we say in Norway when someone needs a thoroughly expaination).
Tanks for you patience!
Tankred
Not stupid, only slow!
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
If you want the generated stub proxy class to implement any interface, it must be a remote interface - an interface that extends Remote. If the interface also extends some other interfaces that aren't remote but are compatiable (by throwing RemoteException or a supertype) then you get those too. But the interface must extend Remote, or the generated stub won't implement it.
In Max's code, DVDDatabaseRemote is a remote interface, extendsing both Remote and DBClient. Because DVDDatabaseRemote extends Remote, for class that implements DVDDatabaseRemote you can generate a stub file that also implements DVDDatabaseRemote. Which means the stub also implements DBClient.
In your code, there is no remote interface other than Remote itself. RemoteDataProxy implements Remote, and also DataProxy. But the generated stub class only implements remote interfaces of the original implementing class. Which means that RemoteDataProxy_Stub implements Remote, but not DataProxy.
Tankred Smult
Greenhorn

Joined: Jul 15, 2003
Posts: 16
Seems I'm getting closer to a solution. There's one difference between my solution and the one in the book. In the book the class itself does not implement Remote directly, but instead a interface that implements Remote.
These examples will hopfully make this more clear. This does not work, as the fact that RemoteDataProxy implements DataProxy is considered a implementation detail by rmic when generating stubs:

Whereas this works (the difference is that I've put a interface in between DataProxy and RemoteDataProxy):

When rmic is called

The stubs are actually generated for the RemoteDataProxyInterface, as this is the closest interface that implements Remote directly. The fact that RemoteDataProxyInterface extends DataProxy is not considered an implementation detail. Why not? Well, I'm not quite sure, but I guess it is because which interfaces an interface extend is not a detail. But which interfaces a class implements is. No, I don't get it either.
Anyway, seems I can get it to work by inserting this interface without having DataProxy extend Remote. This way my LocalDataProxy does not have to extend Remote indirectly, which means that I'm happy. At least for now. Which means I'll stop bugging you guys. At least for now...
...and they all lived happily ever after...
Tankred Smult
Greenhorn

Joined: Jul 15, 2003
Posts: 16
Seems also like Jim Yingst posted a reply pointing out the same issues I adressed in my last posting when I was writing it.
Tanks for the help!
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: NX:contractor - stubs