Generating Prime Numbers with Java RMI using HTTP Server

Create simple HTTP Server

package http;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.URI;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;

import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;

public class HttpServerLite {
  public static void main(String[] args) throws IOException {
    InetSocketAddress addr = new InetSocketAddress(9876);
    HttpServer server = HttpServer.create(addr, 0);

    server.createContext("/", new MyHandler());
    server.start();
    System.out.println("Server is listening on port 9876" );
  }
}

class MyHandler implements HttpHandler {
	public void handle(HttpExchange exchange) throws IOException {
		String requestMethod = exchange.getRequestMethod();
		if (requestMethod.equalsIgnoreCase("GET")) {
			try
			{
				URI uri = exchange.getRequestURI();
				Path path = FileSystems.getDefault().getPath("../jar/",uri.getPath().substring(1));
				byte[] b = Files.readAllBytes(path);
				Headers responseHeaders = exchange.getResponseHeaders();
				responseHeaders.set("Content-Type", "application/java-archive");
				responseHeaders.set("Content-Length",
						((Integer) b.length).toString());
				exchange.sendResponseHeaders(200, 0);
	
				OutputStream responseBody = exchange.getResponseBody();
				responseBody.write(b);
				responseBody.close();
			}catch(Exception e)
			{
				Headers responseHeaders = exchange.getResponseHeaders();
				responseHeaders.set("Content-Type", "text/html");
				exchange.sendResponseHeaders(404, 0);
				OutputStream responseBody = exchange.getResponseBody();
				responseBody.write("error: file not found".getBytes());
				responseBody.close();
			}
		}
	}
}

The HTTP server will look for files in a directory called jar which is located one level above current directory.
NOTE: For the http server to compile in Eclipse, make sure the JRE System Library is set to “Workspace default JRE (jre7)”
Create PrimeNumber RMI server

package server;

import java.util.List;

public interface PrimeTask {
	List<Long> getListofPrimes(Long n);
	Boolean isPrime(Long n);
}
package server;

import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.List;

public interface PrimeCompute extends Remote {
	List<Long> getListofPrimes(PrimeTask t, Long n) throws RemoteException;
	Boolean isPrime(PrimeTask t, Long n) throws RemoteException;
}
package server;

import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.List;

public class PrimeComputeEngine implements PrimeCompute{
	public List<Long> getListofPrimes(PrimeTask t, Long n) throws RemoteException
	{
		return t.getListofPrimes(n);
	}

	public Boolean isPrime(PrimeTask t, Long n) throws RemoteException
	{
		return t.isPrime(n);
	}

	public static void main(String[] args) {
		if (System.getSecurityManager() == null) {
            System.setSecurityManager(new SecurityManager());
        }
		try
		{
			String name = "PrimeCompute";
			PrimeCompute engine = new PrimeComputeEngine();
			PrimeCompute stub =
	                (PrimeCompute) UnicastRemoteObject.exportObject(engine, 0);
			Registry registry = LocateRegistry.getRegistry();
	        registry.rebind(name, stub);
	        System.out.println("ComputeEngine bound");
		} catch (Exception e) {
            System.err.println("ComputeEngine exception:");
            e.printStackTrace();
        }
	}
}

Create a jar file called PrimeCompute.jar with the following classes: PrimeCompute and PrimeTask. Make sure to save it to the jar folder because the HTTP server will read from the jar folder.

For step by step instructions, go to Generating Prime Numbers with Java RMI

Create PrimeNumber RMI client

package client;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import server.PrimeTask;

class PrimeObject implements PrimeTask, Serializable
{
	private static final long serialVersionUID = 8954L;

	public PrimeObject()
	{

	}

	@Override
	public List<Long> getListofPrimes(Long n) {
        List<Long> temp = new ArrayList<Long>();

        for (long i = 1; i <= n; i++)
        {
            if (isPrime(i))
                temp.add(i);
        }
        return temp;
	}

	@Override
	public Boolean isPrime(Long n) {
        if (n == 1)
            return false;
        else if (n < 4)
            return true;
        else if (n % 2 == 0)
            return false;
        else if (n < 9)
            return true;
        else if (n % 3 == 0)
            return false;
        else
        {
            int r = (int)Math.floor(Math.sqrt(n));
            int f = 5;
            while (f <= r)
            {
                if (n % f == 0)
                    return false;
                if (n % (f + 2) == 0)
                    return false;
                f = f + 6;
            }
        }
        return true;
	}
}
package client;

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.List;

import server.PrimeCompute;
import server.PrimeTask;

