Goal: I have client-server program in which client and server runs in different jvms.
To test the same, I want to invoke the Server in a different JVM programatically and then use current jvm to run the client and execute different C/S tests.
Is there any way I can execute a method or run Java commands in different jvm programatically?
1) The most powerful tool in java to run process is ProcessBuilder:
ProcessBuilder pb = new ProcessBuilder("java", "-server", "-jar", "yourJar.jar");
Process p = pb.start();
Than using Process you are able to manipulate child process e.g. read InputStream, destroy e.t.c.
2) If you are able to edit both source code review this question to build efficient communication between JVM on the same host.
If you cannot change code, simply create own loader which load Server and implements inter JVM communication and invoke methods you need, because it in the same JVM space.
You can run virtually any command which you otherwise run manually using
Runtime.getRuntime().exec(command);
For more refer to Runtime.getRuntime().exec(...) documentation.
But also note that running any platform specific command using exec will rob your program its platform independent nature.
Sometime back I saw someone using "mv" to move a file. That made the entire program to Unix-based OS specific. Charm of Java or any virtual machine based language is its platform independent nature.
You can use command line:
Runtime.getRuntime().exec("java -server MyServer")
or if you want to build some more complicated call just use http://commons.apache.org/exec/ to build and run program.
From what I know, this is not possible with plain java. Probably grid enabled frameworks could provide a way of running a java program on multiple JVMs. A similar problem was resolved here:
how-to-run-a-java-file-project-in-remote-jvm-which-is-present-in-other-network
Related
I've been trying to code an app that allows me to open multiple Console sessions (in windows that would be cmd.exe) in a Tabbed fashion way.
One of the most important references I've found is in the following URL where I was able to get a TextAreaOutputStream code to be able to read the STDOUT fron the Process, but this and most of the references around the internet does not solve/fix the issue I'm dealing with.
Reference: Create Java console inside a GUI panel
Even when redirecting the STDOUT, STDERR and STDIN caused me some troubles, the worst part comes when the command you type within the Java Console in one of the tabs executes a command that creates a child process, it's here when my Java applications loses control because a new process was created in the background. Basically, the new child process is out of bound and I'm not able to receive or send any bytes to it and my app hangs.
JVM
MyTabbedConsoleApp
cmd.exe /k (I can still communicate with this one, no problems until here)
apptrack.exe (a child process out of bound from my app, no communication with this, the app hangs)
I'm looking for a better way to create an app that pretty much mimics the Console environment.
You should use ProcessBuilder instead of Runtime as it is the recommended API to deal with operating systems processes.
Check the Changes to Runtime.exec topic for the Java 6u45 Release Notes.
The preferred way to create operating systems processes since JDK
5.0 is using java.lang.ProcessBuilder. The ProcessBuilder class has a much more complete API for setting the environment, working directory
and redirecting streams for the process.
How can i invoke batch file without fork in java?
I use NSSM command-line interface to install my product as windows service. I always use Runtime.exec() to operate with command-line. I bypass bytes from new process's streams and periodically check for it finish job. I wonder, if there is easy way to use command line? I don't need forked process, is there a way not to use it? I want just call some exec("command") function, which acts as simple procedure.
You cannot do the equivalent of Unix / Linux exec() syscall or the Posix shell exec command ... without forking ... in Java. It is not supported by the standard Java class libraries.
It may be possible to write a native code method to call the OS-provided native libraries to do an exec or equivalent. However, this could behave in unexpected ways (e.g. no shutdown hooks) and would definitely be non-portable. And in the case of Windows, I don't think it is possible to do the equivalent of UNIX exec without fork: source Wikipedia.
However, you can easily run a batch file from Java:
How do I run a batch file from my Java Application?
But I don't understand the point of doing an exec to run a batch file instead of the normal fork / exec ... which is what Runtime.exec() does under the covers. Perhaps if you explained, we could understand why you need to do it, and offer a suggestion.
I have several java processes running on a windows machine. I have a Java process which is supposed to monitor the other processes and periodically kill or restart new ones.
If I have a java process running com.foo.Main1 and one running com.foo.Main2 - how can my monitoring process find and kill just the Main2 process?
Update: I have some code that can execute a command line tasklist.exe and parse it, but no matter what I do, I only see the java.exe process, not which class is executing
Update 2: I do not have the ability to install non-java programs.
It's probably going to be a lot simpler using OS-specific tools and using Runtime.exec() to run them, but I'll try and give a platform independent answer:
It might be possible to do this platform independently using the Attach API. This comes with the JDK, so to use it just include tools.jar from your JDK on your program's classpath.
To get a list of virtual machines on the system, use VirtualMachine.list(). You can get/parse arguments from the virtual machine descriptor objects that are returned from this.
The attach API also allows you to load agents into already-running Java processes. Since you want to kill a Java process, you can write a Java agent that simply runs System.exit() (or if you really want it dead use Runtime.halt() instead) when the agent loads.
Once you identify the one you want to kill, attach to it and load the killer agent (the agent has to be built as a JAR file, accessible to the Java process it needs to be loaded into). Shortly after the agent is attached that process should die.
These links might help also:
An Oracle blog on the attach API
Package documentation for java.lang.instrument (has detailed instructions on how to build an agent JAR)
This is specific to Windows.
I was facing the same issue where I have to kill the specific java program using taskkill. When I run the java program, tasklist was showing the same program with Image name set as java.exe. But killing it using taskkill /F java.exe will stop all other java applications other than intended one which is not required.
So I run the same java program using:
start "MyProgramName" java java-program..
Here start command will open a new window and run the java program with window's title set to MyProgramName.
Now to kil this java-program use the following taskkill command:
taskkill /fi "MyProgramName"
Your Java program will be killed only. Rest will be unaffected.
We Have a Multi-threaded Application in JAVA which has multiple threads running in parallel. Now we want to run all these threads on a single core. Currently application is running on a system having more then one Cores.
We know there is a technique available ProcesAffinity in .Net Framework to set process affinity.
But we don't want to depend on .Net Framework, because our application is build in java.
Do we set Process affinity using Bat file and run our application executable jar file through Bat file?
Currently our application is running on Window XP. So we need a solution that should be working fine on XP platform.
EDIT:
It's possible: See Java thread affinity
Pure Java doesn't support running a thread on specific processor. Check the SO question linked above.
Personally, I don't think that the fact that this cannot be set in pure Java is a bad thing, as to me, how an app is run does very much depend on the OS, so therefore a OS-specific solution isn't a bad thing.
You can use the MS psexec utility to set the affinity:
psexec -a 1 java -jar myapplication.jar
Would instruct that all of the threads created by java would be run on the lowest CPU.
And this line would be your .BAT file...
You cannot do it in pure Java. But on some versions of Windows, you can do it via operating system utilities; see https://superuser.com/questions/309617/how-to-limit-a-process-to-a-single-cpu-core ... and you might be able to do this by calling native libraries via JNI.
Say I have a current running process known, how can I turn this into a Process object in Java?
The process is already running, so I don't want to spawn off another one, I just want to encapsulate it into a Process object that I can use within the java code.
Something along the lines of:
int pid = getPid();
Process proc = magicGetProcess(pid);
thanks
I don't think this is possible using only the builtin library. AFAIK, it is already non-trivial to get the running process' own PID (see the feature request and alternate mechanisms).
A quick look at the java.lang.Process class shows that you could go about writing your custom implementation of java.lang.Process using JNI and native code. Your custom class could then implement extra methods, such as the one in your question.
In *nix world grabbing exit code of a non-child process is not easy, because the exit code simply disappears together with the process as soon as the parent process has picked up the exit code of the child. You can attach to the running process using some tracing tool and pick up its exit code when the process dies. Most *nix OSes have command line tools which will let you do it (such as strace on Linux, truss on SunOS) in a non-intrusive way. However, you can only use them against your own processes or if you run as root. Another alternative is to configure audit subsystem of your OS to record exit codes of all processes.
You can't. Every operation in Process requires that the process is a child process. Not an arbitrary process.
what about using RMI? It it possible to pass a Process object to the Process which it is? Probably not, because Process is not Serializable