How to send commands to a subprocess - java

I am creating a simulation system which consists of a test harness creating multiple processes using ProcessBuilder. I would like to be able to send multiple commands to the seperate processes, and I've only thought of a couple options - neither of which seem very fun.
The first method would be to communicate between the parent process and the subprocesses using sockets, which is how the subprocesses communicate with each other. The other would be to use the Writer method, and I've been using the Reader method to read and print the intput stream from each process. I think that both of these would require a similar level of bookkeeping. Ideally it would be nice to call a function like you would for any subclass, but I know that just isn't how multi-process works.
Please let me know what you think the best way to implement this is!
Thanks,
David
Update: I ended up creating a server socket in the test harness that communicates with all of the sub-processes. Once the system is set up, it's as simple as adding a Message to a queue, which is then sent to the correct client.

This answer is in response to your statement:
"Ideally it would be nice to call a function like you would for any
subclass, but I know that just isn't how multi-process works."
If you want to, here is how you can actually do that, if the sub-processes are Java programs running on a JVM:
Use Remote Method Invocation. The wikipedia article has a small example of an RMI server and client.
In essence this works in the following way:
A server provides some services, via remote methods, by implementing a 'remote interface' (whose definition should be available the the client also)
When the server starts up, it creates an instance of the object that implements the service, and 'binds' it to an 'RMI Registry'
A client looks up the 'RMI Registry' for a remote object which it wants to call methods on, and obtains an object which appears to implement the remote interface.
Then the client can call methods on this object, and the RMI runtime ensures that the call makes it to the remote object, and the results are returned.
This seems to be an 'official' Hello World example:
http://docs.oracle.com/javase/1.5.0/docs/guide/rmi/hello/hello-world.html
The arguments of the call must be Serializable (so that they may be transmitted over the network). Usually, this should be as simple as appending implements Serializable to their type definition.

Related

Java: Send job to server for execution

I'm looking for a way to execute "jobs" on a remote server. Normally RMI would do just fine but as far as I know, that requires an actual implementation of the logic on the server. My problem is that I can't predefine the jobs on the server because I want them to be as generic as possible.
So what I have in mind is the following: the client has the implementation of a specific job he wants to have executed. This implementation would obviously have to follow a set of rules in order for the server to be able to work with it. The client packs it into an object of some kind, sends it to the server for execution, and waits for the result of whatever computation he asked for.
Is this possible with RMI? If not, is there something else that allows me to work this way?
Thank you for your time and insight.
You can use Dynamic code downloading using Java RMI but you will have to setup a server to holds clients task classes
As I unterstand your question the server does not 'know' the code to be executed in advance.
So what you could try is sending some runtime-interpretable code like groovy, javascript or python and use one of the many interpreters out there on the serverside.
For simpler executions UEL and the concrete JUEL might be worth a look
Any object that is serializable can be passed over RMI. You could wrap the logic in a serializable object, pass that to the server, and the server executes it (it could have an execute method for example that the server calls).
As mentioned in the comments here, the class you pass from the client to the server would need to be known to both the client and the server.

Java Client/Server Implementation

