• 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
  • Ron McLeod
  • Paul Clapham
  • Devaka Cooray
  • Tim Cooke
Sheriffs:
  • Rob Spoor
  • Liutauras Vilda
  • paul wheaton
Saloon Keepers:
  • Tim Holloway
  • Tim Moores
  • Mikalai Zaikin
  • Carey Brown
  • Piet Souris
Bartenders:
  • Stephan van Hulst

NX:contractor - stubs

 
Ranch Hand
Posts: 183
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.)
 
Greenhorn
Posts: 16
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 16
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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?
 
author and jackaroo
Posts: 12200
280
Mac IntelliJ IDE Firefox Browser Oracle C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
Jim Yingst
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 16
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 16
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 16
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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!
 
Sasparilla and fresh horses for all my men! You will see to it, won't you tiny ad?
Smokeless wood heat with a rocket mass heater
https://woodheat.net
reply
    Bookmark Topic Watch Topic
  • New Topic