Win a copy of Learn Spring Security (video course) this week in the Spring forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

RMI problem

 
Michael Sunny
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi, all,
I know many of you have done RMI protocol. I am trying to not use security manager and java policy file to make cient-server communication. The application runs fine in a single machine. But when run in separate machines, client can not get stub files from server. I got "java.lang.NoClassFoundException: DBAccessImpl_stub (no security manager: RMI class loader disabled). Did any of you have similar problem?
Thanks for any suggestion!
...Mike
 
Mark Spritzler
ranger
Sheriff
Posts: 17278
6
IntelliJ IDE Mac Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You must include the stubs with your client.jar.
Mark
 
Michael Sunny
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Mark! I figured it out. As one of the RMI principles, clients should be able to download the stub files from the server. So it's not necessary to include the stub files in clint.jar file!
 
Sac Patel
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Michael,
On My assignment there is a restriction on RMI that says
<code>
You must provide all classes pre-installed so that no dynamic class downloading occurs.
</code>
SO i think you have to include stubs in client.jar
 
Mark Spritzler
ranger
Sheriff
Posts: 17278
6
IntelliJ IDE Mac Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, because dynamic downloading requires you to have a web server. The assessors do not have a web server, so you must include the stubs with the client.jar.
Mark
 
Qusay Jaafar
Ranch Hand
Posts: 127
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I did not use till now jar file for compile and run classes. only java, javac and rmic.
There are client folder, server folder, db folder and data_db (which include only db.db).
Those folders contains only Source code.
To Compile:
javac -d classes suncertify\server\*.java
(where classes another folder contains only classes files)
Compilation for other folders of course the same.
Then: rmic -v1.2 -d classes
ncertify.server.DataRemoteImpl
of course, a stub created into server folder. Now, I took a copy of this stub to client folder.
Then: start rmiregistry
Then to start the server:
java -classpath .;c:\FBNfolder\classes suncertify.server.ConnectionFactory
HERE I got an exception which as i understand that ClassNotFoundException: suncertify.server.DataRemoteImpl_Stub
I still run it into one machine.
any idea what is happening please?
 
Ta Ri Ki Sun
Ranch Hand
Posts: 442
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
of course, a stub created into server folder. Now, I took a copy of this stub to client folder.

when you say you took a copy to the client folder, do you mean you copied the stub itself or the entire directory structure?
 