I have to make an university project that involves a client/server architecture.
There should be a server where a client can login and search or save some stuff.
What's the best way to implement a stuff like that?
I think it can be done using RMI or ServerSockets or even WebServices, but what's the easiest way to implement this project?
Using Web Sevrvices i think it can be troublesome the authentication/session handling, using ServerSockets i have done some tests where i pass some custom serialized objects, but It doesnt seem to me a good way to go.
Any help is appreciated
Since this is a project for university I will not post an solution, but give you an good direction.
The most basic Way (what may be a good thing for a university project, and for understanding th whole matter...) would be with the Server listening in his Mainthread on a ServerSocket for Requests to connect to the Server and then for every (correct) Request (you need to specify somehow what is correct in this case) starting a new Thread with a Socket connected to the Client. This Threads should be hosted in some sort of List or whatever in the Mainthread of the Server...
Update:
So if this Server provides different functionalities to its clients, which are of course methods in our Server Code, you can specify the Objects which are crated when a new Client connects (I'm calling these "ClientServerConnection" from now on, and which run in its own Thread) in the Way that the Server Object is passed to it, so if one of the "ClientServerConnection"s get a Request for whatever they can call the matching method on the Server-Object and give an according response to the client...
Here some pseudo-code:
in Server:
//request for Connection came in
ClientServerConnection csc = new ClientServerConnection(this, "and everything you need, at least client IP for connecting the socket");
csc.run(); //running in its own thread, of cause ClientServerConnection should extend Thread
connectionList.add(csc); //a list of the connections the Server holds
in ClientServerConnection:
//A request to the use a functionality of the Server come in, in the easiest way you are sending a String, and than trying to match it here
if(recievedString=="doWhatever"){
Server server.doWhatever(); //calling the according method on the Server Object you passed by creation of the ClientServerConnection Object
//now return something to the client, according to whatever the Method did
}else if(recievedString=="doSomethingElse"){
//same again, according to whatever the now requested method does
}else{
//the client requested something you do not provide, need some sort of handling here
}
Hope I got you right and this helps...
'Easy' is a subjective thing, depending on what you already have experience on.
If you have experience in Java related technologies, you could pick a tech stack like Servlets, JSP and JQuery, and use GAE to keep things simple from the 'troublesome' aspects you mentioned. GAE is a platform as a service so you woudnt have to worry about those things, as google takes care of the authentication, scaling etc. You can use GAE with PHP too, if you are into that.
I think RMI is the easiest solution since you define all your interfaces and don't have to care about the protocol used to communicate.
You can also use web service with SOAP which is also a RPC (remote procedure call ) interface.
But by using Socket and ServerSocket you will learn how to build a server / client software from scratch, which is very important to know (because this is the basics).

How to invoke method on the client from the server?

I'm developing a game both with sockets and RMI. The sockets part is done now i'm starting the RMI part. I want to be able to invite someone to play (A->B) and get the response(B->A).
Can you help me?
Thanks in advance. Cheers
EDIT : I've been researching and i'm currently implementing the client as a remote object as well (defining the interface and implementing it). I think it's called callback. Am I on the right path?
What i'm thinking is A calls a method on a remote object on B's computer. The server on B asks the client (which is also a server in the same computer) if it wants to play with A gets the response and returns it to A. Like i said i just finished implementing this game with tcp and udp sockets and now i have to do the same with RMI. There is no way for two clients to communicate directly, like they do over a TCP connection, using RMI, is there?
I've been researching and i'm currently implementing the client as a remote object as well (defining the interface and implementing it). I think it's called callback. Am I on the right path?
RMI is usually implemented as a client and a server. The client makes calls on the server which returns an object that can be consumed on the client. After reading the comments, they are correct that given the way you have described the problem, you will need to make the client also a RMI server. However, I'm not convinced this is necessary.
For example, let's say you have 2 clients that are both trying to play a game. The protocol might look something like this:
A contacts the server S. Server stores the address A and then returns a waiting-for-another-player type message to A.
A then contacts S every couple of seconds to see if the other player has shown up.
B then contacts S and a game is started between A and B. S returns a start-game message to B. S stores some sort of Game object in its memory (and/or on disk) which tracks the progress of the game.
The next time A contacts the server it also gets a start-game message.
So instead of the server needing to contact A or B, they poll every so often to get game updates and the like.
The method calls to S could also wait for the other player and not return until there is one. I think the polling option is better however because then S knows if A stops calling and A doesn't have to worry about S crashing and hanging.
Hope this helps.

Implementing client - masterserver/slaveserver application java

We have a string processing service (c++, uses stdin/out for in/output) that has different layouts, each layout runs separately (eventually will run on separate machines), each layout takes time to load, thats why it must keep running after first run.
I must implement a system with client that will ask the master server to connect it to a relevant slave server which actually runs the relevant layout service. The slave server will communicate the data passed from the client to the service, and when finished will become available on the master server for other clients.
The question is what is the best way to go about implementing the servers? Should I keep an open connection between slave/master until the process is complete to notify the master that the connection is over or keep some sort of var in a synchronized function to check that?
Any other important inputs (or other designs) I have overlooked are also very welcomed, Thanx!
Assuming you can't replace the C++ stuff, here is how I would do it off the top of my head.
I would setup one master server. That server would run a process that accepts requests (probably by HTTP, so it'd be a webservice) and I would have it read the request, parse out what it is, and then call the correct slave. Basically it acts as a proxy. Once it receives the response from the slave it forwards it back to the caller. The simplicity here means that if you start getting more of one type of request, you can set up additional servers for that and round-robin requests to them.
The slaves would be webservices that open the C++ program and forward input and retrieve output. That's all it would do.
I wouldn't bother keeping open connections (except between the slave and the C++ program based on your description). Just using a web request for this stuff will keep the connection between the master and the slave open during the process, but it shouldn't be a problem. This way you don't need to worry about this detail.
Now if I were you I would seriously look at reimplementing the C++ code in Java or calling it via JNI or something. If you can avoid it, I think avoiding the Java wrapper around C++ thing would be a good design goal. The Java could do whatever expensive process it is during start up once, and then hold things ready in memory like the C++ code does.
I hope this helps.
Depending on your scalability needs, you may want to take a look at the Java NIO package. This will give you a starting point to build a scalable, non-blocking server implementation.

Java IPC: GUI and Command Line

I would like to implement a command line interface for a Java application. This wouldn't be too difficult to do, except I would like the command line program to affect the state of another Java GUI program. So for example, I could type:
java CliMain arg1 arg2
And another running GUI instance would perform an appropriate action.
What is the easiest way of implementing something like this?
You could have the GUI application listen on a TCP port (on the localhost interface) and the CLI application would connect to it.
One way to do this would be to use REST over HTTP.
Another way is through JMX. It gives you a lot of stuff "for free" (in the simple case you just implement a bean and register it -- very simple), and is particularly well suited to this task.
you can have the GUI application(like an editor) listen on
1) clipboard event of a certain type
if the event is of a type that you are interested in, then get the clipboard contents.
2) server socket on a certain port
listen on a server socket. when the CLI program starts, it connects to the server socket at a known port, sends info and quits.
3) queue
you can enque from the CLI program and deque from the GUI program.
if you want to investigate further, many professional editors like emacs use the same mechanism. http://www.emacswiki.org/emacs/EmacsClient
Your application could be controlled via RMI. The application would implement a control interface, register its service on localhost and the command line application would get an rmi proxy and call the desired control methods...
Seems hard at first, but when you've tried out you'll quickly see how easy that is. And it also supports encryption via SSL. So you could secure your data exchange if there was security relevant data online.
The easiest way would be for the GUI to listen for commands on a TCP port. The command line would send commands, and the GUI would interpret them.
Maybe you could do it with named pipes as well, but I'm not sure how you'd go about implementing that in Java.

Categories