Invoke another Java Application through your application - java

I need a piece of code that can invoke another java application and send two strings as parameters. And then get String (This is a JSON string) response.
process = new ProcessBuilder("XYZ", Address , Type).start();
In this statement I don't understand what XYZ means, and how to define a particular method of Java Application to be called through this ProcessBuilder statement.

If you want to invoke another Java program (let's say it's called programName with arguments programArg1, programArg2), you'll probably have to use something along the lines of:
ProcessBuilder processBuilder = new ProcessBuilder("java", "programName", programArg1, programArg2);
Process process = processBuilder.start();
p.waitFor(); // If you need to wait until it finishes execution
Take a look at for instance this question to see how to read the program's output (in case it writes it through System.out): How to redirect Process Builder's output to a string?

Related

Create process with method called in Java [duplicate]

Is there a way to start a process in Java? in .Net this is done with for example:
System.Diagnostics.Process.Start("processname");
Is there an equivalent in Java so I can then let the user find the application and then it would work for any OS?
http://www.rgagnon.com/javadetails/java-0014.html
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.file.Paths;
public class CmdExec {
public static void main(String args[]) {
try {
// enter code here
Process p = Runtime.getRuntime().exec(
Paths.get(System.getenv("windir"), "system32", "tree.com /A").toString()
);
// enter code here
try(BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
String line;
while ((line = input.readLine()) != null) {
System.out.println(line);
}
}
} catch (Exception err) {
err.printStackTrace();
}
}
}
You can get the local path using System properties or a similar approach.
http://download.oracle.com/javase/tutorial/essential/environment/sysprop.html
The Java Class Library represents external processes using the java.lang.Process class. Processes can be spawned using a java.lang.ProcessBuilder:
Process process = new ProcessBuilder("processname").start();
or the older interface exposed by the overloaded exec methods on the java.lang.Runtime class:
Process process = Runtime.getRuntime().exec("processname");
Both of these will code snippets will spawn a new process, which usually executes asynchronously and can be interacted with through the resulting Process object. If you need to check that the process has finished (or wait for it to finish), don't forget to check that the exit value (exit code) returned by process.exitValue() or process.waitFor() is as expected (0 for most programs), since no exception is thrown if the process exits abnormally.
Also note that additional code is often necessary to handle the process's I/O correctly, as described in the documentation for the Process class (emphasis added):
By default, the created subprocess does not have its own terminal or console. All its standard I/O (i.e. stdin, stdout, stderr) operations will be redirected to the parent process, where they can be accessed via the streams obtained using the methods getOutputStream(), getInputStream(), and getErrorStream(). The parent process uses these streams to feed input to and get output from the subprocess. Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, or even deadlock.
One way to make sure that I/O is correctly handled and that the exit value indicates success is to use a library like jproc that deals with the intricacies of capturing stdout and stderr, and offers a simple synchronous interface to run external processes:
ProcResult result = new ProcBuilder("processname").run();
jproc is available via maven central:
<dependency>
<groupId>org.buildobjects</groupId>
<artifactId>jproc</artifactId>
<version>2.5.1</version>
</dependency>
See Runtime.exec() and the Process class. In its simplest form:
Process myProcess = Runtime.getRuntime().exec(command);
...
Note that you also need to read the process' output (eg: myProcess.getInputStream()) -- or the process will hang on some systems. This can be highly confusing the first time, and should be included in any introduction to these APIs. See James P.'s response for an example.
You might also want to look into the new ProcessBuilder class, which makes it easier to change environment variables and to invoke subprocesses :
Process myProcess = new ProcessBuilder(command, arg).start();
...

Create a childprocess and make it run a function or class method

I come from a very C background and am totally new to Java. What I want to do is something like fork() in C. I have looked at ProcessBuilder, but all examples seem to spawn an external process as in the following example:
Process p = new ProcessBuilder("/bin/chmod", "777", path).start();
p.waitFor();
I want the new child process to start executing a new function, or a class method.
What I want to do should behave something like:
Process p = new ProcessBuilder(<CLASS_METHOD>).start();
p.waitFor();
The parent process executes the next line (the line containing waitFor()) where as the child process begins executing the given <CLASS_METHOD>.
How can I get this done?
Additional question: Is there any way I can get a handler to SIGCHLD? I want to create a new child-process when one of the child processes die.
Why can't you just create a new java process using the process builder? Something like following.
Process p = new ProcessBuilder("/bin/java /tmp/Main.class").start();
p.waitFor();
if you don't want to hard code the class path, you can do the following to get the path.
String path = Main.class.getProtectionDomain().getCodeSource().getLocation().getPath();

How to execute a linux terminal command from LUAJ?