public class PrimeNumberUtils {
	public static void main(String[] args) {
		if (System.getSecurityManager() == null) {
            System.setSecurityManager(new SecurityManager());
        }
		
		try {
			String name = "PrimeCompute";
			Registry registry = LocateRegistry.getRegistry(args[0]);
			PrimeCompute prime = (PrimeCompute) registry.lookup(name);
			PrimeTask o = new PrimeObject();
			Long l = 1000000L;
			List<Long> p = prime.getListofPrimes(o, l);
			for (Long n : p) {
				System.out.println(n);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

Add reference to the PrimeCompute.jar so the client will compile.

Create a jar file called PrimeObject.jar with the following classes: PrimeObject. Make sure to save it to the jar folder because the HTTP server will read from the jar folder.

Create Security Policy
Create a file called server.policy (and put it in your server project directory). Create a file called client.policy (and put it in your client project directory). Both server.policy and client.policy contains the following:

grant{
permission java.security.AllPermission;
};

Configurations for Java Applications
PrimeNumberServer

Make sure the VM arguments has the following:

-Djava.security.policy=server.policy -Djava.rmi.server.codebase="http://localhost:9876/PrimeCompute.jar http://localhost:9876/PrimeObject.jar"

Replace localhost with your http webserver address.

PrimeNumberClient

Make sure the VM arguments has the following:

-Djava.security.policy=client.policy

HTTPServerLite
No configuration needed.

Running the apps
Run the following in order:
1) rmiregistry
2) HTTP Server
3) PrimeNumberServer
4) PrimeNumberClient

Generating Prime Numbers with Java RMI

Code for server

package server;

import java.util.List;

public interface PrimeTask {
	List<Long> getListofPrimes(Long n);
	Boolean isPrime(Long n);
}
package server;

import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.List;

public interface PrimeCompute extends Remote {
	List<Long> getListofPrimes(PrimeTask t, Long n) throws RemoteException;
	Boolean isPrime(PrimeTask t, Long n) throws RemoteException;
}
package server;

import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.List;

public class PrimeComputeEngine implements PrimeCompute{
	public List<Long> getListofPrimes(PrimeTask t, Long n) throws RemoteException
	{
		return t.getListofPrimes(n);
	}

	public Boolean isPrime(PrimeTask t, Long n) throws RemoteException
	{
		return t.isPrime(n);
	}

	public static void main(String[] args) {
		try
		{
			String name = "PrimeCompute";
			PrimeCompute engine = new PrimeComputeEngine();
			PrimeCompute stub =
	                (PrimeCompute) UnicastRemoteObject.exportObject(engine, 0);
			Registry registry = LocateRegistry.getRegistry();
	        registry.rebind(name, stub);
	        System.out.println("ComputeEngine bound");
		} catch (Exception e) {
            System.err.println("ComputeEngine exception:");
            e.printStackTrace();
        }
	}
}

Code for client

package client;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import server.PrimeTask;

class PrimeObject implements PrimeTask, Serializable
{
	private static final long serialVersionUID = 8954L;

	public PrimeObject()
	{

	}

	@Override
	public List<Long> getListofPrimes(Long n) {
        List<Long> temp = new ArrayList<Long>();

        for (long i = 1; i <= n; i++)
        {
            if (isPrime(i))
                temp.add(i);
        }
        return temp;
	}

	@Override
	public Boolean isPrime(Long n) {
        if (n == 1)
            return false;
        else if (n < 4)
            return true;
        else if (n % 2 == 0)
            return false;
        else if (n < 9)
            return true;
        else if (n % 3 == 0)
            return false;
        else
        {
            int r = (int)Math.floor(Math.sqrt(n));
            int f = 5;
            while (f <= r)
            {
                if (n % f == 0)
                    return false;
                if (n % (f + 2) == 0)
                    return false;
                f = f + 6;
            }
        }
        return true;
	}
}
package client;

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.List;

import server.PrimeCompute;
import server.PrimeTask;

public class PrimeNumberUtils {
	public static void main(String[] args) {
		try {
			String name = "PrimeCompute";
			Registry registry = LocateRegistry.getRegistry(args[0]);
			PrimeCompute prime = (PrimeCompute) registry.lookup(name);
			PrimeTask o = new PrimeObject();
			Long l = 1000000L;
			List<Long> p = prime.getListofPrimes(o, l);
			for (Long n : p) {
				System.out.println(n);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

Eclipse with all the java files

Create jar for RMI codebase


Start rmiregistry

Create Java Application for server

Make sure the VM Arguments has the following

-Djava.rmi.server.codebase=file:/C:\RMI\PrimeNumbersRMI\PrimeCompute.jar

Replace C:\RMI\PrimeNumbersRMI\PrimeCompute.jar with your path

Create Java Application for Client

Make sure the Program Arguments point to server. In this case, it is localhost because the server and client is run from the same machine.
Make sure the VM Arguments has the following

-Djava.rmi.server.codebase=file:/C:\RMI\PrimeNumbersRMI\PrimeCompute.jar

Replace C:\RMI\PrimeNumbersRMI\PrimeCompute.jar with your path

Run Java Application for server first, then run Java Application for client