I have a need to build a client application that will sit on different personal PC's and be able to be run offline in a stand alone environment. When it is online I want to be able to connect to a server that runs some methods against a central database for the client application (these methods can only be run when the client is connected to the server). To do this I thought I would build a client application and a server application. The client application can stand alone if not connected to the internet. If it is connected to the internet I would use RMI to be able to call some methods that the server application has server code. First question is will this work? Is it the best way to do this? I have build a quick little test client and server application to test how RMI works. The client does nothing more then call the server application and had it two numbers which the server application adds together and returns the sum. If I compile all of the code in a default package (using Eclipse) things seem to work (at least running both applicaitons on my local PC). But if I put the client in one package and the server in a seperate package I can't get anything to work. Here is the clinet application code:
package clientSide; import java.rmi.*; public class AddClient { /** * @param args */ public static void main(String[] args){
//Lets try setting up a security manager.. if (System.getSecurityManager() == null) { System.out.println("Security Manager was null, set one up"); System.setSecurityManager(new SecurityManager()); System.out.println("Security Manager is setup"); }
try{ System.out.println(""); System.out.println(""); String addServerURL = "rmi://" + args[0] + "/AddServer"; System.out.println("Using " + addServerURL + " to execute addServerIntf naming.lookup"); AddServerIntf addServerIntf = (AddServerIntf) Naming.lookup(addServerURL); System.out.println("This is the addition of two numbers"); System.out.println("The first number is:" + args[1]); double d1 = Double.valueOf(args[1]).doubleValue(); System.out.println("The second number is:" + args[2]); double d2 = Double.valueOf(args[2]).doubleValue(); System.out.println("The sum is: " + addServerIntf.add(d1, d2)); System.out.println(""); System.out.println("");
//Adding a second call to a different file String addServerURLTwo = "rmi://" + args[0] + "/AddServerTwo"; System.out.println("Using " + addServerURLTwo + " to execute the following"); AddServerIntfTwo addServerIntfTwo = (AddServerIntfTwo) Naming.lookup(addServerURLTwo); System.out.println("This is the addition of three numbers"); System.out.println("The first number is: " + d1); System.out.println("The second number is: " + d2); double d3 = 3; System.out.println("The third number is: " + d3); System.out.println("The sum is: " + addServerIntfTwo.addThree(d1, d2, d3)); System.out.println(""); System.out.println("");
//Just to make sure I can make the first call again //Recalling the first connection. System.out.println("Using " + addServerURL + " to execute the following"); System.out.println("This is the addition of two numbers again"); System.out.println("The sum of " + d1 + " and " + d2 + " is " + addServerIntf.add(d1, d2)); System.out.println(""); System.out.println(""); }catch (Exception e){ System.out.println("Exception in AddClient is as follows " + e); } } }
And the client.policy looks like this. The directory is to the location of my serverSide.jar and I have a....
grant codeBase "file:c:/Docume~1/steveh~1/WORKSP~1/simple~1"{ permission java.security.AllPermission; };
The server application looks like this....
package serverSide; import java.net.*; import java.rmi.*; public class AddServer {
/** * @param args */ public static void main(String[] args) { //Lets try setting up a security manager.. if (System.getSecurityManager() == null) { System.setSecurityManager(new SecurityManager()); }
try{ //The original code AddServerImpl addServerImpl = new AddServerImpl(); Naming.rebind("AddServer", addServerImpl);
//Adding a second lookup AddServerImplTwo addServerImplTwo = new AddServerImplTwo(); Naming.rebind("AddServerTwo", addServerImplTwo); }catch (Exception e){ System.out.println("Exception in addServer: " + e); } } }
The java generated stub code looks like this... package serverSide;
// Stub class generated by rmic, do not edit. // Contents subject to change without notice.
public final class AddServerImpl_Stub extends java.rmi.server.RemoteStub implements AddServerIntf, java.rmi.Remote { private static final long serialVersionUID = 2;
// Stub class generated by rmic, do not edit. // Contents subject to change without notice.
public final class AddServerImplTwo_Stub extends java.rmi.server.RemoteStub implements AddServerIntfTwo, java.rmi.Remote { private static final long serialVersionUID = 2;
This gives me a permissions error. I don't understand how to get aound the error and have the server code load up. I get the same permissions error when I try and run the client code.
But if I take the code out of packages and put everything into one file I can get it to load up and run on the same computer. But I can't take the code to a seperate server and get it to load up. Not sure why.