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

Remote Business Service - Delegating to Local

 
Ranch Hand
Posts: 590
Eclipse IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have set up my Remote Business Service to delegate to my Local Business Service. Is this a valid approach? Or are there any hidden problems here that I am missing? Not sure whether it is valid - but just to note, it does work !

The reason that I ask is that when I run FindBugs against my code base I get the following error:

M B Se: suncertify.service.LocalServiceImpl stored into non-transient field RemoteServiceImpl.service At RemoteServiceImpl.java


I'm not quite sure why it is complaining about LocalServiceImpl being stored in a non-transient field. An instance of RemoteServiceImpl is never communicated across the network. Only a stub is. So why is it looking at whether fields are transient?

Also LocalServiceImpl doesn't implement the Serializable interface. So if my program was attempting to send an instance of RemoteServiceImpl across the network then I would know about it. Because it would fail due to LocalServiceImpl not implementing the Serializable interface.

Assuming I do have to worry about RemoteServiceImpl being serialized. Then where is the problem with storing a reference to LocalServiceImpl in a non-transient field? Confused

The header of my Remote Business Service is:
The header of my Local Business Service is:
The header of my interface for my Remote Business Service is:
The IBusinessService interface does not extend anything.
 
Sheriff
Posts: 11604
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Why have 2 business service implementations and not simply having 1?

The BusinessServiceImpl would just implement RemoteBusinessService and not extend anything. You can use an instance for local mode, and use UnicastRemoteObject.export() to create an instance which can be exposed through RMI.
 
Sean Keane
Ranch Hand
Posts: 590
Eclipse IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hmmm. I think I may have figured it out.

RemoteServiceImpl extends UnicastRemoteObject. UnicastRemoteObject implements the Serializable interface. Therefore RemoteServiceImpl is serializable.

FindBugs looks at whether members of the serializable class are serializable. If the members are not serializable then it checks to see if they are stored to transient fields. It is ok to have non-serializable members in a serializable class if they are transient because Java will not attempt to serialize them. If the non-serializable members are not assigned to a transient field, then FindBugs reports an error.

In my particular case. RemoteServiceImpl is serializable so FindBugs begins looking at whether all of its fields are serializable. It see that I have LocalServiceImpl assigned to a field. It sees that LocalServiceImpl is not serializable and that the field that LocalServiceImpl is assigned to is not transient. So it reports an error.

So in theory I can see the problem. But in practice I don't think there is a problem. Because an instance of RemoteServiceImpl will never be sent over the network. So Java will never attempt to serialize an instance of RemoteServiceImpl, so it will never run into a problem.
 
Sean Keane
Ranch Hand
Posts: 590
Eclipse IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Roel De Nijs wrote:Why have 2 business service implementations and not simply having 1?

The BusinessServiceImpl would just implement RemoteBusinessService and not extend anything. You can use an instance for local mode, and use UnicastRemoteObject.export() to create an instance which can be exposed through RMI.


Based on my previous post the problem is occuring as RemoteServiceImpl extends UnicastRemoteObject.

I don't think there is a problem with my code in practice, but there is in theory. If my class implements the Serializable interface then it should be possible to serialize it. So based on this thinking, I reckon I need to change my code.

Simply not extending UnicastRemoteObject in my RemoteBusinessService and using export as you mentioned Roel would do the trick.

 
Sean Keane
Ranch Hand
Posts: 590
Eclipse IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Roel De Nijs wrote:Why have 2 business service implementations and not simply having 1?



I didn't like the idea of my Local Business Service extending UnicastRemoteObject and implementing Remote.
 
Roel De Nijs
Sheriff
Posts: 11604
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Sean Keane wrote:I didn't like the idea of my Local Business Service extending UnicastRemoteObject and implementing Remote.


It would not extend UnicastRemoteObject, because you would use its export-method. Not wanting to implement Remote is a valid argument.
 
Sean Keane
Ranch Hand
Posts: 590
Eclipse IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Roel De Nijs wrote:

Sean Keane wrote:I didn't like the idea of my Local Business Service extending UnicastRemoteObject and implementing Remote.