I want to simply execute a linux terminal command like ls from LuaJ and the result that it will return or anything that returns i want to receive it and will show the names in the Java Gui. I searched but found this but not one with LuaJ.
Is there any function to execute the terminal command from LuaJ ??
There are multiple ways to do this, for one, you can implement it yourself in Java then link it to LuaJ.
LuaFunction command = new OneArgFunction()
{
public LuaValue call(LuaValue cmd)
{
Process p = Runtime.getRuntime().exec("/bin/sh", "-c", cmd.checkstring());
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
int returnCode = p.waitFor();
return LuaValue.valueOf(returnCode);
}
}
globals.set("command", command);
Then in Lua:
local code = command("ls");
The problem with actually getting the output of a command is that you can't just have a fixall solution. For all the system knows you could be calling a program which runs for 2 hours generating constant output, which could be an issue, not to mention if the program requires input. If you know you're only going to use certain functions you can make a dirty version of above function to capture the output from the stream and return it all instead of the exit code, just don't use it on other processes that don't return quickly. The other alternative is to create a class that wraps the input and output streams from the process and return a coerced version of that class, and manage the input and output from lua.
Lua does have a function that's part of the OsLib called execute(), if execute doesn't exist in your current environment then in Java call:
globals.load(new OsLib());
Before loading the lua code. the os.execute() function returns the status code, and doesn't return the streams, so no way to get the output there. To get around this you can modify the command to pipe the output to a temp file and open it with the io library (new IoLib() if doesn't exist in current environment).
The other option is to use io.openProcess, which also executes the command and returns a file to read the output from.
Resources:
http://luaj.org/luaj/3.0/api/org/luaj/vm2/lib/OsLib.html
http://luaj.org/luaj/3.0/api/org/luaj/vm2/lib/IoLib.html

Java Processbuilder - Catching the exitvalue of another Script?

I try to run a python script in my java programm. What I want to do is to catch the exitValue of the python programm and write it via System.out.println out.
Here is the Python code:
import sys
import subprocess
print "hallo"
i = sys.argv[0]
path = "R:\\xxx\\xxx\\xxx\\read"
resultlist = []
if i == 0:
result = True
else:
result = False
resultlist.append(result)
resultlist.append(path)
sys.exit(resultlist)
The Processbuilder methods .waitFor() and .exitValue() just gives a 0 or a 1 out. So I cant use it.
Is there any possible way to catch the value/string of sys.exit(resultlist) from the python script in my java programm?
man 2 exit:
The function _exit() terminates the calling process "immediately". Any open file descriptors belonging to the process are closed; any children of the process
are inherited by process 1, init, and the process's parent is sent a SIGCHLD signal.
**The value status is returned to the parent process as the process's exit status, and can be collected using one of the wait(2) family of calls.**
You cannot return "complex values" with exit(2) (the syscall) to begin with. If python does that then fine, but it's a "trick". Don't rely on it.
What you want to do is print the output of your program to stdout and capture stdout. For this, use the Process's .getInputStream() and swallow it in, for instance, a ByteArrayOutputStream.
Since you use a ProcessBuilder, you can also use its .redirectOutput() method before executing the process. Since Java 7, it has quite a few options available.

Handling delayed execution of a program in java

I am running an .exe file from my program and it is taking certain time for the same.The output from this command is used in the following statements for further processing. The output is a boolean variable. But the program is returning false immediately, but in fact the command is still in execution and is taking certain time. Because of the false value the subsequent statements is throwing an error. How do i handle this situation.
The return_var = exec(pagecmd) is the executing statement.
boolean return_var = false;
if("true".equals(getConfig("splitmode", ""))){
System.out.println("Inside splitmode if**********************");
String pagecmd = command.replace("%", page);
pagecmd = pagecmd + " -p " + page;
File f = new File(swfFilePath);
System.out.println("The swffile inside splitmode block exists is -----"+f.exists());
System.out.println("The pagecmd is -----"+pagecmd);
if(!f.exists()){
return_var = exec(pagecmd);
System.out.println("The return_var inside splitmode is----"+return_var);
if(return_var) {
strResult=doc;
}else{
strResult = "Error converting document, make sure the conversion tool is installed and that correct user permissions are applied to the SWF Path directory" +
getDocUrl();
}
In conjuction with waitFor() suggested by Andreas, you may also need to use getInputStream of Process object returned by exec() to retrieve the data written by the program you are executing.
Assumed that you are finally using Runtime.exec() inside your exec() method, you can use the waitFor() method of the Process object which is returned from Runtime.exec() to wait until the execution has finished:
...
Process p = Runtime.getRuntime().exec(pagecmd);
int result = p.waitFor();
...
The return value from waitFor() is the exit code of the sub process.
If you actually need to read output from the sub process which the sub process is writing to its stderr or stdout channel, you need to use Process.getInputStream() (Note: not getOutputStream()) and Process.getErrorStream() and read the sub processes output from these streams. Then, check the return values from the stream's read() methods to check if the sub process has terminated (or at least closed its output streams) instead of using waitFor().
Also, for these kind of problems, you should consider using the Apache commons exec library.
Alternatively, you might want to check the ProcessBuilder class.

Categories