I am able to invoke a java class using below command line:
java -jar <my jar name>.jar -option1 <option> "<a string value>"
However, I want to invoke it from a another Java program.
The name of the main class is XYZ
I have imported the jar as a dependency in my project.
That heavily depends on whether you want to launch it as a separate process or simply execute within the same one.
To kick it off in the same process, you could just call the main method:
String[] arguments = new String[]{"-option1", "<option>", "<a string value>"};
MyOtherMainClass.main(arguments);
To start it as a different process:
ProcessBuilder pb = new ProcessBuilder("java", "-jar", "<my jar name>.jar", "-option1", "<option>", "<a string value>");
Process process = pb.start();
int errCode = process.waitFor();
The second example was inspired by http://examples.javacodegeeks.com/core-java/lang/processbuilder/java-lang-processbuilder-example/
Related
I was developing my spring boot server on Windows. Now I have upgraded to Ubuntu 20.04.
the project executes a python script which should return a result as a txt file with this command:
python3 -c "from main import *;main(function,'/tmp/execution12480676806364930620/executionResponse.txt')"
Thanks to this code:
List<String> items = Arrays.asList(project.getExecutorType().buildAndGetExecutionCommandByProject(project));
ProcessBuilder pb = new ProcessBuilder(items);
pb.directory(new File(project.getPath()));
Process p = pb.start();
p.waitFor(5, TimeUnit.SECONDS);
when I print in the console the array passed in the Item variable:
[python3, -c, "from main import *;main(function, '/tmp/execution12480676806364930620/executionResponse.txt')"]
and the path of the array passed in pb.directory :
/tmp/execution12480676806364930620
My problem is that the project is not running and returning nothing.
when i go to the folder and run the same command from terminal everything works.
And that on windows 10 this same process worked fine.
Looking at similar issues I modified my code like this but it doesn't change anything:
List<String> items = Arrays.asList(project.getExecutorType().buildAndGetExecutionCommandByProject(project));
ProcessBuilder pb = new ProcessBuilder();
pb.command(items);
pb.redirectErrorStream(true);
pb.directory(new File(project.getPath()));
Process p = pb.start();
p.waitFor(5, TimeUnit.SECONDS);
What am I doing wrong?
Edit :
My command for read outputs :
private String inputStreamToString(InputStream inputStream){
return new BufferedReader(
new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines()
.collect(Collectors.joining("\n"));
}
And I call it like that :
System.out.println(this.inputStreamToString(p.getErrorStream()));
System.out.println(this.inputStreamToString(p.getInputStream()));
What works, when I just run "python main.py" I get the errors and print them out.
I can easily add the command at the end of the main file but I don't understand why the python -c "..." is not working? I am not receiving any errors ... I manage several languages and this could be a problem for me later
Aha! On closer inspection I think you're right it's not executing anything (and thus not producing any output either normal or error for you to see).
You don't show how the array of strings is created, but your printout suggests you have actually put quotemarks in the third string. That's wrong. When you give the shell command line python -c "import this; dothat" the shell uses the quotemarks to control parsing of this command line, but it does not pass them to the python process; the args passed to the python process (shown vertically for clarity, and omitting the argv[0]=program used in C but omitted in Java) are actually
-c
import this; dothat
If you pass an argument actually containing quotemarks like
-c
"import this; dothat"
then python doesn't execute the commands import and dothat; instead it evaluates the string literal "import this; dothat" and (since it isn't running interactively) discards the result.
Try not including, or removing, the " at the beginning and end. But leave the ' inside the string value because you do want python to receive those.
I have a java process running as windows server using prcorun (http://commons.apache.org/proper/commons-daemon/); unfortunatly I have to launch an external legacy command written in C/C++.
both
Process myProcess = Runtime.getRuntime().exec(command);
and
Process myProcess = new ProcessBuilder(command, arg).start();
work well when java is launched as a stand-alone application, but when I start java as service it replies
command not found
also with
Process myProcess = Runtime.getRuntime().exec("dir");
command not found
I think is a problem due to windows services.
Any suggestion?
I would try to do a quick test and print the PATH environment variable in your service. What I usually found when you run some command as a service, the PATH might not be totally available (which can also explain why DIR is not working for you). If that the case, when starting the service, you have to make sure the PATH include both the normal bin and your legacy bin.
As the error says, the command is not found in the path. You'll need to set the environment variable PATH to the child process's environment. Look at exec(cmd, String[] env) method. You can create an array of environment variables (key value pairs) and pass it to exec().
In my case I used
cmd /c <<YOUR COMMAND>>
eg.
Process myProcess = Runtime.getRuntime().exec("cmd /c dir");
also I added the envinronments. as suggested by smurf
private static String[] getEnv() {
Map<String, String> env = System.getenv();
String[] envp = new String[env.size()];
int i = 0;
for (Map.Entry<String, String> e : env.entrySet()) {
envp[i++] = e.getKey() + "=" + e.getValue();
}
return envp;
}
...
Process myProcess = Runtime.getRuntime().exec("cmd /c dir",getEnv());
Alternative to java.lang.Runtime.exec() that can execute command lines as a single string?
I have a problem running a Java process with arguments as a command from another Java manager process. Say I have a main class Main, and I want to pass 0 as an argument (for javaw.exe it's just one of the arguments). To illustrate, if I run something like this in a console, it works:
javaw.exe -X... -D... -cp ... Main 0
This runs Main with the argument 0. Now, to run this from my manager application I use the following line:
Process p = Runtime.getRuntime().exec(new string[] {
"cmd.exe", "/c", "javaw.exe", "-X... -D... -cp ... Main", "0"});
I get the following output in err:
Error: Could not find or load main class 0
In other words, the JVM identifies the 0 as the main class.
Using a different exec overloading is not a recommended option (it's a generic infrastructure).
Well you're passing the whole of "-X... -D... -cp ... Main" as a single argument. Instead, you should have:
Process p = Runtime.getRuntime().exec(new string[] {
"cmd.exe", "/c", "javaw.exe", "-X...", "-D...", "-cp", "...", "Main", "0"});
I am calling a shell script from java code using :
ProcessBuilder pb2=new ProcessBuilder("/home/abhijeet/sample1.sh ");
Process script_exec = pb2.start();
Which runs successfully,But i need to pass some parameters to it , so I need to execute this script as :
param1=abc param2=xyz /home/abhijeet/sample1.sh
I have tried this code:
ProcessBuilder pb2=new ProcessBuilder("/home/abhijeet/sample1.sh ","param1=abc","param2="xyz");
But it did't work for me.How can i pass arguements to shell script while using Processbuilder for calling it?
Note:My question is about passing arguments to shellscript ,not to commands.i have read that suggested possible duplicate question , but that does't solve my problem,I tried it that way, that is for passing arguements to commands, not for shellscript
You say you need to run the command:
param1=abc param2=xyz /home/abhijeet/sample1.sh
In this case, the "param1" and "param2" strings aren't command-line arguments. This is shell syntax to set the two environment variables param1 and param2 and then invoke sample1.sh.
To accomplish this with ProcessBuilder, you need to access the builder's environment variables:
ProcessBuilder pb2=new ProcessBuilder("/home/abhijeet/sample1.sh");
pb2.environment().put("param1", "abc");
pb2.environment().put("param2", "xyz");
Process script_exec = pb2.start();
As an alternative, the command that you're trying to run uses shell syntax, so you could pass it to a shell to execute it:
ProcessBuilder pb2=new ProcessBuilder(
"/bin/sh",
"-c",
"param1=abc param2=xyz /home/abhijeet/sample1.sh");
Process script_exec = pb2.start();
I have written a java program named Automate.java, in which the another java program named newsmail will be executed.
The problem i face here is, Automate.java is in Desktop location(should be in desktop only always due to some requirements) and newsmail is in /home/Admin/GATE521/LN_RB this location.
What must be done before the below code, such that the command prompt automatically goes to the required folder and executes the program.
String command = "java newsmail";
Process child = Runtime.getRuntime().exec(command);
You can use this exec() :
Process child = Runtime.getRuntime().exec(command, null, new File("/home/Admin/GATE521/LN_RB"));
Resources :
javadoc - Runtime.exec()
Use the new ProcessBuilder class, instead of Runtime.exec().
ProcessBuilder pb = new ProcessBuilder("java", "newsmail");
pb.directory("/home/Admin/GATE521/LN_RB");
pb.start();
You can even look at pb.environment() to change environment variables if necessary.