It would not extend UnicastRemoteObject, because you would use its export-method. Not wanting to implement Remote is a valid argument.



You asked why I had two business service implementations. Because with the setup I had (i.e. not using the export-method) I would had to have made my single service implementation extend UnicastRemoteObject and Remote.

As you pointed out, going with with export-method option removes the concern about extending UnicastRemoteObject. So one problem solved .

If I go with a single class for my service then that still leaves me with a service that I use in non-networking mode implementing Remote.

It doesn't seem right on the face of it. But maybe it's not unusual and is common practice i.e. "here's a class you can use if networking mode if you choose to" - so it's not saying you have to use it in networking mode, just that the option is there. Similarily with Serializable. If you mark a class as being Serializable, it doesn't mean you have to serialize it, it's just that the option is there to do it if you so wish.

I know there have been a few threads about this. So I'll have another read up on it later.
 
Sean Keane
Ranch Hand
Posts: 590
Eclipse IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Roel, were you able to start your server from Eclipse? I changed my code to use the export-method instead of extending UnicastRemoteObject and now I can't start the server from Eclipse. But I can start it from my built JAR.

Here's the error I get when attempting to start my server from Eclipse:

Stub class not found: suncertify.service.RemoteBusinessServiceImpl_Stub; nested exception is:
java.lang.ClassNotFoundException: suncertify.service.RemoteBusinessServiceImpl_Stub
java.rmi.StubNotFoundException: Stub class not found: suncertify.service.RemoteBusinessServiceImpl_Stub; nested exception is:
java.lang.ClassNotFoundException: suncertify.service.RemoteBusinessServiceImpl_Stub
at sun.rmi.server.Util.createStub(Util.java:274)
at sun.rmi.server.Util.createProxy(Util.java:122)
at sun.rmi.server.UnicastServerRef.exportObject(UnicastServerRef.java:179)
at java.rmi.server.UnicastRemoteObject.exportObject(UnicastRemoteObject.java:293)
at java.rmi.server.UnicastRemoteObject.exportObject(UnicastRemoteObject.java:220)
at suncertify.gui.RegisterRemoteService.register(RegisterRemoteService.java:21)



The line of code line where the error is getting thrown from is the second line below:

I know from playing around with RMI before that it can take a bit of messing about to get everything working correctly from Eclipse! Not sure if it is worth this hassle at this stage. But still, it would be handy for testing and tweaking quickly.
 
Sean Keane
Ranch Hand
Posts: 590
Eclipse IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hmmm I went back to basics with my little toy example of using RMI in Eclipse. I changed it to use the export-method rather than my class extending UnicastRemoteObject. It also failed with the same error that I've gotten in my project code.

This is annoying! Anyone got any ideas as to why the stub class cannot be found? I am using Java 6.

Below is a slimmed down example that gives the same error:


Below is a slimmed down example where I extend UnicastRemoteObject and I do not get the error:
 
Sean Keane
Ranch Hand
Posts: 590
Eclipse IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Phew, problem solved!!!

The solution was to simply use exportObject(Remote obj, int port) instead of exportObject(Remote obj) .

I'm unsure as to why exportObject(Remote obj, int port) works but exportObject(Remote obj) does not work.

What puzzles me, as outlined on the thread I referenced, is that exportObject(Remote obj) worked fine when I packaged everything up into a JAR. But it didn't work when running from Eclipse or when simply running from the command line.

From reading other threads on this forum, it seems that exportObject(Remote obj, int port) is the one to go with. So I'm happy enough with moving forward. But still curious as to why exportObject(Remote obj) works when the class file is packaged up in a JAR.

At times it seems like RMI is a black art
 
Roel De Nijs
Sheriff
Posts: 11604
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Sean Keane wrote:From reading other threads on this forum, it seems that exportObject(Remote obj, int port) is the one to go with.


That's the one I used too, but I never tried the examples with the one-parameter-method.

Maybe you can start a topic about this strange thingy in a more appropriate thread, because here are no RMI gurus I guess.
 
Sean Keane
Ranch Hand
Posts: 590
Eclipse IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I've created this thread here. So I'll see what comes up. But getting thorough explanations about RMI behaviour can be challenging!
 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic