Java main argument identified as main class - java

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"});

Related

Node running in Runtime.getRuntime().exec()

I can run the following command from the terminal in Windows:
D:\myProject> node ./node_modules/someModule/create.js -c control -b 1
But not if I try to run this within Runtime.getRuntime().exec(cmdarray, envp, dir).
String[] cmdarray = {"node", "./node_modules/someModule/create.js"};
String[] envp = {"-c=control", "-b=1"};
File startingPath = new File("D:\myProject");
Process process = Runtime.getRuntime().exec(cmdarray, envp, startingPath);
I also tried to the cmdarray as a single entry and even adding the arguments at the end and leaving envp empty.
But it's not working.
How would be the correct way to write the command? And is there a difference, when I run this on Windows and Mac?
You shouldn't put command line options into the environment. They are not environment variables! Put them into the command array ... as individual array elements; e.g.
String[] cmdarray = {
"node", "./node_modules/someModule/create.js",
"-c", "control", "-b", "1"};
And is there a difference, when I run this on Windows and Mac?
If you do it this way, there should be no difference between Windows and Mac. But obviously it is up to you to test your code on all platforms you intend to support!
Note also that when you use a simple command name (e.g. node) the command needs to be on command search path; i.e. $PATH or %PATH%.

Bash - treat parameters as command parameters

I know, that we can execute commands in a BASH using the -c parameter:
bash --login -c "command parameter"
Since we need to be able to execute any command with arbitrary parameters (that can contain spaces, quotes or apostrophes) programmatically (from Java), we would like BASH to treat all parameters as command, something like the -- usually used to separate options from file names, e.g. with Git. Is there a way to execute the above call similar to
bash --login -<some option> -- command parameter
which could be executed from Java easily without escaping command or parameter?
new ProcessBuilder(new String[] {
"bash",
"--login",
"-<some option>",
"--"
command,
parameter
}).start();
-c command must be the last option argument to bash. Any subsequent arguments, whether or not they start with a dash, are assigned to the positional parameters $0, $1, ... in the shell executing the command.
That's usually convenient, since it lets you substitute strings into the command being executed without worrying about quoting them.
Since the first argument following the command is assigned to $0, it is very common to see invocations like
bash -c 'complicated command using "$#"' _ arg1 arg2 arg3
so that arg1 will be assigned to $1 (thus allowing "$#" to work as expected, for example).
As an example:
new ProcessBuilder( new String[] {
"bash",
"--login",
"-<some option>",
"-c",
"for arg in \"$#\"; do frobnicate \"$arg\" 42; done",
"_",
"first thing to frobnicate",
"second thing", ...
}).start();

invoking command line java from java code accepting arguments

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/

How to pass arguments to shellscript using java?

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();

servlet multiple exec commands

I am writing a servlet to run terminal commands, I have to run three commands one after the another on the same terminal.
When I use exec as shown below I am able to get the result for the single command,
Runtime rt = Runtime.getRuntime();
process proc = rt.exec("zsh");
but when I attempt to run,
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec("zsh", "source ./myenv/bin/activate", "python runner.py");
it shows a warning (doesn't execute) as follows,
The method exec(String, String[], File) in the type Runtime is not applicable for the arguments (String, String, String).
I've also tried running three differed exec commands but they do not happen in the same sequence and on the same terminal, what should I do to make the above three commands to run on the same terminal sequentially and give me the output after the third command?
The three commands I intent to run are,
1. zsh
2. source ./myenv/bin/activate
3. python runner.py
all the three must be executed one after the other in the same sequence.
exec takes a String[] not a varargs list so you need to run:
Process proc = rt.exec(new String[] {"zsh", "source ./myenv/bin/activate",
"python runner.py"}, null, new File("parentdirectoryofmyenv"));
As shown you also need to include the working directory for the process or it won't be able to find "./myenv".
EDIT:
Simplifying this further. I am assuming that "source ./myenv/bin/activate" is setting the environment for the process. This can be done as follows:
Process proc = rt.exec(
new String[] {"python", "runner.py"},
new String[] {"ENV1=VAL1", "ENV2=VAL2"},
new File("parentdirectoryofrunnerpy"));

Categories

Resources