Pass arguments and run .cmd file in windows using java - java

I want to run and pass the arguments to ".cmd" file using Java program. I have checked the existing Solutions, but nothing is working in my case.
From Command line, I am running below command after getting into Directory C:/users/project/solr/bin
solr.cmd -s "C:users/github/example/solr-config"
So, solr.cmd gets arguments from the other Directory and then it runs the solr instance.
I have tried this, but I am not sure how to provide Parameters to Runtime.getRuntime():
Runtime run = Runtime.getRuntime();
Process p = null;
String cmd = "cmd /c start C:/users/project/solr/bin C:users/github/example/solr-config";
Process pr = run.exec(cmd);
I have followed this link: How do I run a batch file from my Java Application?
Could anyone please help me this.

I solved it by modifying cmd as solr.cmd expects -s also as argument:
String cmd = "cmd /c start C:/users/project/solr/bin/solr.cmd -s C:users/github/example/solr-config;

There is a difference between "it doesn't work" and "it doesn't show anything". As per the documentation:
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.
If you want to retrieve the data that your process might have printed out on the standard I/O, you will have to read them from the abovementioned streams.

Related

ProcessBuilder process not providing real time output

I'm running ProcessBuilder in a java program using eclipse IDE and Ubuntu 20.04. Specifically for bluetooth LE commands. For commands like "hciconfig" the process completes and I can print the output to the console or a textarea (JFX). Other commands like hcidump run continuously until manually terminated. For these commands I'm unable to print the intermediate output while the process is running. I've tried both the apache.commons CommandLine and the java ProcessBuilder methods probably 6 ways to sundown each. This should be a fairly straightforward task but so far no luck. Here is the java code:
Process pb = new ProcessBuilder()
.command("hcidump", "-i", "hci0")
.redirectOutput(ProcessBuilder.Redirect.INHERIT)
.start();
System.out.println(pb.getOutputStream().toString());
The printed output stream appears to be an address:
java.lang.ProcessImpl$ProcessPipeOutputStream#b06aa6f
How do I access the process output while the process is still running?
The stdout stream of the sub-process is the unfortunately named pb.getInputStream(), not pb.getOutputStream() which is the stdin for the sub-process.
Just send stdout to the destination using transferTo, for example:
pb.getInputStream().transferTo(System.out);
However you have second issue that you are not reading stderr, check also:
pb.getErrorStream().transferTo(System.out);

Why is my runtime command ignored after calling a batch file?

public class Test_Python
{
public static void main( String[] args ) throws IOException
{
String command = "cmd /k start cmd.exe /k \"cd C:\\Workspace\\supply\\environment\\ && setup.bat && python -V ";
Runtime.getRuntime().exec(command);
}
}
When I execute my code, the "python -V" does not work, it is not executed in the cmd window.
But if I delete the "setup.bat" from my command, the "python -V" is executed (I can read the version in the cmd window)
Also, if I manually start a cmd, type setup.bat and then python -V it works.
My batch file is used to set my working environment:
SET basedir=%~dp0
echo %basedir%
cmd /k "cd %basedir%\..\scripts && set PYTHONPATH=%basedir%\..\lib"
Is there any way to know why it fails?
Unlike python Java may need some help. As I can see you are running on Windows.
You invoke the Runtime.exec() method. The method returns a Process instance, and in it's documentation you can read
By default, the created process 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 process. 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 process may cause the process to block, or even deadlock.
So it is likely your process is started by the OS but gets blocked due to I/O restrictions. Get around that by reading the STDOUT and STDERR streams until your process finishes. One good programming model is visible at https://www.baeldung.com/run-shell-command-in-java
Now that we know the OS is not blocking the process, the issue may be inside the command itself. Note you concatenated several commands using the && operator. I do not have a windows system but searched a bit online:
https://www.ionos.com/digitalguide/server/know-how/windows-cmd-commands/
CommandA && CommandB (the second command is only run if the first was successful)
To check how the first part of your command exits run it separately in Java and do not forget to print the process.exitValue() method.
But looking at the whole picture, all you do with the first part is to change the working directory and set some environment variable. What stops you from running the ProcessBuilder methods? The example in the documentation directly sets the environment and directory.

Correct way to run another java program from java

I want to run the following shell command from a java application:
java -jar saxon9he.jar -warnings:fatal a.xml a.xsl param1=123 param2=abc
Currently, I am simply executing this as a shell command using
ProcessBuilder pb = new ProcessBuilder(commandLineParts);
[...]
Process process = pb.start();
What is the correct way to do this in java?
This is the correct way of executing a command in Java. Just to clear possible confusion: ProcessBuilder doesn't execute the program using a shell. That's the reason why you have to provide it with a list of arguments and not a single string (that would be parsed by a shell).
There are two possibilities:
either you want to run the Java program in a new JVM and then using
the ProcessBuilder is the way to go
or you don't mind if it is executed in the same JVM and then you can call the main method yourself as Sean suggests (possibly in a different thread)
Another option, depending on the type of the application, would be to perform some acrobatics with an application server to start the app in it.
If you use the ProcessBuilder just be careful about handling its input and output streams - if you don't handle them your application can hang: Java ProcessBuilder: Input/Output Stream This has been improved in Java 7.

How to run linux script from Java

I want to run linux script from Java program and continue to execute program only when script stop. I am not interested to read script output ... Can anybody help me?
Thanks a lot,
and excuse me for my bad English
Assuming all other threads are idle:
// run the script.
Process proc = Runtime.getRuntime().exec("/path/to/myscript");
// wait for the return code.
int ecode = proc.waitFor();
If you have more complex arguments to your script, or it needs to monitor STDOUT, STDERR, or needs other modifications (like feeding data to STDIN, or changing execution directory, environment variables, etc.) then you should do the same effective procedure, but instead of using Runtime.exec(...) you should build and start the Process manually. Read the Process javadoc and ProcessBuilder javadoc on how to set it up, and start it.
You can also launch the bash interpreter instead
Process proc = Runtime.getRuntime().exec("/bin/bash /path/to/myscript");
int ecode = proc.waitFor();
This may work in some generally broken cases when #rolfl solution may not work (non executable script file, #!/ header missing, etc)

Java Runtime.exec() with ssh on Linux Issues

I am trying to start a new process using Runtime.exec(), but my problem lies within using ssh to remote in and then run a java program there. Code:
test = "ssh -t username#host java packageName.ClassName portNumber (Other command line args for this class)"
Process proc = Runtime.getRuntime().exec(new String[] {"/bin/bash", "-c", test});
this doesn't fail or catch, but I need to be able to see the stdout for the newly running process and I don't.
Note: if I run ssh -t username#host java packageName.ClassName portNumber (Other command line args for this class) from the command line it works fine. I have the host setup to not require a password by using ssh keys.
Any ideas?
You need to use Process.getInputStream to obtain the output from the sub-process being created.
See this article for a good discussion on Runtime.exec.
I think you can ask for an input stream that corresponds to the stdout of the process and then print it on your standard output. If you need to see it after it executes, just call waitFor() method on the process so it finishes before you start printing.
Use getInputStream() to access returned process's stdout. You can also use facilities provided by ProcessBuilder.Redirect.

Categories