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.
Related
I have an application with GUI. GUI is used for settings management only. Now I need to turn this into Windows service. I thought of splitting my app into 2: service itself and GUI-tool for providing settings. Main problem is that I'm not sure, how this tools should "communicate". Settings are stored mostly in files, and after new settings applied, service should restart.
As for now, I thought of admin-tool sending few requests to service over TCP/IP, that also allows to control service from the network. Problem is that I need to hardcode, or use some text file, to set default port on which service would listen for admin-tool connections after it's installation.
May be there is any alternative solution, which is more suitable here?
You are creating a service. If all you need in the communication layer is being able to stop and start the services, then you don't need to open a port and start listening. The system gives you means to do that with commands that you can run. you are talking about windows, so for example you can run the command "sc start MyServiceName" to start service "MyServiceName". there is also a command called "net" which allows you to start and stop services. These OS commands can be then called from java code in various ways that are available to execute external code.
here is a link that shows how to do that with sc command, check the accepted answer: start-windows-service-from-java
here is another link that shows difference between two commands "sc" and "net": net-start-service-and-sc-start-what-is-the-difference
Note that "sc" supports starting services on remote machines: simplest-way-to-restart-service-on-a-remote-computer
Is it possible that a java program is running and it works on commands from another java program simultaneously running in same machine? For example: if a second java program sends a query database command to first running java program, the first one will execute a query in the database connected to it and reply back to second one.
Please help.
Thanks in advance.
You could use socket programming to do this.
Make a server and make it listen to incoming messages.
http://docs.oracle.com/javase/tutorial/networking/sockets/
You could learn about sockets from the above link.
It is possible.
Socket programming is good but in this case you have to implement synchronization and multi threading request handling.
Another way is using web service for storing data in db.
http://docs.oracle.com/javaee/6/tutorial/doc/gijvh.html
Probably you can use any of
remote invocations (RMI), see http://docs.oracle.com/javase/tutorial/rmi/
or
manged beans (JMX), see http://docs.oracle.com/javase/tutorial/jmx/
As already answered you can use socket proramming but you would have to implement your own protocol.
It should be easier to use RMI which lets you invoke remote methods as if they were local but it is limited to java.
A "bit" heavier (in resources and implementation) solution is using web services but it is a standard which is not limited to java world.
You can also use JMS but I think it should be overkill (you need a server such as activeMQ)
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.
Is there any way to call a certain method in a running java application?
Forexample: I have a java application running, Now I want to call a method uk.co.planetbeyond.chatservice.Stopper.stop() on the same instance of the application. Can I do that?
The easiest way to do this is using JMX. You just have to expose methods you want to call to MBean. Then you can use any JMX client you want to call the methods. You can either use JConsole that is a part of your JDK or create your own command line application.
There is also command line JMX client.
No.
You could however have your java application:
listen for input from the command line with new Scanner(System.in) (for example)
listen on a port for input using a variety of protocols, http being a common choice
watch for appearance of a file (lame, but it would work)
Once running, the JVM will only notice something it's looking for - ie it can only "pull"; you can't "push" anything into it
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.