Need help -- Pass two params in java in command line through perl - java

I need to pass two params in a java file similar as I pass from command line.
Something like
$ENV{classpath} = ".\\my.jar;$ENV{classpath}";
system("$ENV{JAVA_HOME}\\bin\\java com.myclass param1 param2" );
how can i achieve this in a perl script?

I don't have access to my work system still let me give it a try. It should work for you.
my $cpJava=" -cp /your/classpath";
my $myClass="your class name";
my $runMe="Java path ".$cpJava." ".$myClass." ".join(' ', #ARGV);
#ARGV will have all your parameters. Learn more about join from here.
Then use system:
system($runMe);
Hope it would work for you.

Related

Space in python variable passed as argument to subprocess

I have a variable toPath (contains path like C:/Program Files(x86)/bla).
This variable I pass as agrument: '[-operation update -contents ' + toPath + ']'
But because I have a space in this variable I get IllegalArgumentException.
How can I fix this?
I'm not sure but it looks like you are trying to do a typical newcomer mistake.
If you are trying to run a command that is build from multiple variables you can be vulnerable to injection attacks. To prevent this, use the subprocess module and hand in all parameters as a list. The module will take care of all the stuff to make it work with spaces as well.
For example ls -l should be run as:
subprocess.call(["ls", "-l"])
Your example caontains [] and might be rather different but without it would be:
subprocess.call(['-operation','update', '-contents', toPath])
Please note that there are other functions than call() (which returns the return code only) in the subprocess module.
Pass argument in double quotes.
toPath = "\"C:/Program Files(x86)/bla\"";
try
'[-operation update -contents "' + toPath + '"]'

Call a jar using perl and pass variables using STDIN

I am calling a jar via perl with the following command.
my $command = "$java_home/bin/java my_jar.jar ARG1 ARG2 ARG3";
my $result = `$command 2>&1;
However my JAR also expects arguments via STDIN. I need to know how to pass those arguments. I have tried passing them like normal arguments, and that didn't work. I read on a forum that OPEN2 might work however after reading the documentation I couldn't figure out how to make it work.
Any ideas on how to make this work would be great.
Thanks ahead of time.
Since you need to send and receive data from the Java process, you need two-way communication. That's what IPC::Open2 is designed to do. This allows you to create a dedicated pipe that renders STDIN/STDOUT unnecessary:
use IPC::Open2;
my $pid = open2( \*from_jar, \*to_jar, $command )
or die "Could not open 2-way pipe: $!";
print to_jar, "Here is input\n"; # Pass in data
my $result = <from_jar>; # Retrieve results
Also consider IPC::Open3 to handle errors as well.

How to change the System clock of a Linux machine by using Java?

I know that by using the command in the terminal
date --set="2011-12-07 01:20:15.962"
you would actually be able to change the System clock, so I tried it in Java and came up with the following statement
Process p = Runtime.getRuntime().exec("date --set=\"2011-12-07 01:20:15.962\"");
but it was not able to set the clock.
Do you have any idea guys how it may be able work?
Premise:
The machine is Slackware,
The privilege is root level
There are two problems with this line of code:
Process p = Runtime.getRuntime().exec("date --set=\"2011-12-07 01:20:15.962\"");
You did not wait for the process to complete (see also http://docs.oracle.com/javase/6/docs/api/java/lang/Process.html#waitFor())
Parameters should be separated from program name, try this:
"date", "-s", "2011-12-07 01:20:15.962"
Alternatively, invoke shell as the process, and pass in a line of code:
.exec("sh", "-c", "date --set=\"2011-12-07 01:20:15.962\"")
Process p=Runtime.getRuntime().exec(new String[]{"date","--set","2011-12-07 01:20:15.962"});
The above statement worked like magic. #Howard Gou was right with "Parameters should be separated from program name"
The parts of the command statement should be passed by using a String array.

ProcessBuilder adds extra quotes to command line

I need to build the following command using ProcessBuilder:
"C:\Program Files\USBDeview\USBDeview.exe" /enable "My USB Device"
I tried with the following code:
ArrayList<String> test = new ArrayList<String>();
test.add("\"C:\\Program Files\\USBDeview\\USBDeview.exe\"");
test.add("/enable \"My USB Device\"");
ProcessBuilder processBuilder = new ProcessBuilder(test);
processBuilder.start().waitFor();
However, this passes the following to the system (verified using Sysinternals Process Monitor)
"C:\Program Files\USBDeview\USBDeview.exe" "/enable "My USB Device""
Note the quote before /enable and the two quotes after Device. I need to get rid of those extra quotes because they make the invocation fail. Does anyone know how to do this?
Joachim is correct, but his answer is insufficient when your process expects unified arguments as below:
myProcess.exe /myParameter="my value"
As seen by stefan, ProcessBuilder will see spaces in your argument and wrap it in quotes, like this:
myProcess.exe "/myParameter="my value""
Breaking up the parameter values as Joachim recommends will result in a space between /myparameter= and "my value", which will not work for this type of parameter:
myProcess.exe /myParameter= "my value"
According to Sun, in their infinite wisdom, it is not a bug and double quotes can be escaped to achieve the desired behavior.
So to finally answer stefan's question, this is an alternative that SHOULD work, if the process you are calling does things correctly:
ArrayList<String> test = new ArrayList<String>();
test.add("\"C:\\Program Files\\USBDeview\\USBDeview.exe\"");
test.add("/enable \\\"My USB Device\\\"");
This should give you the command "C:\Program Files\USBDeview\USBDeview.exe" "/enable \"My USB Device\"", which may do the trick; YMMV.
As far as I understand, since ProcessBuilder has no idea how parameters are to be passed to the command, you'll need to pass the parameters separately to ProcessBuilder;
ArrayList<String> test = new ArrayList<String>();
test.add("\"C:\\Program Files\\USBDeview\\USBDeview.exe\"");
test.add("/enable");
test.add("\"My USB Device\"");
First, you need to split up the arguments yourself - ProcessBuilder doesn't do that for you - and second you don't need to put escaped quotes around the argument values.
ArrayList<String> test = new ArrayList<String>();
test.add("C:\\Program Files\\USBDeview\\USBDeview.exe");
test.add("/enable");
test.add("My USB Device");
The quotes are necessary on the command line in order to tell the cmd parser how to break up the words into arguments, but ProcessBuilder doesn't need them because it's already been given the arguments pre-split.
I wasn't able to get it to work in any of the above ways. I ended up writing the command to a separate script (with "\ " for each space) and writing that into a script file, then calling the script file.
Split the arguments and add it to the command list. The ProcessBuilder will append quotes to the argument if it contains space in it.
ArrayList<String> cmd= new ArrayList<String>();
cmd.add("C:\\Program Files\\USBDeview\\USBDeview.exe");
cmd.add("/enable");
cmd.add("My USB Device");

Does Java have an equivalent to C#'s Environment.GetCommandLineArgs()?

I know that I can get the command-line arguments in the "main" method, but I need to be able to get them indirectly.
Thanks for your help.
Following expression is exactly what you want:
System.getProperty("sun.java.command")
You can list the threads, find the main thread, and crawl down the stack trace until you find the call to main, and pull out the args.
update a comment points out that this won't work all by itself, and I think the comment is correct. I misremembered the capabilities of stack introspection or mentally mixed in JVMTI.
So, here's plan B. Connect to yourself with JMX. The VM Summary MBean has the args.
Connection name: 
pid: 77090 com.basistech.jdd.JDDLauncher -config src/main/config/benson-laptop-config.xml
All this having been said, what you should do is call System.getProperty and live with the need to use -D to pass parameters from the outside world down into your cave.
You could write a wrapper to take the cli and re-format it to use -DPROP=VAL
int main(int argc, char*argv[])
{
std::vector<std::string> in (argv+1,argv+argc), out();
out.push_back("java.exe");
out.push_back("-cp");
out.push_back("my-jar.jar");
out.push_back("main.class")
for( auto it = in.begin(); it!=in.end(); ++in)
{
//process CLI args. turn "-abc","BLAH" into "-Darg.a=true","-Darg.b=true","-Darg.c=BLAH" and push to out
//Do additional processing. Maybe evn use get_opt() or Boost.ProgramOptions
}
//use exec or CreateProcess to launch java with the proper args
//or even use something like WinRun4J's methods to load the jvm.dll
//Then your program shows up as "MyExe.exe" instead of "java.exe"
//Use System.getProperty("arg.a","false") to get the value of a
}
Of course, you could always just tell you users to invoke a bash/batch script with the proper -DA=true type arguments

Categories

Resources