Wenn ich die compute-Method über den Client aufrufe, endet der mit einer NULL-Pointer exception, die für mich total unerklärlich ist, weil ich in einer einfachern Version wo der Server die Funktion selbst bereitstellt alles gut funktioniert. Der andere Service funktioniert auch gut.
Mein Code:
ProxyServer
GeneralProxy
Server
ComputeClient
ComputeService
Mein Code:
Java:
import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
public class ProxyComputeServer extends GeneralProxy implements ComputeService{
private Server backgroundServer;
public ProxyComputeServer(Server backgroundServer) throws RemoteException, AlreadyBoundException {
super(backgroundServer, Server.computeServiceName, "Computeproxy");
Registry registry = LocateRegistry.getRegistry();
ComputeService computeSort = (ComputeService) UnicastRemoteObject.exportObject(this, 0);
registry.bind(Server.computeServiceName, computeSort);
}
/**
* The boolean rightToCompute should simulate a right checking system.
* @param inputString
* @param rightToSort
* @return
* @throws RemoteException
*/
@Override
public String compute(int intputTime, boolean rightToCompute) throws RemoteException {
if(rightToCompute) return backgroundServer.compute(intputTime);
return "Sorry, you don't have the right to compute something.";
}
}
Java:
import java.io.Closeable;
import java.io.IOException;
import java.rmi.Remote;
public abstract class GeneralProxy implements Closeable, Remote{
protected Server backgroundServer;
private String serviceName;
private String proxyName;
public GeneralProxy(Server backgroundServer, String serviceName, String proxyName) {
this.backgroundServer=backgroundServer;
this.serviceName=serviceName;
this.proxyName=proxyName;
}
@Override
public void close() throws IOException {
backgroundServer.quitProxy(proxyName, serviceName, this);
}
}
Java:
/**
* A two instant server with 2 Services.
*/
import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.NotBoundException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.Arrays;
import java.util.Scanner;
public class Server {
private int name;
public Server(int name) {this.name=name;}
public static String sortServiceName="strsort";
public static String computeServiceName="compute";
public void quitProxy(String name, String serviceName, Remote closer) throws RemoteException{
System.out.println("quit");
Registry registry = LocateRegistry.getRegistry();
try {
UnicastRemoteObject.unexportObject(closer, false);
System.out.println("Unbind "+serviceName+".");
registry.unbind(serviceName);
} catch (NotBoundException e) {
throw new RemoteException("Could not unregister service, quiting anyway", e);
}
new Thread() {
@Override
public void run() {
System.out.println("Shutting down Server "+name+" ...");
try {
sleep(2000);
} catch (InterruptedException e) {
// I don't care
}
System.out.println("done (Server "+name+" closed)");
System.exit(0);
}
}.start();
}
public static void main(String args[]) {
try {
Server bigServer = new Server(1);
LocateRegistry.createRegistry(1099);
ProxyComputeServer computeProxy=new ProxyComputeServer(bigServer);
ProxySortServer sortProxy=new ProxySortServer(bigServer);
System.out.println("Server ready");
try (Scanner sc = new Scanner(System.in);){
if(sc.nextLine().equals("shutdown")){
computeProxy.close();
sortProxy.close();
}
}
} catch (Exception e) {
System.err.println("Server exception: " + e.toString());
e.printStackTrace();
}
}
public String compute(int inputTime) {
try {
Thread.sleep(inputTime*1000);
} catch (InterruptedException e) {
return "Server "+name+": The computation couldn't be completed.";
}
return "Server "+name+": You have waited "+inputTime+" seconds.";
}
public String sort(String inputString) {
char[] chars = inputString.toCharArray();
Arrays.sort(chars);
return "Server "+name+": "+(new String(chars));
}
}
Java:
/**
* This client lets the user compute Staff.
*/
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.Scanner;
import java.util.concurrent.ThreadLocalRandom;
public class ComputeClient {
private ComputeClient() {}
public static void main(String[] args) {
String host = args[0];
System.setProperty("java.rmi.server.hostname",host);
try {
Registry registry = LocateRegistry.getRegistry(host);
ComputeService stubcompute = (ComputeService) registry.lookup("compute");
boolean noUserInput=true;
try (Scanner sc = new Scanner(System.in);){
noUserInput=false;
System.out.println("How long should the calculation take?");
int i=sc.nextInt();
String s=stubcompute.compute(7, true);
System.out.println(s);
}
if(noUserInput){
System.out.println("Something went wrong with the input. Enjoy this computation.");
System.out.println(stubcompute.compute(ThreadLocalRandom.current().nextInt(1, 21), true));
}
} catch (Exception e) {
System.err.println("Client exception: " + e.toString());
e.printStackTrace();
}
}
}
Java:
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface ComputeService extends Remote{
String compute(int inputTime, boolean rightToCompute) throws RemoteException;
}