Andrew Monkhouse
author and jackaroo
Marshal Commander
Pie
Posts: 11851
185
C++ Firefox Browser IntelliJ IDE Java Mac Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Qusay
It looks like you the RMI Registry does not know where your stub files are.
Many people start the RMI Registry within their program, as that way
  • the RMI Registry inherits the same classpath as the application
  • there is one less step for the examiner to do


  • However, starting the RMI Registry externally can be a good thing as well, especially in real life (do you really want to be running 10 applications, with 10 RMI Registries).
    But if you start the RMI Registry manually, you have to think about the codebase.
    I think the command you need is:

    I dont remember if it needs that trailing backslash (or even if it accepts backslashes - it should).
    Regards, Andrew
     
    Qusay Jaafar
    Ranch Hand
    Posts: 127
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    First, to (Ta Ri Ki Sun), I mentioned it is only copy the stub, not the folder itself.
    Second to Andrew,
    I have a client folder (package) and let us say it is on a machine.
    Also, I have a server folder (package) and let say it is on another machine.
    Now, How can the client connects to the server to start rmiregistry automatically.
    That's only if I start the server and starts rmiregistry programatically like the code below:


    is this correct? or am I missing something here?
    By the way, shall the user keeps client folder and server folder in its machine, or what?
     
    Andrew Monkhouse
    author and jackaroo
    Marshal Commander
    Pie
    Posts: 11851
    185
    C++ Firefox Browser IntelliJ IDE Java Mac Oracle
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hi Qusay
    This seems a different set of problems to your earlier issues with getting a ClassNotFoundException when starting the server. Does this mean that you have resolved that problem, or that you are giving up on it for the moment and trying the alternative method?
    How can the client connects to the server to start rmiregistry automatically.

    Normally the client would not start the server or the RMI Registry. The normal sequence of events would be:
  • start the server (which may start the RMI Registry programatically, as many here have done)
  • start the client

  • Technically you could start the server from the client. You would then have to ensure that the user did not shut down the client which is also acting as a server. I personally dont like this concept, but if you would like me to expand on it, I will.
    The code you have for starting the RMI Registry and registring your service is correct. This should work, and you should not need to worry about setting the codebase (so you should not see that ClassNotFoundException) or having a policy file.
    When you are happy with this way of doing things, you might want to think about
  • allowing the user to change the port for the RMI Registry (which will require at least two changes in the code snippet you provided)
  • removing hard coded magic numbers (1099) and using constants
  • making your service name a bit more unique than "ServerService".


  • By the way, shall the user keeps client folder and server folder in its machine, or what?

    Probably the examiner will run everything on the one machine, so both client and server folders (do you mean package instead of folder?) on the same machine.
    If you want to allow for proper separation of client and server (server on one machine, client on another) then on the client machine you probably only need the server folder with the stub files in it - you should not need the other files that are currently in the server folder.
    Regards, Andrew
     
    Qusay Jaafar
    Ranch Hand
    Posts: 127
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    my first problem which is related to start rmiregistry (I am not sure if it is solved or not ).
    (in FBN folder I have two folders, source and classes)
    before, I start rmiregistry manually:
    C:\FBN>start rmiregistry
    C:\FBN>java -classpath .;C:\FBN\classes suncertify.server.ConnectionFactory
    C:\FBN>java -classpath .;C:\FBN\classes suncertify.client.MainLauncher
    Dialog appears and the user click on "Network Connection" button
    ( failed and get ClassNotFoundException ) which is the stub of course.
    Then I changed direcotry one step deep:
    C:\FBN\classes>start rmiregistry
    C:\FBN>java -classpath .;C:\FBN\classes suncertify.server.ConnectionFactory
    C:\FBN>java -classpath .;C:\FBN\classes suncertify.client.MainLauncher
    Dialog appears and the user click on "Network Connection" button
    ( failed and get the following message )
    writing aborted; java.io.NotSerializableException: suncertify.server.DataAdapter
    Now, when I start rmiregistry programatically like the code above:
    C:\FBN>java -classpath .;C:\FBN\classes suncertify.server.ConnectionFactory
    C:\FBN>java -classpath .;C:\FBN\classes suncertify.client.MainLauncher
    Dialog appears and the user click on "Network Connection" button
    ( failed and get the following message )
    writingaborted; java.io.NotSerializableException: suncertify.server.DataAdapter
    which it means the both ways I got same message. help here please?
    I am happy to start rmiregistry programatically. It is easier for every one. I will do what you suggest about the port and the service name, but why we need a unique name in our assignment?
    So, about client in a machine and server in another machine, I will create client.jar and server.jar and in this case both cases for the examiner will be helpful, do you think so?
     
    Andrew Monkhouse
    author and jackaroo
    Marshal Commander
    Pie
    Posts: 11851
    185
    C++ Firefox Browser IntelliJ IDE Java Mac Oracle
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hi Qusay
    ClassNotFoundException is usually because of not setting the codebase (see my example higher up).
    NotSerializableException means that you are probably trying to return an instance of DataAdapter class that does not:
  • extend UnicastRemoteObject and implement Remote, or
  • implement Serializable


  • DataAdapter must do one or the other in order for it to be "returned" over the RMI interface.
    You probably do not want DataAdapter to be serializable. If the class were serializable, then the entire class would be shipped over to the client, and would run on the client side. (I did actually toy with doing this - I could have verified whether a client had locked a record before calling unlock without any network traffic - but I decided against it).
    Regards, Andrew
     
    Andrew Monkhouse
    author and jackaroo
    Marshal Commander
    Pie
    Posts: 11851
    185
    C++ Firefox Browser IntelliJ IDE Java Mac Oracle
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hi Qusay
    why we need a unique name in our assignment?

    You dont have to. As long as you document clearly in the user documentation what the name of your service is, and that no other application may use it.
    I went overboard with my assignment, trying to cater for every possibility that could affect the running of the server. So I could start the RMI Registry programatically or use an already running RMI Registry. I could use any port the user desired. And I had a very unique name for my service so that if the examiner wanted to run my application on an existing RMI Registry, I did not have to worry about the name clashing. (I did stop short of allowing the user to change the service name though - but I would have done it if the instructions had allowed it :roll: )
    But most of what I did was what I would consider "friendly" programming - trying to make life easy for the examiner (or for the client / system adminstrator). Others here have passed with very good marks with almost no flexibility (could not change port, could only run with inbuilt RMI server).
    Regards, Andrew
     
    • Post Reply
    • Bookmark Topic Watch Topic
    • New Topic