I've just started RMI programming recently and had complete most of the parts for the assignment requirements. But there was this question in my head where one of the requirements is supporting multiple threads. Basically in which part should the multi thread be implemented?
Should I make the Server class Runnable or make the objects that are being created in the Server class Runnable?
Here's the code of my Server class:
public class Server {
public static void main(String args[]) {
String portNum = "4444";
try {
Account_Server_Controller accountController = new Account_Server_Controller();
BookCategory_Server_Controller categoryController = new BookCategory_Server_Controller();
Book_Server_Controller bookController = new Book_Server_Controller();
BookActivity_Server_Controller bookActivityController = new BookActivity_Server_Controller();
startRegistry(Integer.parseInt(portNum));
Naming.rebind(ServerLocater.getAccountRegistryURL(), accountController);
Naming.rebind(ServerLocater.getBookRegistryURL(), bookController);
Naming.rebind(ServerLocater.getCategoryRegistryURL(), categoryController);
Naming.rebind(ServerLocater.getBookActivityRegistryURL(), bookActivityController);
System.out.println("Server is Ready.");
} catch (NumberFormatException | MalformedURLException | RemoteException e) {
System.out.println("Exception in Server.main: " + e);
}
}
private static void startRegistry(int rmiPortNum) throws RemoteException {
try {
Registry registry = LocateRegistry.getRegistry(rmiPortNum);
registry.list();
} catch (RemoteException ex) {
System.out.println("RMI registry is not located at port " + rmiPortNum);
Registry registry = LocateRegistry.createRegistry(rmiPortNum);
System.out.println("RMI registry created at port " + rmiPortNum);
}
}
}
No. You don't have to start any threads or implement any Runnables.
You just have to make sure that your remote method implementations are thread-safe.
Related
I am willing to use CoAP protocol for implementing a java push-based messaging system. Particularly in such a system, a client opens just once a connection with a server (resource) and the server pushes messages (‘non-confirmable’) with a specific rate (e.g., 10 messages per second). However I did not find any existing solution to build the above system.
What I found is the pull-based messaging system. For such case, a client opens a connection with the server and after some time the client sends a GET request. Then, the server handles the request and pushes (as response) a single message to the client.
Hence, for each GET, I have a single message as response -- i.e., a two-way asynchronous interaction.
Does anybody have any idea on how to implement the push-based messaging system using CoAP? Does CoAP supports such a system?
The pull-based messaging system is implemented as follows
Server Part
public class CoapServerPartAsync extends CoapServer {
private static final int COAP_PORT = 8891;
private static int incrementor = 1;
/*
* Application entry point.
*/
public static void main(String[] args) {
try {
// create server
CoapServerPartAsync server = new CoapServerPartAsync();
// add endpoints on all IP addresses
server.addEndpoints();
server.start();
} catch (SocketException e) {
System.err.println("Failed to initialize server: " + e.getMessage());
}
}
/**
* Add endpoints listening on default CoAP port on all IP addresses of all network interfaces.
*
* #throws SocketException if network interfaces cannot be determined
*/
private void addEndpoints() throws SocketException {
InetSocketAddress bindToAddress = new InetSocketAddress("127.0.0.1", COAP_PORT);
addEndpoint(new CoapEndpoint(bindToAddress));
}
/*
* Constructor for a new Hello-World server. Here, the resources
* of the server are initialized.
*/
public CoapServerPartAsync() throws SocketException {
// provide an instance of a Hello-World resource
add(new HelloWorldResource());
}
/*
* Definition of the Hello-World Resource
*/
class HelloWorldResource extends CoapResource {
public HelloWorldResource() {
// set resource identifier
super("helloWorld");
// set display name
getAttributes().setTitle("Hello-World Resource");
}
#Override
public void handleGET(CoapExchange exchange){
// respond to the request
System.out.println("Push [Hello World!"+(incrementor)+"]");
exchange.respond("Hello World!"+(incrementor));
incrementor++;
}
}
}
Client Part
public class CoapClientPartAsync {
// static boolean getResponse = false;
public static void main(String args[]) {
CoapClient client = new CoapClient("coap://127.0.0.1:8891/helloWorld").useNONs();
while(true){
CoapObserveRelation relation = client.observe(
new CoapHandler() {
#Override public void onLoad(CoapResponse response){
String content = response.getResponseText();
System.out.println("NOTIFICATION: " + content);
}
#Override public void onError() {
System.err.println("OBSERVING FAILED (press enter to exit)");
}
});
try {
Thread.sleep(1000);
}catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Hi all I have question related with Pyro4 and Java. My question is how can I send information between RMI server in Java and clients RMI in Python?.
This is my code, I don't have any errors but I can't send anything.
Java Code:
implements ReceiveMessageInterface
{
int thisPort;
String thisAddress;
Registry registry; // rmi registry for lookup the remote objects.
// This method is called from the remote client by the RMI.
// This is the implementation of the �gReceiveMessageInterface�h.
public void receiveMessage(String x) throws RemoteException
{
System.out.println(x);
}
public RmiServer() throws RemoteException
{
try{
// get the address of this host.
thisAddress= (InetAddress.getLocalHost()).toString();
}
catch(Exception e){
throw new RemoteException("can't get inet address.");
}
thisPort=3232; // this port(registry�fs port)
System.out.println("this address="+thisAddress+",port="+thisPort);
try{
// create the registry and bind the name and object.
registry = LocateRegistry.createRegistry( thisPort );
registry.rebind("rmiServer", this);
}
catch(RemoteException e){
throw e;
}
}
static public void main(String args[])
{
try{
RmiServer s=new RmiServer();
}
catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
}
And this is my code in Python:
import Pyro4
proxy=Pyro4.core.Proxy("PYRONAME:PhDJara/127.0.1.1")
print("5*11=%d" % proxy.multiply(5,11)) print("'x'*10=%s" %
proxy.multiply('x',10))
Thanks for your help.
jarain78
What makes you think that you should be able to connect these two?
Pyro4 is only conceptually similar to Java's RMI, but they're two totally different protocols. You cannot connect them directly.
If you want to write a Python client using Pyro and talk to a server, that server has to be a Pyro server. The only way to create one in Java is by using Jython + Pyro.
I'm trying to get a RMI program to work. So far, the server starts up correctly but the client fails casting the remote object to the interface.
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException:
com.sun.proxy.$Proxy0 cannot be cast to MonitorClient.InterfaceMonitor
All other answers I've found are for cases where the end user has cast the equivalent of InterfaceMonitorImpl (unknown to the client) instead of the Interface instead. This is not my case and I'm really at a loss here — RMI is nightmare-ish.
Server side
Main:
InterfaceMonitor obj;
try {
LocateRegistry.createRegistry(1099);
InterfaceMonitor stub = (InterfaceMonitor) UnicastRemoteObject.exportObject(new InterfaceMonitorImpl(), 0);
Registry registry = LocateRegistry.getRegistry();
registry.bind("imon", stub);
System.out.println("Server ready");
} catch (RemoteException | AlreadyBoundException ex) {
System.out.println("Server error: " + ex.toString());
}
InterfaceMonitor.java:
public interface InterfaceMonitor extends Remote {
int checkAge() throws RemoteException;
}
InterfaceMonitorImpl.java:
public class InterfaceMonitorImpl implements InterfaceMonitor {
public InterfaceMonitorImpl() throws RemoteException {
}
#Override
public int counter() throws RemoteException {
return 10;
}
}
Client side
try {
Registry reg = LocateRegistry.getRegistry(null);
InterfaceMonitor im = (InterfaceMonitor) reg.lookup("imon");
int counter = im.counter();
System.out.println("Counter: " + counter);
} catch (NotBoundException | RemoteException ex) {
Logger.getLogger(MonitorGUI.class.getName()).log(Level.SEVERE, null, ex);
}
The InterfaceMonitor.java is also on the client side.
Thanks for your time!
Obviously you must have two copies of InterfaceMonitor: one in MonitorClient and one in what may be something like MonitorServer. That makes two different classes. Not two copies of the same class. The class name, package, method declarations, inheritance, ... all have to be the same.
I'm frensh so sorry for my english.
I'm trying to start a server rmi but the application stop whitout error :
Here my code:
public class Server {
public static void main(String[] args) {
try {
RemoteFunction skeleton = (RemoteFunction) UnicastRemoteObject.exportObject(new FunctionImpl(), 0);
int port = Integer.parseInt(Jndiprop.getString("port"));
Registry registry = LocateRegistry.createRegistry(port);
registry.rebind(Jndiprop.getString("url"), skeleton);
System.out.println("Rmi start");
} catch (Exception e) {
e.printStackTrace();
}
}
}
the port and the url are ok.
Someone can help me ?
You must store the Registry in a static variable. Otherwise it can be garbage-collected, which leads to a train of events that allows the whole JVM to exit.
I am trying to start/stop an Endpoint web service in a separate thread from my main program with the click of a button. Starting works fine, i am able to access all my WebMethods without issue. The problem is, when i click the stop button to try and stop the web service endpoint, i get an exception and i don't know what it is. I am new to Java as well.
Thanks in advance.
Excetion thrown at 'ep.stop()':
WebService Running On: http://0.0.0.0:9898/
Exception in thread "Thread-0" java.lang.NullPointerException
at com.sun.xml.internal.ws.transport.http.server.ServerMgr.removeContext(Unknown Source)
at com.sun.xml.internal.ws.transport.http.server.HttpEndpoint.stop(Unknown Source)
at com.sun.xml.internal.ws.transport.http.server.EndpointImpl.stop(Unknown Source)
at com.simba.Server.startWebSrv(Server.java:27)
at com.simba.Server.run(Server.java:13)
Server class:
import javax.xml.ws.Endpoint;
public class Server extends Thread {
public volatile boolean active = true;
private Endpoint ep;
private String ip = "0.0.0.0";
public void run(){
ep = Endpoint.publish("http://" + ip + ":9898/", new SWS());
startWebSrv();
}
private void startWebSrv(){
synchronized(this){
try {
while (active) {
System.out.println("WebService Running On: http://" + ip + ":9898/");
wait();
}
}catch (InterruptedException e) {
e.printStackTrace();
}finally{
if(!active){
ep.stop();
System.out.println("WebService Stopped!");
}
}
}
}
}
How i am attempting to stop the service/thread from my main program:
MenuItem mntmToggleWebservice = new MenuItem(menu_4, SWT.NONE);
mntmToggleWebservice.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
synchronized(srv){
srv.active = false;
srv.notifyAll();
}
}
});
mntmToggleWebservice.setText("Toggle WebService");
Problem solved!
Don't use '0.0.0.0'. For some reason, creating the service on '0.0.0.0' works (uses the machine's actual ip), but Endpoint.stop() doesn't not play well with it.
Instead I just used 'System.getEvn('COMPUTERNAME')' and create the service with the machine name.
You can use the "input" to block the run of program
public class ServiceMain {
private static void DoNothing() {
}
public static void main(String[] args) {
String address = "http://127.0.0.1:7775/hb";
Endpoint ep = Endpoint.publish(address, new ServiceImp());
Scanner scanIn=new Scanner(System.in);
System.out.println("Web Service Release Successfully!");
while(!scanIn.next().equals("stop")){
DoNothing();
}
scanIn.close();
ep.stop();
System.out.println("Web Service Close Successfully!");
}
}